truetype技术和矢量字库的技术原理及实现

广泛汉字矢量字库(HZKSLxxJ)格式  
          在矢量字库中,每个汉字都是以128   X   128点阵制成矢量数据。每个汉字  
  的矢量数据都由一指针指向,   指针区在每个汉字字库文件的开头0xBB3E字节。  
  每个汉字矢量数据指针占6个字节,   其格式为:前4个字节为汉字的矢量数据在  
  文件中的偏移,   后2个字节为汉字的矢量数据的长度。  
   
          汉字指针在指针区的偏移由公式计算:pos=((qu-16)*94+wei-1)*6。  
                          注:qu--区号。wei--位号。  
   
          汉字的矢量数据格式为:控制码+坐标值。共有十种控制码,以下是控制码的   含义:  
          (1)若控制码第7,6位为11,清除码,结束当前笔划,将第一个坐标与当前坐  
  标连线;建立新笔划,(X,Y)各占7位,由控制码的第5位开始,即:11XXXXXX   XYYYYYYY。  
                  注:一个字节的位:  
                        7   6   5   4   3   2   1   0  
                        X   X   X   X   X   X   X   X  
          (2)若控制码小于等于0x40,之后控制码大小个字节为坐标值,每个坐标占   一个字节,  
  共有控制码大小个坐标,(X,Y)坐标各占4位,其自的最高位为符号位,   即:FXXXFYYY。  
          (3)若控制码的高4位等于4,之后控制码的低4位大小个字节为坐标值,每个  
  坐标占一个字节,共有控制码大小个坐标,(X,Y)坐标各占4位,X为正,Y为正,  
  即:+XXXX+YYYY。  
          (4)若控制码的高4位等于5,之后控制码的低4位大小个字节为坐标值,每个  
  坐标占一个字节,共有控制码大小个坐标,(X,Y)坐标各占4位,X为负,Y为正,  
  即:-XXXX+YYYY。  
          (5)若控制码的高4位等于6,之后控制码的低4位大小个字节为坐标值,每个  
  坐标占一个字节,共有控制码大小个坐标,(X,Y)坐标各占4位,X为负,Y为负,  
  即:-XXXX-YYYY。  
          (6)若控制码的高4位等于7,之后控制码的低4位大小个字节为坐标值,每个  
  坐标占一个字节,共有控制码大小个坐标,(X,Y)坐标各占4位,X为正,Y为负,  
  即:+XXXX-YYYY。  
          (7)若控制码等于0x80,   其后1字节为Y坐标值,   最高位为符号位,   X坐标不   变,   即:  
  10000000   FYYYYYYY。  
          (8)   若控制码等于0x90,   其后1字节为X坐标值,   最高位为符号位,   Y坐标不   变,即:  
  10000001   FXXXXXXX。  
          (9)   若控制码的高4位等于8,其后1字节为Y坐标值,控制码的低4位值为X坐  
  标值,X坐标各占4位,最高位为符号位,Y坐标各占8位,最高位为符号位,   即:1000FXXX  
  FYYYYYYY。  
          (10)若控制码的高4位等于9,其后1字节为X坐标值,控制码的低4位值为Y坐  
  标值,Y坐标各占4位,最高位为符号位,X坐标各占8位,最高位为符号位,   即:1000FYYY  
  FXXXXXXX。  
  -------------------------------------------------------------------------  
  用Turbo   C   2.0编译以下程序:  
  #include     
  #include     
  main()  
  {  
    unsigned   long   int   pos;  
    unsigned   int   i,j,k,len,q,w;  
    unsigned   char   c,a,x=0,y=0,x1,y1,xs=0,ys=0,buffer[100];  
    FILE   *fp;  
    int   d=DETECT,m=VGAHI;  
    if((fp=fopen("hzkslt","rb"))==NULL)   return;  
  /*                           ^^^^^^汉字字库的文件名                           */  
    printf("Input   Qu   :");scanf("%u",&q);  
    printf("Input   Wei:");scanf("%u",&w);  
    printf("//n");  
    pos=((q-1l)*94l+w-1l)*6l;  
    fseek(fp,pos,0);  
    fread(&pos,4,1,fp);  
  /*   printf("%lX   :   ",pos);*/  
    fread(&len,2,1,fp);  
    fseek(fp,pos,0);  
    initgraph(&d,&m,"   ");  
    while   (len!=0)  
    {  
      c=getc(fp);  
      len--;  
      if   ((c&0xf0)>=0xc0)  
      {  
        if   (q==0)  
          line(xs,ys,x,y);  
        x=c;  
        fread(&y,1,1,fp);  
        len--;  
        a=y;  
        y>>=7;  
        x=x&0x3f;  
        x<<=1;  
        x=x+y;  
        y=a&0x7f;  
        x1=x;y1=y;  
        xs=x;ys=y;  
        q=0;  
        continue;  
      }  
      /*if   ((c&0xf0)==0x00   &&   (c&0x0f)!=0)*/  
      if   (c<0x40 &&   c!=0)  
      {  
        fread(buffer,1,c,fp);  
        len-=c;  
        for(i=0;i        {  
          if   ((buffer[i]&0x80)==0)  
            x1=x+(buffer[i]>>4);  
          else  
            x1=x-((buffer[i]&0x70)>>4);  
          if   ((buffer[i]&0x08)==0)  
            y1=y+(buffer[i]&0x07);  
          else  
            y1=y-(buffer[i]&0x07);  
          line(x,y,x1,y1);  
          x=x1;  
          y=y1;  
        }  
        continue;  
      }  
      if   ((c&0xf0)==0x40   &&   (c&0x0f)!=0)  
      {  
        fread(buffer,1,(c&0x0f),fp);  
        len-=(c&0x0f);  
        for(i=0;i<(c&0x0f);i++)  
        {  
          x1=x+(buffer[i]>>4);  
          y1=y+(buffer[i]&0x0f);  
          line(x,y,x1,y1);  
          x=x1;  
          y=y1;  
        }  
        continue;  
      }  
      if   ((c&0xf0)==0x50   &&   (c&0x0f)!=0)  
      {  
        fread(buffer,1,(c&0x0f),fp);  
        len-=(c&0x0f);  
        for(i=0;i<(c&0x0f);i++)  
        {  
          x1=x-(buffer[i]>>4);  
          y1=y+(buffer[i]&0x0f);  
          line(x,y,x1,y1);  
          x=x1;  
          y=y1;  
        }  
        continue;  
      }  
      if   ((c&0xf0)==0x60   &&   (c&0x0f)!=0)  
      {  
        fread(buffer,1,(c&0x0f),fp);  
        len-=(c&0x0f);  
        for(i=0;i<(c&0x0f);i++)  
        {  
          x1=x-(buffer[i]>>4);  
          y1=y-(buffer[i]&0x0f);  
          line(x,y,x1,y1);  
          x=x1;  
          y=y1;  
        }  
        continue;  
      }  
      if   ((c&0xf0)==0x70   &&   (c&0x0f)!=0)  
      {  
        fread(buffer,1,(c&0x0f),fp);  
        len-=(c&0x0f);  
        for(i=0;i<(c&0x0f);i++)  
        {  
          x1=x+(buffer[i]>>4);  
          y1=y-(buffer[i]&0x0f);  
          line(x,y,x1,y1);  
          x=x1;  
          y=y1;  
        }  
        continue;  
      }  
      if   ((c&0xf0)==0x80   &&   (c&0x0f)==0x00)  
      {  
        buffer[0]=getc(fp);  
        len--;  
        if   ((buffer[0]&0x80)==0x80)  
          y1=y-(buffer[0]&0x7f);  
        else  
          y1=y+buffer[0];  
        line(x,y,x,y1);  
        y=y1;  
        continue;  
      }  
      if   ((c&0xf0)==0x80   &&   (c&0x0f)!=0x00)  
      {  
        buffer[0]=getc(fp);  
        len--;  
        if   ((c&0x08)==0x08)  
          x1=x-(c&0x07);  
        else  
          x1=x+(c&0x07);  
        if   ((buffer[0]&0x80)==0x80)  
          y1=y-(buffer[0]&0x7f);  
        else  
          y1=y+buffer[0];  
        line(x,y,x1,y1);  
        x=x1;  
        y=y1;  
        continue;  
      }  
      if   ((c&0xf0)==0x90   &&   (c&0x0f)==0x00)  
      {  
        buffer[0]=getc(fp);  
        len--;  
        if   ((buffer[0]&0x80)==0x80)  
          x1=x-(buffer[0]&0x7f);  
        else  
          x1=x+buffer[0];  
        line(x,y,x1,y);  
        x=x1;  
        continue;  
      }  
      if   ((c&0xf0)==0x90   &&   (c&0x0f)!=0x00)  
      {  
        buffer[0]=getc(fp);  
        len--;  
        if   ((buffer[0]&0x80)==0x80)  
          x1=x-(buffer[0]&0x7f);  
        else  
          x1=x+buffer[0];  
        if   ((c&0x08)==0x08)  
          y1=y-(c&0x07);  
        else  
          y1=y+(c&0x07);  
        line(x,y,x1,y1);  
        x=x1;  
        y=y1;  
        continue;  
      }  
      if   (c==0xb0)  
      {  
        buffer[0]=getc(fp);  
        buffer[1]=getc(fp);  
        len-=2;  
        if   ((buffer[0]&0x80)==0)  
          x1=x+(buffer[0]&0x7f);  
        else  
          x1=x-(buffer[0]&0x7f);  
        if   ((buffer[1]&0x80)==0)  
          y1=y+(buffer[1]&0x7f);  
        else  
          y1=y-(buffer[1]&0x7f);  
        line(x,y,x1,y1);  
        x=x1;  
        y=y1;  
        continue;  
      }  
      getch();  
      closegraph();  
      printf("//n",len,len,x,y,c,getc(fp));  
      break;  
    }  
    line(xs,ys,x,y);  
    getch();  
    closegraph();  
    /*printf("--//n",len,len,x,y);*/  
    fclose(fp);  
  }  

点阵字库是把每一个汉字都分成16×16或24×24个点,然后用每个点的虚实来表示汉字的轮廓,常用来作为显示字库使用,这类点阵字库汉字最大的缺点是不能放大,一旦放大后就会发现文字边缘的锯齿。 矢量字库保存的是对每一个汉字的描述信息,比如一个笔划的起始、终止坐标,半径、弧度等等。在显示、打印这一类字库时,要经过一系列的数学运算才能输出结果,但是这一类字库保存的汉字理论上可以被无限地放大,笔划轮廓仍然能保持圆滑,打印时使用的字库均为此类字库。Windows使用的字库也为以上两类,在FONTS目录下,如果字体扩展名为FON,表示该文件为点阵字库,扩展名为TTF则表示矢量字库!

矢量字体是与点阵字体相对应的一种字体。矢量字体的每个字形都是通过数学方程来描述的,一个字形上分割出若干个关键点,相邻关键点之间由一条光滑曲线连接,这条曲线可以由有限个参数来唯一确定。矢量字的好处是字体可以无级缩放而不会产生变形。目前主流的矢量字体格式有3种:Type1,TrueType和OpenType,这三种格式都是平台无关的。
  Type1全称PostScript? Type1,是1985年由Adobe公司提出的一套矢量字体标准,由于这个标准是基于PostScript Description Language(PDL),而PDL又是高端打印机首选的打印描述语言,所以Type1迅速流行起来。但是Type1是非开放字体,Adobe对使用Type1的公司征收高额的使用费。
  TrueType是1991年由Apple公司与Microsoft公司联合提出另一套矢量字标准。
  Typ1使用三次贝塞尔曲线来描述字形,TrueType则使用二次贝塞尔曲线来描述字形。所以Type1的字体比TrueType字体更加精确美观。一个误解是,Type1字体比TrueType字体占用空间多。这是因为同样描述一个圆形,二次贝塞尔曲线只需要8个关键点和7段二次曲线;而三次贝塞尔曲线则需要12个关键点和11段三次曲线。然而实际情况是一般来说 Type1比TrueType要小10%左右。这是因为对于稍微复杂的字形,为了保持平滑,TrueType必须使用更多的关键点。由于现代大部分打印机都是使用PDL作为打印描述语言,所以True1字体打印的时候不会产生形变,速度快;而TrueType则需要翻译成PDL,由于曲线方程的变化,还会产生一定的形变,不如Type1美观。
  这么说来,Type1应该比TrueType更具有优势,为什么如今的计算机上TrueType反而比Type1使用更广泛呢?这是因为第一:Type1由于字体方程的复杂,所以在屏幕上渲染的时候,花费的时间多,解决方案是大部分Type1字体嵌入了点阵字体,这样渲染快,但是边缘不光滑,比较难看。很多ps文档和ps转换的pdf文档都是这样,在计算机上浏览的时候字体很难看,但是打印出来很美观。TrueType则渲染比较快,可以平滑的显示在屏幕上,看上去很美观。
  第二个原因是Type1的高额使用费,使得Type1没有被所有的操作系统所支持。Windows家族只有OS/2和windows 2000及之后的版本从操作系统级别开始支持Type1。由于这个问题,Adobe只好在其所有的产品中嵌入Adobe Type Manager(ATM)作为渲染引擎。
  OpenType则是Type1与TrueType之争的最终产物。1995年,Adobe公司和Microsoft公司开始联手开发一种兼容Type1和TrueType,并且真正支持Unicode的字体,后来在发布的时候,正式命名为OpenType。OpenType可以嵌入Type1和TrueType,这样就兼有了二者的特点,无论是在屏幕上察看还是打印,质量都非常优秀。可以说OpenType是一个三赢的结局,无论是Adobe,Microsoft还是最终用户,都从OpenType中得到了好处。Windows家族从Windows 2000开始,正式支持OpenType。打开系统的字体目录(一般是C://Windows//Fonts//或C://Winnt//Fonts),可以看到:一个红色A的图标的是点阵字体,两个重叠的T的图标是TrueType字体,一个O的图标就是OpenType字体。
  btw, Agfa貌似是Type1的忠实拥趸,我看到的Agfa字体都是Type1的,不过真的是非常漂亮
说起矢量字体,不得不说一下多边形填充原理。本来是想将多边形填充作为单独的一节内容,可惜说得太细我累大家也累。

  多边形填充最需要关注的就是斜率,计算每条边的斜率,从而得到每条边在每一行上的切点。然后从左到右,将各切点连接起来,逐行进行。

   多边形有两种填充方式,Alternate和Winding。矢量字体主要用的前一种方式,而winding会将所有的切点都连接起来,没有了中间的分隔区域。

  比如,在Alternate模式下,从最左边的切点1,会连接切点2,然后从切点3连接到切点4,而2到3是不连接的。这样就形成了一个空洞,也是矢量字的奥秘所在。Winding模式会将所有的切点都连接起来,即从最左边的一直画到最右边。

FillMode

 

多边形组——PolyPolygon

 

将多个多边形组合成一个组,从而形成复杂的多边形组。同样,这个组也依赖于FillMode的填充模式。下面我们来看一下中文的“口”是如何写出来的。

“口”由两条多边形组合而成,根据FillMode为Alternate,相重叠的部分不显示。用笔在字的中央画一条横线,就可以找到4个交点,而交点2到3是不连接的,这样就形成了“口”中间的洞。

 

微软Arial字体中“S”的曲线

微软的Arial字体中存储的“S”,就是多个Bezier3点组成的。点41是锚点,而40和42是控制点,来控制通过41的曲线的张力。在点的定义上,有on curve和not on curve两种,通常将在曲线上的点定为锚点,而不在曲线上的点为控制点。

 

这是我年初的时候,为了研究矢量字体,将字母P用微软的方式输出后,再读取字库点阵数据,使用红叉画出字库中所有的点。P是由两条Bezier曲线包围而成的,第二条起着切割的目的,已形成P中间的圆洞。

 

看看字母“B”的填充。

 

  字体是如何保证对齐的呢?原来在字库内部,有一个基准线,就好像信纸的虚线,用来水平方向对齐的,同样,也有个垂直方向的基准线。每个字都有上浮和下沉的高度,这也是该字的最上和最下的点所处的位置。

 

    矢量字在不同字号下,根据点阵尺寸,显示的精细程度也不一样。我们这里将“8”放大了看,在小字号和大字号下的效果。

 

    在不同的字号下,根据最简单的缩放原理,将所有的点缩放到合适的位置,再确定曲线。这时候,一条边就占据不了整列像素,或者一条边压在了两列像素的中间,这样就造成了灰色的线条。而这并不是我们想要的效果,Photoshop通过USM锐化滤镜,将虚边得以逐步清晰,以达到所要的矢量字。

 

    苹果系统通过调整整体点阵的位置,将所有的点适当便宜半个像素以内的位置,可以实现较为清晰的字体。如果在关闭了消除锯齿方式,则有些边线由于占据不了半个像素,而不能够显示,这就形成了所谓的缺边或者缺笔划。

 

有些软件,比如Adobe Acrobat,通过一种较为复杂的方式,以实现矢量字的清晰。将某些关联的点作为一个segment,并且局部偏移到邻近的整数位,而其他部分不动。这种方法目前较为流行,可以实现比苹果和ps还要清晰的矢量效果。

 

为什么我们通常看到的齿条文字这么清晰呢

  微软的TTF为了保证小字号下的清晰,可谓是用尽了方法。首先,在庞大的字库,内置了数个字号的点阵字,接着才是矢量字。比如宋体,内置了12、14、16、18等几个点阵字库,在这些之外才使用矢量字库来渲染。这也是为什么一个TTF文件要几兆甚至几十兆的容量,不过内嵌的点阵字越多,在不同字号下实现的效果自然越好。别小看了这些点阵字,每一个都是平面设计师在工具上画的,并非由软件生成。唉,可怜的设计师啊~~~~~~

  不过,有个特例。比如Arial字体,内部全是矢量字,但各种尺寸下都是这么清晰。为什么呢?

  原来,微软在字库中加入了解释程序,interpreter,一种专门用于字库渲染的脚本命令。在不同的字号下,都有相应的语句,将矢量字得以最清晰化。这是一种复杂的技术,微软也觉得不能广泛使用,所以只有在部分的英文字库中才有,而且该脚本对应每个字都有一段代码,容量非常大,用在汉字上几乎是不可能,除非是整个文字不多于100个才能使用。

  interpreter就是这么神奇,他也是目前最好的技术,能够将矢量字渲染的和点阵字一样的清晰。他将某些边线的距离拉开,而将另一部分收缩,总之是按照人的想法来做的,这也是编好的程序。

 

  我用一种新的方式,保证了任何字号下的清晰。目前还在做实验,希望将来能够做成PS的插件,或者做成个工具,输出成PNG格式。这样,设计师就能够显示最清晰的矢量字体了,免得用PS输出的看不清。

 

 

矢量字体的终极技术


在1998年的时候,微软声称发明了一种新的技术,能在LCD上将矢量字体的清晰度提高到300%。而后,出现了名为Microsoft Reader的软件,我还用过几个版本。Adobe也不甘示弱,随即在Acrobat 4中对CoolType进行了支持,而Linux的FreeType库也开始支持次像素平滑。据我多年的研究观察,Acrobat做的最好,最灵活,而微软的缺少适当的调节工具,Linux的次像素平滑简直就是垃圾,照虎画猫。

ClearType使用彩色来描边,显示对比度越是强的文字,比如白底黑字或者黑底白字,都是最清晰的。其实,理论上ClearType能够将显示精度提到到300%,但实际上只能达到200%左右。

 

一般来说,液晶显示器的点阵分布都非常均匀,每个点都是由红绿蓝3色排列而成。我们通常要显示一个白色,需要将红绿蓝都点亮,而黑色是都不显示。ClearType将点的概念再次扩展,把邻近的两个点3色混淆,借前一个点的颜色而忽略后一点的某种颜色。这样,就可以把传统的一个点的最小单位扩展到1/3个点的单位。

 

在使用ClearType技术后,原来的字体渲染将更加清晰,当然,只限于LCD显示器,CRT会更加模糊。ClearType还有一个关键的技术,就是Linux的次像素平滑没有学去的地方,一定要考虑到红绿蓝的颜色亮度平衡。一般来说,绿色的亮度最高,而蓝色的最低,所以我们要在显示绿色的时候加点红色和蓝色来调低亮度,而显示蓝色的时候要加入绿色和红色来增加亮度。这种做法也可以使边界的彩边不是那么明显,看起来更像是黑色的字。不过,这种做法使得原本可以提高显示精细程度到300%的技术,降低了许多,不过还是要高于200%。

下面我最满意的矢量字效果,这是试验程序截图,以后做成PS的插件,供大家免费下载使用。

注:仅限LCD显示器观看,否则效果只会更差。
矢量字体中每一个字形是通过数学曲线来描述的,它包含了字形边界上的关键点,连线的导数信息等,字体的渲染引擎通过读取这些数学矢量,然后进行一定的数学运算来进行渲染。这类字体的好处是字体可以无限放大而不产生变形。矢量字体主要包括 Type1 和 TrueType 等几类。

  又叫Outline font,通常使用贝塞尔曲线,绘图指令和数学公式进行绘制。这样可以在对字体进行放大的时候保持字体边缘的光滑,更美观。

一般图片根据信息表示方式分为的矢量图和位图。


   矢量图就是用一系列计算指令来表示的图,因此矢量图是用数学方法描述的图,本质上是很多个数学表达式的编程语言表达。画矢量图的时候如果速度比较慢,你可以看到绘图的过程。

 

   可以把矢量图理解为一个“形状”,比如一个圆,一个抛物线等等,因此缩放不会影响其质量。

 

   位图是象素集合。不用我解释了。

 

   矢量图用途是:

 

   矢量图一般用来表达比较小的图像,移动,缩放,旋转,拷贝,改变属性都很容易,一般用来做成一个图库,比如很多软件里都有矢量图库,把它拖出来随便你画多大都行。

 

   而数码照片一般都是位图。

   矢量图可以转换成位图,不过反过来把位图转换为矢量图技术上比较难实现,很多图形设计软件都支持将像素图转换成矢量图性,一般可用矢量软件的描摹功能实现,这样就可以在矢量图形的基础上再做编辑,但这样的转换有时候会很耗时,有时候并不能达到预想的效果,一般用于比较简单的位图,或者想要表现一些特殊的效果。

   矢量图由矢量轮廓线和矢量色块组成,文件的大小由图像的复杂程度决定,与图形的大小无关,并且矢量图可以无限放大而不会模糊。

   平时看到的很多图像(如数码照片)被称为像素图(也叫点阵图、光栅图、位图),它们是由许多像小方块一样的像素点(Pixels)组成的,位图中的像素由其位置值和颜色值表示。

位图:
又称光栅图,一般用于照片品质的图像处理,是由许多像小方块一样的"像素"组成的图形。由其位置与颜色值表示,能表现出颜色阴影的变化。在PHOTOSHOP主要用于处理位图。

关于矢量图形几个概念的说明
2000-07-10· sunone·CPCW

何谓矢量图像?
矢量图像,也称为面向对象的图像或绘图图像,在数学上定义为一系列由线连接的点。矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。既然每个对象都是一个自成一体的实体,就可以在维持它原有清晰度和弯曲度的同时,多次移动和改变它的属性,而不会影响图例中的其它对象。这些特征使基于矢量的程序特别适用于图例和三维建模,因为它们通常要求能创建和操作单个对象。基于矢量的绘图同分辨率无关。这意味着它们可以按最高分辨率显示到输出设备上。
何谓位图图像?
  与上述基于矢量的绘图程序相比,像 Photoshop 这样的编辑照片程序则用于处理位图图像。当您处理位图图像时,可以优化微小细节,进行显著改动,以及增强效果。位图图像,亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增多单个像素,从而使线条和形状显得参差不齐。然而,如果从稍远的位置观看它,位图图像的颜色和形状又显得是连续的。由于每一个像素都是单独染色的,您可以通过以每次一个像素的频率操作选择区域而产生近似相片的逼真效果,诸如加深阴影和加重颜色。缩小位图尺寸也会使原图变形,因为此举是通过减少像素来使整个图像变小的。同样,由于位图图像是以排列的像素集合体形式创建的,所以不能单独操作(如移动)局部位图。
为什么处理位图时要着重考虑分辨率?
  处理位图时,输出图像的质量决定于处理过程开始时设置的分辨率高低。分辨率是一个笼统的术语,它指一个图像文件中包含的细节和信息的大小,以及输入、输出、或显示设备能够产生的细节程度。操作位图时,分辨率既会影响最后输出的质量也会影响文件的大小。处理位图需要三思而后行,因为给图像选择的分辨率通常在整个过程中都伴随着文件。无论是在一个300 dpi的打印机还是在一个2570dpi的照排设备上印刷位图文件,文件总是以创建图像时所设的分辨率大小印刷,除非打印机的分辨率低于图像的分辨率。如果希望最终输出看起来和屏幕上显示的一样,那么在开始工作前,就需要了解图像的分辨率和不同设备分辨率之间的关系。显然矢量图就不必考虑这么多。
了解 CorelDRAW 中的对象
  CorelDRAW 中的对象可以是任何基本的绘图元素或者是一行文字,例如线条、椭圆、多边形、矩形、标注线或一行美术字等。创建完一个简单对象后,就可以定义出它的特征,如填充颜色、轮廓颜色、曲线平滑度等,并对其应用特殊效果。在这些信息中,包括对象在屏幕中的位置、创建它的顺序、以及定义的属性值,都将作为对象描述的一部分。这意味着当操作对象(如移动对象)时,CorelDRAW 会重建其形状和全部属性。
  对象可以有一条封闭路径或者一条开放路径。一个群组对象是由一个或多个对象构成的。当用挑选工具选择一个对象时,可以通过它四周的选择框来识别它。当选中一个对象时,选择框的边角和中点会出现 8个填充方块。每个单独的对象都有自己的选择框。当用“组群”命令把两个或更多的对象进行组合时,将会产生一个组群,可以把它当作一个对象来选择和操作。对象由路径构成,这些路径构成了它的轮廓和边界。一个路径可由单个或几个线段构成。每个线段的端点有一个中空的方块,称为节点。可以用形状工具选择一个对象的节点,从而改变它的总体形状和弯曲角度。
开放路径对象和封闭路径对象有什么区别?
  开放路径对象的两个端点是不相交的。封闭路径对象就是那种两个端点相连构成连续路径的对象。开放路径对象既可能是直线,也可能是曲线,例如用手绘工具创建的线条、用贝塞尔曲线工具创建的线条或用螺纹工具创建的螺纹线等。但是,在用“手绘工具”或“贝塞尔曲线工具”时,把起点和终点连在一起也可以创建封闭路径。封闭路径对象包括圆、正方形、网格、自然笔线、多边形和星形等。封闭路径对象是可以填充的,而开放路径对象则不能填充。

你可能感兴趣的:(GUI,framework)