IGPGraphicsPathIterator 能遍历路径中的子路径和路径标记.
IGPGraphicsPathIterator.Count; { 点总数 } IGPGraphicsPathIterator.SubpathCount; { 子路径数 } IGPGraphicsPathIterator.HasCurve; { 是否包含曲线 } IGPGraphicsPathIterator.Rewind; { 重新开始, 用于遍历前 } IGPGraphicsPathIterator.NextSubPath(); { 下一个子路径 } IGPGraphicsPathIterator.NextPathType(); { 当前子路径起始点的类型; 必须和 NextSubPath 同时使用 } IGPGraphicsPathIterator.Enumerate; { 获取路径数据的函数, 应在 NextMarker 过程中使用 } IGPGraphicsPathIterator.CopyData(); { 复制指定范围的路径数据 } IGPGraphicsPathIterator.NextMarker(); { 下一个路径标记 }
Count、SubpathCount、HasCurve 测试:
uses GdiPlus; procedure TForm1.FormCreate(Sender: TObject); var Path: IGPGraphicsPath; PathIterator: IGPGraphicsPathIterator; Rect: TGPRect; str: string; begin Rect.Initialize(20, 20, 150, 100); Path := TGPGraphicsPath.Create; Path.AddRectangle(Rect); Path.AddEllipse(Rect); PathIterator := TGPGraphicsPathIterator.Create(Path); with TStringBuilder.Create do begin Append('点总数: '); Append(PathIterator.Count); AppendLine; Append('子路径数: '); Append(PathIterator.SubpathCount); AppendLine; Append('是否包含曲线: '); Append(PathIterator.HasCurve); str := ToString; Free; end; ShowMessage(str); end;
NextSubPath、Rewind 测试:
uses GdiPlus, GdiPlusHelpers; var Path: IGPGraphicsPath; PathIterator: IGPGraphicsPathIterator; { 初始化数据 } procedure TForm1.FormCreate(Sender: TObject); var Pt1,Pt2: TGPPoint; Rect: TGPRect; begin Pt1.Initialize(20, 20); Pt2.Initialize(150, 150); Rect.InitializeFromLTRB(Pt1.X, Pt1.Y, Pt2.X , Pt2.Y); Path := TGPGraphicsPath.Create; Path.AddRectangle(Rect); Path.AddEllipse(Rect); Path.AddLine(Pt1.X, Pt1.Y, Pt2.X, Pt2.Y); PathIterator := TGPGraphicsPathIterator.Create(Path); end; { 绘制路径 } procedure TForm1.FormPaint(Sender: TObject); var Pen: IGPPen; begin Pen := TGPPen.Create($FFC0C0C0); Canvas.ToGPGraphics.DrawPath(Pen, Path); end; { 遍历路径 } procedure TForm1.Button1Click(Sender: TObject); var Pen: IGPPen; PathSection: IGPGraphicsPath; B: Boolean; //这 out 参数需要的 begin Pen := TGPPen.Create($FFFF0000, 2); PathSection := TGPGraphicsPath.Create; //这也需要先建立 PathIterator.NextSubPath(PathSection, B); Repaint; Canvas.ToGPGraphics.DrawPath(Pen, PathSection); Tag := Tag + 1; //借 Self.Tag 一用 if Tag = PathIterator.SubpathCount then begin Tag := 0; PathIterator.Rewind; end; end;
NextPathType 测试:
uses GdiPlus; procedure TForm1.FormCreate(Sender: TObject); var Path: IGPGraphicsPath; PathIterator: IGPGraphicsPathIterator; Rect: TGPRect; bool: Boolean; m1,m2,n,n1,n2: Integer; b: Byte; begin Rect.Initialize(20, 20, 150, 100); Path := TGPGraphicsPath.Create; Path.AddRectangle(Rect); Path.AddEllipse(Rect); PathIterator := TGPGraphicsPathIterator.Create(Path); while PathIterator.NextSubPath(m1, m2, bool) <> 0 do begin n := PathIterator.NextPathType(b, n1, n2); ShowMessageFmt('%d-%d; %d: %d-%d', [m1,m2,n,n1,n2]); end; //0-3; 4: 0-3 //4-16; 13: 4-16 end;
NextMarker、CopyData、Enumerate 测试:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses GdiPlus, GdiPlusHelpers; var Path: IGPGraphicsPath; PathIterator: IGPGraphicsPathIterator; { 初始化 Path 与 PathIterator } procedure TForm1.FormCreate(Sender: TObject); var Rect: TGPRect; begin Path := TGPGraphicsPath.Create; { 用路径 Marker 把路径分成了三部分 } Path.AddLine(TGPPoint.Create(20, 20), TGPPoint.Create(200, 20)); Path.AddLine(TGPPoint.Create(20, 50), TGPPoint.Create(200, 50)); Path.SetMarker; Path.AddLine(TGPPoint.Create(20, 80), TGPPoint.Create(200, 80)); Path.AddLine(TGPPoint.Create(20, 110), TGPPoint.Create(200, 110)); Path.SetMarker; Path.AddLine(TGPPoint.Create(20, 140), TGPPoint.Create(200, 140)); Path.AddLine(TGPPoint.Create(20, 170), TGPPoint.Create(200, 170)); PathIterator := TGPGraphicsPathIterator.Create(Path); end; { 绘制 Path } procedure TForm1.FormPaint(Sender: TObject); var Pen: IGPPen; begin Pen := TGPPen.Create($FFC0C0C0, 2); Canvas.ToGPGraphics.DrawPath(Pen, Path); end; { 测试 CopyData 函数 } procedure TForm1.Button1Click(Sender: TObject); var Pen: IGPPen; Brush: IGPSolidBrush; PathTmp: IGPGraphicsPath; n1,n2: Integer; Data: IGPPathData; Rect: TGPRectF; i: Integer; ps: array of TGPPointF; ts: array of Byte; begin Repaint; Pen := TGPPen.Create($80FF0000, 2); Brush := TGPSolidBrush.Create($FF0000FF); if PathIterator.NextMarker(n1, n2) = 0 then begin PathIterator.Rewind; Exit; end; Data := PathIterator.CopyData(n1, n2); for i := 0 to Data.Count - 1 do begin Rect.Initialize(Data.Points[i].X -3, Data.Points[i].Y-3, 6, 6); Canvas.ToGPGraphics.FillRectangle(Brush, Rect); end; SetLength(ps, Data.Count); SetLength(ts, Data.Count); CopyMemory(ps, Data.PointPtr, Data.Count * SizeOf(TGPPointF)); CopyMemory(ts, Data.TypePtr, Data.Count); PathTmp := TGPGraphicsPath.Create(ps, ts); Canvas.ToGPGraphics.DrawPath(Pen, PathTmp); end; { 测试 Enumerate 函数 } procedure TForm1.Button2Click(Sender: TObject); var Pen: IGPPen; Brush: IGPSolidBrush; PathTmp: IGPGraphicsPath; n1,n2: Integer; Data: IGPPathData; Rect: TGPRectF; i: Integer; ps: array of TGPPointF; ts: array of Byte; begin Repaint; Pen := TGPPen.Create($80FF0000, 2); Brush := TGPSolidBrush.Create($FF0000FF); if PathIterator.NextMarker(n1, n2) = 0 then begin PathIterator.Rewind; Exit; end; Data := PathIterator.Enumerate; { 和 Button1Click 就这一句不一样 } for i := 0 to Data.Count - 1 do begin Rect.Initialize(Data.Points[i].X -3, Data.Points[i].Y-3, 6, 6); Canvas.ToGPGraphics.FillRectangle(Brush, Rect); end; SetLength(ps, Data.Count); SetLength(ts, Data.Count); CopyMemory(ps, Data.PointPtr, Data.Count * SizeOf(TGPPointF)); CopyMemory(ts, Data.TypePtr, Data.Count); PathTmp := TGPGraphicsPath.Create(ps, ts); Canvas.ToGPGraphics.DrawPath(Pen, PathTmp); end; end.