GdiPlus[39]: IGPGraphicsPath (六) - 路径的辅助工具 IGPGraphicsPathIterator


IGPGraphicsPathIterator 能遍历路径中的子路径和路径标记.


IGPGraphicsPathIterator.Count;          { 点总数 }

IGPGraphicsPathIterator.SubpathCount;   { 子路径数 }

IGPGraphicsPathIterator.HasCurve;       { 是否包含曲线 }



IGPGraphicsPathIterator.Rewind;         { 重新开始, 用于遍历前 }

IGPGraphicsPathIterator.NextSubPath();  { 下一个子路径 }

IGPGraphicsPathIterator.NextPathType(); { 当前子路径起始点的类型; 必须和 NextSubPath 同时使用 }

IGPGraphicsPathIterator.Enumerate;      { 获取路径数据的函数, 应在 NextMarker 过程中使用 }

IGPGraphicsPathIterator.CopyData();     { 复制指定范围的路径数据 }

IGPGraphicsPathIterator.NextMarker();   { 下一个路径标记 }


 
   

Count、SubpathCount、HasCurve 测试:

GdiPlus[39]: IGPGraphicsPath (六) - 路径的辅助工具 IGPGraphicsPathIterator


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 测试:

GdiPlus[39]: IGPGraphicsPath (六) - 路径的辅助工具 IGPGraphicsPathIterator


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 测试:

GdiPlus[39]: IGPGraphicsPath (六) - 路径的辅助工具 IGPGraphicsPathIterator


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.


 
   

你可能感兴趣的:(iterator)