再学 GDI+[50]: 路径 - GetPathPoints、GetPathTypes、TPathData、GetPathData


这个例子有错误! 点的类型很多时候不是单一的;

譬如某个点可能同时是子路径结束点、曲线点、标记点, 此时类型值就是三种类型的复合值.

遗憾的是做这个例子时, 我还不知道... 放在这里吧, 留个纪念, 记下曾经的幼稚!


本例效果图:

再学 GDI+[50]: 路径 - GetPathPoints、GetPathTypes、TPathData、GetPathData

代码文件:

unit Unit1;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, Grids;



type

  TForm1 = class(TForm)

    StringGrid1: TStringGrid;

    procedure FormCreate(Sender: TObject);

    procedure FormPaint(Sender: TObject);

    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;

      var CanSelect: Boolean);

  end;



var

  Form1: TForm1;



implementation



{$R *.dfm}



uses GDIPOBJ, GDIPAPI;



procedure TForm1.FormCreate(Sender: TObject);

begin

  StringGrid1.Align := alRight;

  StringGrid1.FixedCols := 0;

  StringGrid1.ColCount := 3;

  StringGrid1.ColWidths[0] := 25;

  StringGrid1.ColWidths[1] := 25;

  StringGrid1.ColWidths[2] := 80;

  StringGrid1.DefaultRowHeight := 20;



  StringGrid1.Cells[0,0] := 'X';

  StringGrid1.Cells[1,0] := 'Y';

  StringGrid1.Cells[2,0] := '点类型';

end;



procedure TForm1.FormPaint(Sender: TObject);

var

  g: TGPGraphics;

  p: TGPPen;

  path: TGPGraphicsPath;

  points: array of TGPPoint;

  types: PByte;

  typestr: string;

  i: Integer;

begin

  g := TGPGraphics.Create(Canvas.Handle);

  p := TGPPen.Create(aclRed);

  path := TGPGraphicsPath.Create;



  path.StartFigure;

  path.AddRectangle(MakeRect(30,20,90,40));

  path.AddEllipse(MakeRect(30,80,90,180));

  path.CloseFigure;



  g.DrawPath(p, path);



  SetLength(points, path.GetPointCount);

  GetMem(types, path.GetPointCount);



  path.GetPathPoints(PGPPoint(points), Length(points));

  path.GetPathTypes(types, Length(points));



  StringGrid1.RowCount := Length(points) + 1;



  for i := 0 to Length(points) - 1 do

  begin

    case types^ of

      $00 : typestr := '路径起始点';

      $01 : typestr := '直线点';

      $03 : typestr := '贝塞尔线点';

      $07 : typestr := '遮盖点';

      $10 : typestr := '虚线点';

      $20 : typestr := '路径标记';

      $80 : typestr := '子路径结束点';

    end;

    StringGrid1.Cells[0, i+1] := IntToStr(points[i].X);

    StringGrid1.Cells[1, i+1] := IntToStr(points[i].Y);

    StringGrid1.Cells[2, i+1] := typestr;

    Inc(types);

  end;



  Dec(types, Length(points));

  FreeMem(types);

  types := nil;

  path.Free;

  p.Free;

  g.Free;

end;



procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;

  var CanSelect: Boolean);

var

  x,y: Integer;

begin

  x := StrToIntDef(StringGrid1.Cells[0,ARow], 0);

  y := StrToIntDef(StringGrid1.Cells[1,ARow], 0);

  Repaint;

  Canvas.Brush.Color := clBlue;

  Canvas.FillRect(Bounds(x-3,y-3,6,6));

  Text := Format('%d,%d',[x,y]);

end;



end.


 
   
这个例子有点麻烦, 如果使用 TPathData 类会简单许多, 下面是用 TPathData 实现的代码, 运行效果相同; 不过这样获取的点数组必须是小数数组. 代码如下:

unit Unit1;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, Grids;



type

  TForm1 = class(TForm)

    StringGrid1: TStringGrid;

    procedure FormCreate(Sender: TObject);

    procedure FormPaint(Sender: TObject);

    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;

      var CanSelect: Boolean);

  end;



var

  Form1: TForm1;



implementation



{$R *.dfm}



