AsphyreBmp.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:18k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit AsphyreBmp;
  2. //---------------------------------------------------------------------------
  3. // AsphyreBmp.pas                                       Modified: 19-Jan-2007
  4. // Asphyre extensions to TBitmap class                            Version 3.0
  5. //---------------------------------------------------------------------------
  6. // The contents of this file are subject to the Mozilla Public License
  7. // Version 1.1 (the "License"); you may not use this file except in
  8. // compliance with the License. You may obtain a copy of the License at
  9. // http://www.mozilla.org/MPL/
  10. //
  11. // Software distributed under the License is distributed on an "AS IS"
  12. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  13. // License for the specific language governing rights and limitations
  14. // under the License.
  15. //---------------------------------------------------------------------------
  16. interface
  17. //---------------------------------------------------------------------------
  18. uses
  19.  Windows, Types, Classes, Graphics, CommonDef, Vectors2, AsphyreTypes,
  20.  ImageFx;
  21. //---------------------------------------------------------------------------
  22. type
  23.  TBitmapEx = class(TBitmap)
  24.  private
  25.   function GetPixels(x, y: Integer): Cardinal;
  26.   procedure SetPixels(x, y: Integer; const Value: Cardinal);
  27.   function GetGrayshade(X, Y: Integer): Real;
  28.   function ModulateAlpha(Color: Cardinal; Beta: Real): Cardinal;
  29.  public
  30.   property Pixels[x, y: Integer]: Cardinal read GetPixels write SetPixels; default;
  31.   property Grayshade[X, Y: Integer]: Real read GetGrayshade;
  32.   procedure PutPixel(x, y: Integer; Color: Cardinal);
  33.   function GetPixel(x, y: Integer): Cardinal;
  34.   procedure Clear(Color: Cardinal);
  35.   procedure Line(const Src, Dest: TPoint; Color1, Color2: Cardinal); overload;
  36.   procedure Line(x1, y1, x2, y2: Integer; Color1, Color2: Cardinal); overload;
  37.   procedure WuLine(Src, Dest: TPoint2; Color0, Color1: Cardinal); overload;
  38.   procedure WuLine(x1, y1, x2, y2: Single; Color0, Color1: Cardinal); overload;
  39.   procedure FillRect(const Rect: TRect; const Colors: TColor4); overload;
  40.   procedure FrameRect(const Rect: TRect; Color: TColor);
  41.   procedure Triangle(x0, y0, x1, y1, x2, y2: Integer; Color: Cardinal);
  42.   procedure SetAlphaMask(MaskedColor: Cardinal; Tolerance: Integer);
  43.   procedure SetAlpha(Alpha: Integer);
  44.   procedure AssignAttrib(Source: TBitmap);
  45.   procedure CopyFrom(Source: TBitmap);
  46.   procedure SaveTo(Dest: TBitmap);
  47.   procedure Shrink2x(Dest: TBitmap);
  48.   constructor Create(); override;
  49.  end;
  50. //---------------------------------------------------------------------------
  51.  TBitmaps = class
  52.  private
  53.   Data: array of TBitmapEx;
  54.   function GetCount(): Integer;
  55.   procedure SetCount(const Value: Integer);
  56.   function GetItem(Num: Integer): TBitmapEx;
  57.   procedure SetItem(Num: Integer; const Value: TBitmapEx);
  58.  public
  59.   property Items[Num: Integer]: TBitmapEx read GetItem write SetItem; default;
  60.   property Count: Integer read GetCount write SetCount;
  61.   function Add(): Integer;
  62.   procedure Remove(Num: Integer);
  63.   procedure RemoveAll();
  64.   function Find(Image: TBitmapEx): Integer;
  65.   constructor Create();
  66.   destructor Destroy(); override;
  67.  end;
  68.  //---------------------------------------------------------------------------
  69. implementation
  70. //---------------------------------------------------------------------------
  71. type
  72.  TGradientRect = record
  73.   UpperLeft : Longword;
  74.   LowerRight: Longword;
  75.  end;
  76. //---------------------------------------------------------------------------
  77.  TGradientTriangle = record
  78.   Vertex1: Longword;
  79.   Vertex2: Longword;
  80.   Vertex3: Longword;
  81.  end;
  82. //---------------------------------------------------------------------------
  83.  PTriVertex = ^TTriVertex;
  84.  TTriVertex = record
  85.   x: Integer;
  86.   y: Integer;
  87.   Red  : Word;
  88.   Green: Word;
  89.   Blue : Word;
  90.   Alpha: Word;
  91.  end;
  92. //---------------------------------------------------------------------------
  93.  PVertex4 = ^TVertex4;
  94.  TVertex4 = array[0..3] of TTriVertex;
  95.  TVertex3 = array[0..2] of TTriVertex;
  96. //---------------------------------------------------------------------------
  97. function GradientFill(Handle: THandle; pVertex: Pointer; dwNumVertex: Longword;
  98.  pMesh: Pointer; dwNumMesh: Longword; dwMode: Longword): Boolean;
  99.  stdcall; external 'Msimg32.dll';
  100. //---------------------------------------------------------------------------
  101. function TriVertex(Point: TPoint; Color: Cardinal): TTriVertex;
  102. begin
  103.  Result.x    := Point.X;
  104.  Result.y    := Point.Y;
  105.  Result.Red  := (Color and $FF) shl 8;
  106.  Result.Green:= Color and $FF00;
  107.  Result.Blue := (Color shr 8) and $FF00;
  108.  Result.Alpha:= (Color shr 16) and $FF00;
  109. end;
  110. //---------------------------------------------------------------------------
  111. procedure Rect2Vertex(Vertex: PVertex4; Rect: TRect);
  112. begin
  113.  Vertex[0].x:= Rect.Left;
  114.  Vertex[0].y:= Rect.Top;
  115.  Vertex[1].x:= Rect.Right;
  116.  Vertex[1].y:= Rect.Top;
  117.  Vertex[2].x:= Rect.Right;
  118.  Vertex[2].y:= Rect.Bottom;
  119.  Vertex[3].x:= Rect.Left;
  120.  Vertex[3].y:= Rect.Bottom;
  121. end;
  122. //---------------------------------------------------------------------------
  123. procedure Color2Vertex(Vertex: PTriVertex; Color: Cardinal);
  124. begin
  125.  Vertex.Red  := (Color and $FF) shl 8;
  126.  Vertex.Green:= Color and $FF00;
  127.  Vertex.Blue := (Color shr 8) and $FF00;
  128.  Vertex.Alpha:= (Color shr 16) and $FF00;
  129. end;
  130. //---------------------------------------------------------------------------
  131. constructor TBitmapEx.Create();
  132. begin
  133.  inherited;
  134.  PixelFormat:= pf32bit;
  135. end;
  136. //---------------------------------------------------------------------------
  137. function TBitmapEx.GetPixels(x, y: Integer): Cardinal;
  138. var
  139.  px: PCardinal;
  140. begin
  141.  px:= Pointer(Integer(Scanline[y]) + (x shl 2));
  142.  Result:= px^;
  143. end;
  144. //---------------------------------------------------------------------------
  145. procedure TBitmapEx.SetPixels(X, Y: Integer; const Value: Cardinal);
  146. var
  147.  px: PCardinal;
  148. begin
  149.  px:= Pointer(Integer(Scanline[y]) + (x shl 2));
  150.  px^:= Value;
  151. end;
  152. //---------------------------------------------------------------------------
  153. procedure TBitmapEx.PutPixel(x, y: Integer; Color: Cardinal);
  154. var
  155.  px: PCardinal;
  156. begin
  157.  if (x < 0)or(y < 0)or(x >= Width)or(y >= Height) then Exit;
  158.  px:= Pointer(Integer(Scanline[y]) + (x shl 2));
  159.  px^:= BlendPixels(DisplaceRB(Color) or $FF000000, px^, Color shr 24);
  160. end;
  161. //---------------------------------------------------------------------------
  162. function TBitmapEx.GetPixel(x, y: Integer): Cardinal;
  163. begin
  164.  if (x >= 0)and(y >= 0)and(x < Width)and(y < Height) then
  165.   Result:= GetPixels(x, y) else Result:= 0;
  166. end;
  167. //---------------------------------------------------------------------------
  168. function TBitmapEx.GetGrayshade(x, y: Integer): Real;
  169. var
  170.  Color: Cardinal;
  171. begin
  172.  Color:= GetPixel(x, y);
  173.  Result:= ((Color and $FF) * 0.3 + ((Color shr 8) and $FF) * 0.59 +
  174.   ((Color shr 16) and $FF) * 0.11) / 255.0;
  175. end;
  176. //---------------------------------------------------------------------------
  177. procedure TBitmapEx.Clear(Color: Cardinal);
  178. var
  179.  j, i: Integer;
  180.  px: PCardinal;
  181. begin
  182.  Color:= DisplaceRB(Color);
  183.  for j:= 0 to Height - 1 do
  184.   begin
  185.    px:= Scanline[j];
  186.    for i:= 0 to Width - 1 do
  187.     begin
  188.      px^:= Color;
  189.      Inc(px);
  190.     end;
  191.   end;
  192. end;
  193. //---------------------------------------------------------------------------
  194. procedure TBitmapEx.Line(const Src, Dest: TPoint; Color1, Color2: Cardinal);
  195. var
  196.  xDelta, yDelta, vFixed, vDelta, i, vPos, Alpha, AlphaVel: Integer;
  197. begin
  198.  xDelta:= Abs(Dest.X - Src.X);
  199.  yDelta:= Abs(Dest.Y - Src.Y);
  200.  if (xDelta < 1)and(yDelta < 1) then
  201.   begin
  202.    PutPixel(Src.X, Src.Y, BlendPixels(Color2, Color1, 128));
  203.    Exit;
  204.   end;
  205.  if (yDelta > xDelta) then
  206.   begin
  207.    vFixed:= Src.X shl 16;
  208.    vDelta:= ((Dest.X - Src.X) shl 16) div yDelta;
  209.    vPos:= Src.Y;
  210.    Alpha:= 0;
  211.    AlphaVel:= $FFFF div yDelta;
  212.    if (Dest.Y < vPos) then
  213.     begin
  214.      vPos:= Dest.Y;
  215.      vFixed:= Dest.X shl 16;
  216.      vDelta:= -vDelta;
  217.      Alpha:= $FFFF;
  218.      AlphaVel:= -AlphaVel;
  219.      Inc(vPos);
  220.      Inc(vFixed, vDelta);
  221.      Inc(Alpha, AlphaVel);
  222.     end;
  223.    Dec(yDelta);
  224.    for i:= 0 to yDelta do
  225.     begin
  226.      PutPixel(vFixed shr 16, vPos + i, BlendPixels(Color2, Color1, Alpha shr 8));
  227.      Inc(vFixed, vDelta);
  228.      Inc(Alpha, AlphaVel);
  229.     end;
  230.   end else
  231.   begin
  232.    vFixed:= Src.Y shl 16;
  233.    vDelta:= ((Dest.Y - Src.Y) shl 16) div xDelta;
  234.    vPos:= Src.X;
  235.    Alpha:= 0;
  236.    AlphaVel:= $FFFF div xDelta;
  237.    if (Dest.X < vPos) then
  238.     begin
  239.      vPos:= Dest.X;
  240.      vFixed:= Dest.Y shl 16;
  241.      vDelta:= -vDelta;
  242.      Alpha:= $FFFF;
  243.      AlphaVel:= -AlphaVel;
  244.      Inc(vPos);
  245.      Inc(vFixed, vDelta);
  246.      Inc(Alpha, AlphaVel);
  247.     end;
  248.    Dec(xDelta);
  249.    for i:= 0 to xDelta do
  250.     begin
  251.      PutPixel(vPos + i, vFixed shr 16, BlendPixels(Color2, Color1, Alpha shr 8));
  252.      Inc(vFixed, vDelta);
  253.      Inc(Alpha, AlphaVel);
  254.     end;
  255.   end;
  256. end;
  257. //---------------------------------------------------------------------------
  258. procedure TBitmapEx.Line(x1, y1, x2, y2: Integer; Color1, Color2: Cardinal);
  259. begin
  260.  Line(Point(x1, y1), Point(x2, y2), Color1, Color2);
  261. end;
  262. //---------------------------------------------------------------------------
  263. function TBitmapEx.ModulateAlpha(Color: Cardinal; Beta: Real): Cardinal;
  264. begin
  265.  Result:= (Color and $FFFFFF) or (Round((Color shr 24) * Beta) shl 24);
  266. end;
  267. //---------------------------------------------------------------------------
  268. procedure TBitmapEx.WuLine(Src, Dest: TPoint2; Color0, Color1: Cardinal);
  269. const
  270.  Epsilon = 0.00001; // treshold to consider the line is straight
  271. var
  272.  DeltaX, DeltaY, Grad, xEnd, yEnd, xPos, yPos: Real;
  273.  Alpha, AlphaInc: Real;
  274.  Aux, Point0, Point1: TPoint2;
  275.  Index: Integer;
  276.  MyColor: Cardinal;
  277. begin
  278.  DeltaX:= Dest.x - Src.x;
  279.  DeltaY:= Dest.y - Src.y;
  280.  if (Abs(DeltaX) > Abs(DeltaY)) then
  281.   begin // horizontal line
  282.    if (DeltaX < 0.0) then
  283.     begin
  284.      Aux := Src;
  285.      Src := Dest;
  286.      Dest:= Aux;
  287.      DeltaX:= -DeltaX;
  288.      DeltaY:= -DeltaY;
  289.     end;
  290.    Grad:= DeltaY / DeltaX;
  291.    // 1st point
  292.    xEnd:= Int(Src.x + 0.5);
  293.    yEnd:= Src.y + (xEnd - Src.x) * Grad;
  294.    yPos:= yEnd + Grad;
  295.    Point0:= Point2(Int(xEnd), Int(yEnd));
  296.    // 2nd point
  297.    xEnd:= Int(Dest.x + 0.5);
  298.    yEnd:= Dest.y + (xEnd - Dest.x) * Grad;
  299.    Point1:= Point2(Int(xEnd), Int(yEnd));
  300.    Alpha:= 0.0;
  301.    AlphaInc:= 255.0 / Abs(Int(Point1.x) - Int(Point0.x));
  302.    for Index:= Trunc(Point0.x) to Trunc(Point1.x) do
  303.     begin
  304.      MyColor:= BlendPixels(Color1, Color0, Round(Alpha));
  305.      PutPixel(Index, Trunc(yPos), ModulateAlpha(MyColor, 1.0 - Frac(yPos)));
  306.      PutPixel(Index, Trunc(yPos) + 1, ModulateAlpha(MyColor, Frac(yPos)));
  307.      yPos:= yPos + Grad;
  308.      Alpha:= Alpha + AlphaInc;
  309.     end;
  310.   end else
  311.   begin // vertical line
  312.    if (DeltaY < 0.0) then
  313.     begin
  314.      Aux := Src;
  315.      Src := Dest;
  316.      Dest:= Aux;
  317.      DeltaX:= -DeltaX;
  318.      DeltaY:= -DeltaY;
  319.     end;
  320.    Grad:= DeltaX / DeltaY;
  321.    // 1st point
  322.    yEnd:= Int(Src.y + 0.5);
  323.    xEnd:= Src.x + (yEnd - Src.y) * Grad;
  324.    xPos:= xEnd + Grad;
  325.    Point0:= Point2(Int(xEnd), Int(yEnd));
  326.    // 2nd point
  327.    yEnd:= Int(Dest.y + 0.5);
  328.    xEnd:= Dest.x + (yEnd - Dest.y) * Grad;
  329.    Point1:= Point2(Int(xEnd), Int(yEnd));
  330.    Alpha:= 0.0;
  331.    AlphaInc:= 255.0 / Abs(Int(Point1.y) - Int(Point0.y));
  332.    for Index:= Trunc(Point0.y) to Trunc(Point1.y) do
  333.     begin
  334.      MyColor:= BlendPixels(Color1, Color0, Round(Alpha));
  335.      PutPixel(Trunc(xPos), Index, ModulateAlpha(MyColor, 1.0 - Frac(xPos)));
  336.      PutPixel(Trunc(xPos) + 1, Index, ModulateAlpha(MyColor, Frac(xPos)));
  337.      xPos := xPos + Grad;
  338.      Alpha:= Alpha + AlphaInc;
  339.     end;
  340.   end;
  341. end;
  342. //---------------------------------------------------------------------------
  343. procedure TBitmapEx.WuLine(x1, y1, x2, y2: Single; Color0, Color1: Cardinal);
  344. begin
  345.  WuLine(Point2(x1, y1), Point2(x2, y2), Color0, Color1);
  346. end;
  347. //---------------------------------------------------------------------------
  348. procedure TBitmapEx.FillRect(const Rect: TRect; const Colors: TColor4);
  349. var
  350.  Vertex4: TVertex4;
  351.  Mesh: array[0..1] of TGradientTriangle;
  352. begin
  353.  Rect2Vertex(@Vertex4, Rect);
  354.  Color2Vertex(@Vertex4[0], Colors[0]);
  355.  Color2Vertex(@Vertex4[1], Colors[1]);
  356.  Color2Vertex(@Vertex4[2], Colors[2]);
  357.  Color2Vertex(@Vertex4[3], Colors[3]);
  358.  Mesh[0].Vertex1:= 0;
  359.  Mesh[0].Vertex2:= 1;
  360.  Mesh[0].Vertex3:= 2;
  361.  Mesh[1].Vertex1:= 0;
  362.  Mesh[1].Vertex2:= 2;
  363.  Mesh[1].Vertex3:= 3;
  364.  GradientFill(Canvas.Handle, @Vertex4, 4, @Mesh, 2, GRADIENT_FILL_TRIANGLE);
  365. end;
  366. //---------------------------------------------------------------------------
  367. procedure TBitmapEx.Triangle(x0, y0, x1, y1, x2, y2: Integer; Color: Cardinal);
  368. var
  369.  Vertex3: TVertex3;
  370.  Mesh: TGradientTriangle;
  371. begin
  372.  Vertex3[0].x:= x0;
  373.  Vertex3[0].y:= y0;
  374.  Vertex3[1].x:= x1;
  375.  Vertex3[1].y:= y1;
  376.  Vertex3[2].x:= x2;
  377.  Vertex3[2].y:= y2;
  378.  Color2Vertex(@Vertex3[0], Color);
  379.  Color2Vertex(@Vertex3[1], Color);
  380.  Color2Vertex(@Vertex3[2], Color);
  381.  Mesh.Vertex1:= 0;
  382.  Mesh.Vertex2:= 1;
  383.  Mesh.Vertex3:= 2;
  384.  GradientFill(Canvas.Handle, @Vertex3, 3, @Mesh, 1, GRADIENT_FILL_TRIANGLE);
  385. end;
  386. //---------------------------------------------------------------------------
  387. procedure TBitmapEx.FrameRect(const Rect: TRect; Color: TColor);
  388. begin
  389.  with Canvas do
  390.   begin
  391.    Brush.Style:= bsSolid;
  392.    Brush.Color:= Color;
  393.    FrameRect(Rect);
  394.   end;
  395. end;
  396. //---------------------------------------------------------------------------
  397. procedure TBitmapEx.SetAlpha(Alpha: Integer);
  398. var
  399.  Index   : Integer;
  400.  AlphaCol: Longword;
  401.  px      : PLongword;
  402.  Count   : Integer;
  403. begin
  404.  AlphaCol:= (Cardinal(Alpha) and $FF) shl 24;
  405.  for Index:= 0 to Height - 1 do
  406.   begin
  407.    px:= Scanline[Index];
  408.    for Count:= 0 to Width - 1 do
  409.     begin
  410.      px^:= (px^ and $FFFFFF) or AlphaCol;
  411.      Inc(px);
  412.     end;
  413.   end;  
  414. end;
  415. //---------------------------------------------------------------------------
  416. procedure TBitmapEx.SetAlphaMask(MaskedColor: Cardinal; Tolerance: Integer);
  417. var
  418.  Index: Integer;
  419.  Aux  : Pointer;
  420. begin
  421.  for Index:= 0 to Height - 1 do
  422.   begin
  423.    Aux:= Scanline[Index];
  424.    LineConvMasked(Aux, Aux, Width, Tolerance, DisplaceRB(MaskedColor));
  425.   end;
  426. end;
  427. //---------------------------------------------------------------------------
  428. procedure TBitmapEx.AssignAttrib(Source: TBitmap);
  429. begin
  430.  SetSize(Source.Width, Source.Height);
  431. end;
  432. //---------------------------------------------------------------------------
  433. procedure TBitmapEx.CopyFrom(Source: TBitmap);
  434. var
  435.  i, MyPitch: Integer;
  436. begin
  437.  AssignAttrib(Source);
  438.  MyPitch:= Width * 4;
  439.  for i:= 0 to Height - 1 do
  440.   Move(Source.Scanline[i]^, Scanline[i]^, MyPitch);
  441. end;
  442. //---------------------------------------------------------------------------
  443. procedure TBitmapEx.SaveTo(Dest: TBitmap);
  444. var
  445.  i, MyPitch: Integer;
  446. begin
  447.  Dest.Width := Width;
  448.  Dest.Height:= Height;
  449.  Dest.PixelFormat:= PixelFormat;
  450.  MyPitch:= Width * 4;
  451.  for i:= 0 to Height - 1 do
  452.   Move(Scanline[i]^, Dest.Scanline[i]^, MyPitch);
  453. end;
  454. //---------------------------------------------------------------------------
  455. procedure TBitmapEx.Shrink2x(Dest: TBitmap);
  456. var
  457.  j: Integer;
  458. begin
  459.  if (Dest.PixelFormat <> pf32bit) then Dest.PixelFormat:= pf32bit;
  460.  if (Dest.Width <> Width div 2)or(Dest.Height <> Height div 2) then
  461.   begin
  462.    Dest.Width := Width div 2;
  463.    Dest.Height:= Height div 2;
  464.   end;
  465.  for j:= 0 to Dest.Height - 1 do
  466.   ShrinkLine2x(ScanLine[j * 2], ScanLine[(j * 2) + 1], Dest.ScanLine[j], Dest.Width);
  467. end;
  468. //---------------------------------------------------------------------------
  469. constructor TBitmaps.Create();
  470. begin
  471.  inherited;
  472.  SetLength(Data, 0);
  473. end;
  474. //---------------------------------------------------------------------------
  475. destructor TBitmaps.Destroy;
  476. begin
  477.  RemoveAll();
  478.  inherited;
  479. end;
  480. //---------------------------------------------------------------------------
  481. function TBitmaps.GetCount(): Integer;
  482. begin
  483.  Result:= Length(Data);
  484. end;
  485. //---------------------------------------------------------------------------
  486. procedure TBitmaps.SetCount(const Value: Integer);
  487. begin
  488.  while (Length(Data) < Value) do Add();
  489.  while (Length(Data) > Value)and(Length(Data) > 1) do Remove(0);
  490. end;
  491. //---------------------------------------------------------------------------
  492. function TBitmaps.GetItem(Num: Integer): TBitmapEx;
  493. begin
  494.  if (Num >= 0)and(Num < Length(Data)) then
  495.   Result:= Data[Num] else Result:= nil;
  496. end;
  497. //---------------------------------------------------------------------------
  498. procedure TBitmaps.SetItem(Num: Integer; const Value: TBitmapEx);
  499. begin
  500.  if (Num >= 0)and(Num < Length(Data)) then
  501.   Data[Num].CopyFrom(Value);
  502. end;
  503. //---------------------------------------------------------------------------
  504. function TBitmaps.Add(): Integer;
  505. var
  506.  Index: Integer;
  507. begin
  508.  Index:= Length(Data);
  509.  SetLength(Data, Index + 1);
  510.  Data[Index]:= TBitmapEx.Create();
  511.  Result:= Index;
  512. end;
  513. //---------------------------------------------------------------------------
  514. function TBitmaps.Find(Image: TBitmapEx): Integer;
  515. var
  516.  i: Integer;
  517. begin
  518.  Result:= -1;
  519.  for i:= 0 to Length(Data) - 1 do
  520.   if (Data[i] = Image) then
  521.    begin
  522.     Result:= i;
  523.     Break;
  524.    end; 
  525. end;
  526. //---------------------------------------------------------------------------
  527. procedure TBitmaps.Remove(Num: Integer);
  528. var
  529.  i: Integer;
  530. begin
  531.  if (Num < 0)or(Num >= Length(Data)) then Exit;
  532.  Data[Num].Free();
  533.  for i:= Num to Length(Data) - 2 do
  534.   Data[i]:= Data[i + 1];
  535.  SetLength(Data, Length(Data) - 1); 
  536. end;
  537. //---------------------------------------------------------------------------
  538. procedure TBitmaps.RemoveAll();
  539. var
  540.  i: Integer;
  541. begin
  542.  for i:= 0 to Length(Data) - 1 do
  543.   if (Data[i] <> nil) then
  544.    begin
  545.     Data[i].Free();
  546.     Data[i]:= nil;
  547.    end;
  548.  SetLength(Data, 0);
  549. end;
  550. //---------------------------------------------------------------------------
  551. end.