正义女神f面罩:beginpath路径

来源:百度文库 编辑:偶看新闻 时间:2024/04/30 00:19:00
1   路径的概念 
在Windows   95/NT   这样的Win32操作系统中,除了已有的位图,画笔,画刷,字体,调色板和区域之外,还增加了一个新的GDI对象:路径。路径是可以被填充,画出轮廓或同时被画出轮廓并填充的一个或多个图形。路径的引入,大大地丰富了Windows的图形功能,使得应用程序可以方便地建立复杂区域,绘制和填充不规则图形。这里说的不规则图形是指由直线和贝塞尔曲线组成的图形(相对于矩形,多边形,椭圆等规则图形)。 

2   路径的使用   
与其它原有的GDI对象不同的是,MFC类库没有专门用一个C++类来封装路径对象(或许在以后的版本中会得到支持)。有关路径的定义和使用等各种操作都必须通过调用API函数(或CDC类中对应的成员函数)来实现。 
路径的使用过程大致如下: 
(1)调用BeginPath()函数开始路径定义; 
(2)调用GDI绘图函数来定义路径; 
在Win32中,可以用于定义路径的GDI绘图函数包括: 
AngleArc   Arc   ArcTo   Chord   *CloseFigure 
Ellipse   *ExtTextOut   *LineTo   *MoveToEx   Pie 
*PolyBezier   *PolyBezierTo   PolyDraw   *Polygon   *Polyline 
*PolyLineTo   *PolyPolygon   *PolyPolylin   Rectangl   RoundRect 
*TextOut 
其中,在Windows   95中只能使用上述带*的GDI函数。 
(3)调用EndPath()函数结束路径定义; 
完成路径定义后,所定义的路径即被同时选进设备描述表,设备描述表中原有的路径对象在调用BeginPath()函数开始路径定义时即被废弃。 
(4)使用路径对象。 
完成路径定义工作之后,应用程序便可以利用有关GDI函数来使用路径,这些函数包括绘制路径轮廓StrokePath(),填充路径FillPath(),绘制轮廓并填充StrokeAndFillPath(),把路径转换成区域PathToRegion(),把路径直线化FlattenPath(),提取路径数据GetPath(),加宽路径WidenPath()和设置裁剪路径SelectClipPath()等。这些函数的具体使用方法可参阅有关的SDK文档。 

3   应用举例 
路径的引入为我们在应用程序中定义复杂区域提供了极大的方便,而不再局限于直线和椭圆弧这两种线形,这一点是很容易理解的。 
另外,注意到在定义路径时可以使用TextOut()和ExtTextOut()函数,我们便可以在文字特色显示方面巧妙地使用路径,克服以往文字特显对位图操作的倚赖,从而方便快捷地制作出堪与WPS和Word等文字处理软件相媲美的“艺术汉字”来。 
本文下面所提供的这个示例程序执行后,在窗口中显示出按正弦曲线起伏排列的“龙腾虎跃”五个楷体大字。窗口背景为灰色,文字前景则为一幅256色位图,就好象是把彩图剪成文字粘贴在窗口上一样(见下图)。下面具体说明该示例程序的创建方法。 

(1)启动VC++,创建一个单文档应用,项目名取为Path,其它选项保留原缺省设置。 
(2)在CPathView类中增加一个成员变量: 
//   PathView.h   :   interface   of   the   CPathView   class 
…… 
class   CPathView   :   public   CView 

…… 
//   Implementation 
public: 
CFont   m_fontKaiTi; 
…… 
并在CPathView类的构造函数中创建该Cfont对象,在CPathView类的析构函数中撤消该Cfont对象: 
//   PathView.cpp   :   implementation   of   the   CPathView   class 
…… 
CPathView::CPathView() 

//   TODO:   add   construction   code   here 
m_fontKaiTi.CreateFont(200   ,   0   ,   0   ,   0   ,   FW_BLACK   ,   
FALSE   ,   FALSE   ,   FALSE   , 
GB2312_CHARSET   ,   
OUT_DEFAULT_PRECIS   , 
CLIP_DEFAULT_PRECIS   ,   
DEFAULT_QUALITY   , 
FIXED_PITCH   |   FF_MODERN, 
"楷体_GB2312 "); 

CPathView::~CPathView() 

m_fontKaiTi.DeleteObject(); 

(3)在CPathView::OnDraw()函数中添加如下代码: 
void   CPathView::OnDraw(CDC*   pDC) 

…… 
//   TODO:   add   draw   code   for   native   data   here 
RECT   rect; 
GetClientRect(&rect); 

CFont*   pOldFont=(CFont*)pDC-> SelectObject(&m_fontKaiTi); 
pDC-> SetBkMode(TRANSPARENT); 

//定义路径 
pDC-> BeginPath();{ 
pDC-> TextOut(0,10, "龙 ",2); 
pDC-> TextOut(200,10, "腾 ",2); 
pDC-> TextOut(400,10, "虎 ",2); 
pDC-> TextOut(600,10, "跃 ",2);   } 
pDC-> EndPath(); 

pDC-> SelectObject(pOldFont); 

//检取路径数据 
int   nCount=pDC-> GetPath(NULL,NULL,0); 
CPoint*   points=new   CPoint[nCount]; 
BYTE*   bytes=new   BYTE[nCount]; 
pDC-> GetPath(points,bytes,nCount); 

//对路径定义点按正弦曲线进行变换 
int   i; 
for(i=0;i points[i].y=points[i].y+(int)(80*sin(points[i].x 
/300.*3.1415926)+100); 

//重建一个新的路径 
CPoint   ptStart; 
pDC-> BeginPath();{ 
for(i=0;i switch(bytes[i]){ 
//移动当前点位置 
case   PT_MOVETO: 
pDC-> MoveTo(points[i]); 
ptStart=points[i]; 
break; 
//画直线 
case   PT_LINETO: 
pDC-> LineTo(points[i]); 
break; 
//画贝塞尔曲线 
case   PT_BEZIERTO: 
pDC-> PolyBezierTo(points+i,3); 
i=i+2; 
break; 
//画贝塞尔曲线并封闭图形 
case   PT_BEZIERTO|PT_CLOSEFIGURE: 
points[i+2]=ptStart; 
pDC-> PolyBezierTo(points+i,3); 
i=i+2; 
break; 
//画直线并封闭图形 
case   PT_LINETO|PT_CLOSEFIGURE: 
pDC-> LineTo(ptStart); 
break; 


pDC-> CloseFigure(); 

pDC-> EndPath(); 

//绘制窗口灰色背景 
CBrush*   pOldBrush=(CBrush*)(pDC-> SelectStockObject(GRAY_BRUSH)); 
pDC-> Rectangle(&rect); 
pDC-> SelectObject(pOldBrush); 

//设置裁剪路径 
pDC-> SetPolyFillMode(WINDING); 
pDC-> SelectClipPath(RGN_COPY); 

//用位图填充裁剪区域 
CBitmap   bmp; 
CBitmap*   pBmpOld; 
bmp.LoadBitmap(IDB_BMP); 

CDC   dcMem; 
dcMem.CreateCompatibleDC(pDC); 
pBmpOld=dcMem.SelectObject(&bmp); 

pDC-> StretchBlt(0,0,rect.right,rect.bottom, 
&dcMem,0,0,600,100,SRCCOPY); 

dcMem.SelectObject(pBmpOld); 
dcMem.DeleteDC(); 
bmp.DeleteObject(); 

(4)在资源中添加文字前景位图,其ID为IDB_BMP。 
(5)编译,连接,运行该应用程序。