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.