请问 Windows 下矢量字体是如何描述的,如以 TrueType 字体为例,其格式如何?我要做的应用是最终控制物理器件的运动轨迹走出汉字(大小可变)的外形轮廓,然后以水平、垂直或45°方向的直线填充(密度可调),请问该用什么算法实现?由于我对矢量格式一无所知,希望大家能教以方法,或提供基础性资料,网址亦可

解决方案 »

  1.   

    显示汉字
    GetPath将汉字轮廓以线段与贝赛尔线的形式存在数组中
    下面的自己研究!
      

  2.   

    GetPath是个通用的方法:不只是text,支持path的GDI作图函数都可以.
    但通用的速度就般般了.
    可以用GetGlyphOutline函数解决问题,Get出来的数据处理起来有些麻烦,你要找些原代码看看.
    看你的问题,是只要填充?好象用FillPath就可以了吧.
      

  3.   

    fillPath 好像只能在电脑输出设备上看到结果,但我不仅仅要在显示器上处理我需要矢量的描述数据,然后控制两个步进电机,使其运动轨迹为矢量数据所描述的轮廓
      

  4.   

    要实践你的功能,不一定要用GetPath,我的思路是,先在Form上画出你需要的字,
    然后用扫描线的方法复制到你的设备上,设备只需用MoveTo及LineTovoid __fastcall TForm1::Button1Click(TObject *Sender)
    {
         String ch="噗"; //可以多个字符
         Canvas->Font->Name="宋体";
         Canvas->Font->Color=clBlack;
         Canvas->Font->Size=40;   
         Canvas->TextOut(100,100,ch); 
         int w=Canvas->TextWidth(ch);
         int h=Canvas->TextHeight(ch);
        TColor c,oldc;
        for(int j=0;j<h;j++)
         {
          oldc=c=clWhite;
          for(int i=0;i<w;i++)
            {
                c=Canvas->Pixels[100+i][100+j];
                if (c!=oldc)
                 {
                    if (c==clBlack)
                        Canvas->MoveTo(300+i,100+j);  //在你的设备上MoveTo 
                      else
                        Canvas->LineTo(300+i,100+j); //在你的设备上LineTo
                    oldc=c;
                 }
            }
          }
    }
      

  5.   

    感谢  bluebohe(薄荷)    你的方法给了我一个方向,我要做的跟“用铣刀在铁板上刻字”差不多,但精度要求很高,就是用激光在任何材料表面(或在透明材料内部雕刻)刻文字或图形,文字可能很大也可能小到要用放大镜看。
        我现在的思路是先编辑好各种对象,然后开一个预览窗口,将各个对象逐个显示在预览窗口中进行线扫描。但是假如我只需要汉字的轮廓并不填充的话,可能速度会比较慢,还有文字很小的话不知道精度够不够。
        我本来是做单片的编程的,对Windows编程很生疏,为了做这个事才开始真正接触,对你上面这段BCB代码(我猜的,不知是不是)要表达的原理基本能猜懂:),我选择的工具是VC,自己看书学了快三个月了,基本实现的软件的界面和编辑功能,但感觉还是没有摸着Windows编程的门,有时候一个很小的问题会将我难住好几天,希望以后能得到你更多的指点。
      

  6.   

    我是拷贝别人的代码,这些代码我找了一上午,
    http://expert.csdn.net/Expert/topic/2098/2098463.xml?temp=.3817255
      

  7.   

    现在我已经知道了怎样获取矢量数据了,其中曲线部分大多用贝塞尔线来描述的,但是我是要用来做控制的,不能用库函数画,现在的问题是如何生成贝塞尔曲线给定贝塞尔曲线的三个关键点,怎样用moveto,lineto或putpixel等来生成这条曲线呢?
      

  8.   

    typedef struct xyz {
    double x;
    double y;
    double z;
    }XYZ,*PXYZ;//生成两点间插值点
    //参数:nCurPos为待计算点相对于已有点的位置,pOrgPt为已有点,ptPrev
    // 为已计算出的前一个点,o_pt存储计算出的插值点,g_cDivNum 杨条插值点段数
    void CalcInterpolatePt( const short nCurPos, const PXYZ pOrgPt,
       const PXYZ ptPrev, PXYZ o_pt ,unsigned char g_cDivNum)
    {
    XYZ pta, ptb, ptc;
    short nCurEndPos = 0;

    if( nCurPos )
    {
    pta = *ptPrev;
    nCurEndPos = g_cDivNum - 1;
    }
    else
    nCurEndPos = 0;

    ptb = pOrgPt[0]; //TTPOLYCURVE结构中存储的已知控制点
    ptc.x = o_pt[nCurEndPos].x = ( pOrgPt[0].x + pOrgPt[1].x )/2;
    ptc.y = o_pt[nCurEndPos].y = ( pOrgPt[0].y + pOrgPt[1].y )/2;
    o_pt[nCurEndPos].z = 0.0;

    if( g_cDivNum == 1 ) //不必再插入插值点
    return;
    else if( nCurPos == 0 ) //起始段
    return;
        //按指定段数加入插值点
    else
    {
    double t = 0.0;
    double dUnit = 1/(double)g_cDivNum;

    for( short i = 0; i < g_cDivNum - 1; i ++ )
    {
    //从VC帮助中查出样条插值点计算公式
    //x(t) = (xA-2xB+xC)*t^2 + (2xB-2xA)*t + xA
    //y(t) = (yA-2yB+yC)*t^2 + (2yB-2yA)*t + yA
    t = ( i + 1 ) * dUnit;
    o_pt[i].x = ( pta.x - 2 * ptb.x + ptc.x ) * t * t +
    2 * ( ptb.x - pta.x ) * t + pta.x;
    o_pt[i].y = ( pta.y - 2 * ptb.y + ptc.y ) * t * t +
    2 * ( ptb.y - pta.y ) * t + pta.y;
    o_pt[i].z = 0.0;
    }
    }
    return;
    }//对由p指向的wPtNum个控制点表示的样条进行插值计算,将计算出的
    //插值点记录在o_pPts指向的点数组中
    void InterpolateSpline( const WORD wPtNum, const XYZ * p,
      XYZ * o_pPts,unsigned char g_cDivNum )
    {
    ASSERT( AfxIsValidAddress( p, 3 * wPtNum * sizeof(double) ) );
    ASSERT( o_pPts );

    //计算插值后点数
    short nPtNum = ( wPtNum - 2 )*( g_cDivNum - 1 ) + wPtNum + 1;

    //计算各点坐标
    o_pPts[0] = p[0]; //起点
    for( short i = 0, j = 1; i < wPtNum && j < nPtNum; i ++ )
    {
    if( ( i + 1 ) != wPtNum ) //中间各点
    {
                //生成两点间插值点
    CalcInterpolatePt( i, (XYZ *)&p[i], &o_pPts[j-1],
    &o_pPts[j] ,g_cDivNum);
    if( i )
    j += g_cDivNum;
    else
    j ++;
    }
    else //终点
    {
    o_pPts[j] = p[i];
    j ++;
    }
    }
    }