uses GDIPOBJ, GDIPAPI;



procedure TForm1.FormCreate(Sender: TObject);

begin

  StringGrid1.Align := alRight;

  StringGrid1.FixedCols := 0;

  StringGrid1.ColCount := 3;

  StringGrid1.ColWidths[0] := 25;

  StringGrid1.ColWidths[1] := 25;

  StringGrid1.ColWidths[2] := 80;

  StringGrid1.DefaultRowHeight := 20;



  StringGrid1.Cells[0,0] := 'X';

  StringGrid1.Cells[1,0] := 'Y';

  StringGrid1.Cells[2,0] := '点类型';

end;



procedure TForm1.FormPaint(Sender: TObject);

var

  g: TGPGraphics;

  p: TGPPen;

  path: TGPGraphicsPath;

  PathData: TPathData;

  Points: PGPPointF;

  Types: PByte;

  TypeStr: string;

  i: Integer;

begin

  g := TGPGraphics.Create(Canvas.Handle);

  p := TGPPen.Create(aclRed);

  path := TGPGraphicsPath.Create;



  path.StartFigure;

  path.AddRectangle(MakeRect(30,20,90,40));

  path.AddEllipse(MakeRect(30,80,90,180));

  path.CloseFigure;



  g.DrawPath(p, path);



  PathData := TPathData.Create;

  path.GetPathData(PathData);

  Points := PathData.Points;

  Types := PathData.Types;



  StringGrid1.RowCount := PathData.Count + 1;



  for i := 0 to PathData.Count - 1 do

  begin

    case Types^ of

      $00 : TypeStr := '路径起始点';

      $01 : TypeStr := '直线点';

      $03 : TypeStr := '贝塞尔线点';

      $07 : TypeStr := '遮盖点';

      $10 : TypeStr := '虚线点';

      $20 : TypeStr := '路径标记';

      $80 : TypeStr := '子路径结束点';

    end;

    StringGrid1.Cells[0, i+1] := IntToStr(Trunc(Points.X));

    StringGrid1.Cells[1, i+1] := IntToStr(Trunc(Points.Y));

    StringGrid1.Cells[2, i+1] := TypeStr;

    Inc(Points);

    Inc(Types);

  end;



  PathData.Free;

  path.Free;

  p.Free;

  g.Free;

end;



procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;

  var CanSelect: Boolean);

var

  x,y: Integer;

begin

  x := StrToIntDef(StringGrid1.Cells[0,ARow], 0);

  y := StrToIntDef(StringGrid1.Cells[1,ARow], 0);

  Repaint;

  Canvas.Brush.Color := clBlue;

  Canvas.FillRect(Bounds(x-3,y-3,6,6));

  Text := Format('%d,%d',[x,y]);

end;



end.


 
   
窗体文件:

object Form1: TForm1

  Left = 0

  Top = 0

  Caption = 'Form1'

  ClientHeight = 276

  ClientWidth = 303

  Color = clBtnFace

  Font.Charset = DEFAULT_CHARSET

  Font.Color = clWindowText

  Font.Height = -11

  Font.Name = 'Tahoma'

  Font.Style = []

  OldCreateOrder = False

  Position = poDesktopCenter

  OnCreate = FormCreate

  OnPaint = FormPaint

  PixelsPerInch = 96

  TextHeight = 13

  object StringGrid1: TStringGrid

    Left = 88

    Top = 40

    Width = 154

    Height = 120

    TabOrder = 0

    OnSelectCell = StringGrid1SelectCell

  end

end


 
   
路径中的点类型枚举:

PathPointType = (

  PathPointTypeStart        = $00, {路径起始点}

  PathPointTypeLine         = $01, {直线点}

  PathPointTypeBezier       = $03, {默认贝塞尔线点}

  PathPointTypePathTypeMask = $07, {遮盖点}

  PathPointTypeDashMode     = $10, {虚线点}

  PathPointTypePathMarker   = $20, {路径标记}

  PathPointTypeCloseSubpath = $80, {子路径结束点}



  PathPointTypeBezier3      = $03  {立体贝塞尔线点}

);

TPathPointType = PathPointType;


 
   

你可能感兴趣的:(Path)