1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| Unit uCanvasHelper;
{$mode objfpc}{$H+}
{$modeswitch advancedrecords}
{$modeswitch typehelpers}
Interface
Uses
LCLIntf, Classes, SysUtils, Graphics, FPImage;
Type TCanvasHelper = Class helper for TCanvas
public
Procedure FloodFill( x_, y_: Integer; FillColor: TColor); overload;
end;
implementation
{$R *.lfm}
uses LCLIntf, FPImage;
{ TFBase }
Procedure TCanvasHelper.FloodFill(x_, y_: Integer; FillColor: TColor);// FillStyle: TFillStyle);
Var
Stack: Array Of TPoint;
Stackp: Integer;
x, y: Integer;
FillColor2, ReplaceColor: TFPColor;
Procedure PutInStack(X, Y: Integer);
Begin
inc(stackp);
If Stackp > high(stack) Then Begin
// Blockweise Vor Allokierung
SetLength(Stack, high(Stack) + 1025);
End;
Stack[stackp] := Point(X, Y);
End;
Procedure GetFromStack(Var X, Y: Integer);
Begin
X := Stack[stackp].X;
Y := Stack[stackp].Y;
dec(stackp);
End;
Function ColorInRange(c1, c2: TFPColor): Boolean;
Begin
result := (c1.red = c2.red) And (c1.green = c2.green) And (c1.blue = c2.blue);
End;
Begin
X := X_;
Y := Y_;
If (X >= Self.Width) Or (Y >= Self.Height) Or (x < 0) Or (y < 0) Then Exit;
FillColor2.red := (FillColor And $000000FF) Shl 8;
FillColor2.green := (FillColor And $0000FF00);
FillColor2.blue := (FillColor And $00FF0000) Shr 8;
ReplaceColor := Self.Colors[X, Y];
If (ReplaceColor.red = FillColor2.red) And (ReplaceColor.green = FillColor2.green) And (ReplaceColor.blue = FillColor2.blue) Then Exit;
stackp := -1;
PutInStack(X, Y);
While stackp >= 0 Do Begin
GetFromStack(X, Y);
While (X > 0) And ColorInRange(Self.Colors[X - 1, Y], ReplaceColor) Do Dec(X);
While (X < Self.Width) And ColorInRange(Self.Colors[X, Y], ReplaceColor) Do
Begin
If Y > 0 Then
If ColorInRange(Self.Colors[X, Y - 1], ReplaceColor) Then PutInStack(X, Y - 1);
If Y + 1 < Self.Height Then
If ColorInRange(Self.Colors[X, Y + 1], ReplaceColor) Then PutInStack(X, Y + 1);
Self.Colors[X, Y] := FillColor2;
Inc(X);
End;
End;
SetLength(Stack, 0);
End;
End. |