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

翻译|其它|编辑:郝浩|2006-02-21 16:47:00.000|阅读 1673 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


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;
}

结束语
 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP