WEB开发网
开发学院软件开发VC 根据所选择的TrueType字体生成点阵数据 阅读

根据所选择的TrueType字体生成点阵数据

 2008-02-26 20:27:06 来源:WEB开发网   
核心提示:3、通过选入字体的DC得到字体的点阵数据,这个处理依靠如下的函数,根据所选择的TrueType字体生成点阵数据(3), DWORD GetGlyphOutline( UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffe

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小时之外。

上一页  1 2 3 

Tags:根据 选择 TrueType

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接