通過路徑的 Warp 方法可以讓路徑在一個范圍內(四個點決定的范圍)變換;
第一個參數可以是 3 個點或 4 個點的數組, 如果是 3 個的數組, 那麼第 4 個點將自動跟 隨一個平行四邊形;
第二個參數用來指定點數組的個數, 本例就是通過這個參數控制了點的個數;
第三個參數是一個矩形, 這個矩形應該是路徑的外接矩形, 之後的參數都是可選的;
第四個參數也是一個矩陣變換, 因由專門的 例子 , 這裡沒有嘗試;
第五個參數是 TWarpMode(WarpModePerspective, WarpModeBilinear) , 默認前者;
第六個參數可以指定 Flatten 變換, 前面有 例子 , 這裡也沒有嘗試.
本例效果圖:
代碼文件:unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls;
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses GDIPOBJ, GDIPAPI;
var
ptfs: array[0..3] of TGPPointF;
ptCount: Integer = 4;
pti: Integer;
R: TRect;
flag: Boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
CheckBox1.Caption := '只用 3 個點控制';
R := Rect(20, 20, ClientWidth-20, ClientHeight - 40);
ptfs[0] := MakePoint(R.Left*1.0, R.Top);
ptfs[1] := MakePoint(R.Right*1.0, R.Top);
ptfs[2] := MakePoint(R.Left*1.0, R.Bottom);
ptfs[3] := MakePoint(R.Right*1.0, R.Bottom);
end;
procedure TForm1.FormPaint(Sender: TObject);
var
g: TGPGraphics;
p: TGPPen;
b: TGPBrush;
path: TGPGraphicsPath;
fontFamily: TGPFontFamily;
StringFormat: TGPStringFormat;
rectf: TGPRectF;
i: Integer;
begin
g := TGPGraphics.Create(Canvas.Handle);
p := TGPPen.Create(aclRed, 1);
b := TGPHatchBrush.Create(HatchStyleShingle, aclDarkCyan);
path := TGPGraphicsPath.Create;
path.AddEllipse(MakeRect(R));
fontFamily := TGPFontFamily.Create('Arial Black');
StringFormat := TGPStringFormat.Create;
StringFormat.SetAlignment(StringAlignmentCenter);
StringFormat.SetLineAlignment(StringAlignmentCenter);
path.GetBounds(rectf);
path.AddString('Delphi', -1, fontFamily, FontStyleRegular, 48, rectf, StringFormat);
path.Warp(PGPPointF(@ptfs), Length(ptfs), rectf);
g.FillPath(b, path);
for i := 0 to ptCount - 1 do
g.DrawRectangle(p, MakeRect(ptfs[i].X-3, ptfs[i].Y-3, 6, 6));
StringFormat.Free;
fontFamily.Free;
path.Free;
b.Free;
p.Free;
g.Free;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
ptCount := 4;
if CheckBox1.Checked then ptCount := 3;
Repaint;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i: Integer;
begin
for i := 0 to 3 do
if PtInRect(Bounds(Trunc(ptfs[i].X-3), Trunc(ptfs[i].Y-3), 6, 6), Point(X, Y)) then
begin
pti := i;
flag := True;
Exit;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if flag then
begin
ptfs[pti].X := X;
ptfs[pti].Y := Y;
Repaint;
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
flag := False;
end;
end.