Skip to content

Commit

Permalink
TSimbaImage.DrawTPA implement (fake) alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
ollydev committed Nov 21, 2023
1 parent 864ce8f commit d085c4b
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 66 deletions.
2 changes: 1 addition & 1 deletion Source/editor/simba.editor_autocomplete.pas
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
interface

uses
Classes, SysUtils, Graphics, StdCtrls, Controls, Forms, LCLType,
Classes, SysUtils, Graphics, Controls, Forms, LCLType,
SynEdit, SynEditTypes, SynEditKeyCmds, SynEditHighlighter,
SynCompletion_Simba,
simba.mufasatypes, simba.settings,
Expand Down
93 changes: 47 additions & 46 deletions Source/image/simba.image.pas
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ TSimbaImage = class(TSimbaBaseClass)

FTextDrawer: TSimbaTextDrawer;

procedure _DrawTPA(const TPA: TPointArray; Color: TColor);
procedure _DrawTPAAlpha(const TPA: TPointArray; Color: TColor; Alpha: Byte);

procedure _DrawBoxFilled(Box: TBox; Color: TColor);
procedure _DrawBoxFilledAlpha(Box: TBox; Color: TColor; Alpha: Byte);

Expand Down Expand Up @@ -126,8 +129,8 @@ TSimbaImage = class(TSimbaBaseClass)
procedure SetExternalData(AData: PColorBGRA; AWidth, AHeight: Integer);
procedure ResetExternalData;

procedure DrawATPA(ATPA: T2DPointArray; Color: TColor = -1);
procedure DrawTPA(Points: TPointArray; Color: TColor);
procedure DrawATPA(const ATPA: T2DPointArray; Color: TColor = -1; Alpha: Byte = 0);
procedure DrawTPA(const TPA: TPointArray; Color: TColor; Alpha: Byte = 0);

// Line
procedure DrawCrosshairs(ACenter: TPoint; Size: Integer; Color: TColor);
Expand Down Expand Up @@ -251,17 +254,6 @@ implementation
simba.image_lazbridge, simba.image_integral, simba.image_gaussblur,
simba.image_bitmaparealoader, simba.image_utils;

function GetDistinctColor(const Color, Index: Integer): Integer; inline;
const
// Distinct colors - https://sashamaps.net/docs/resources/20-colors/
DISTINCT_COLORS: TIntegerArray = ($4B19E6, $4BB43C, $19E1FF, $D86343, $3182F5, $B41E91, $F4D442, $E632F0, $45EFBF, $D4BEFA, $909946, $FFBEDC, $24639A, $C8FAFF, $000080, $C3FFAA, $008080, $B1D8FF, $750000, $A9A9A9);
begin
if (Color > -1) then
Result := Color
else
Result := DISTINCT_COLORS[Index mod Length(DISTINCT_COLORS)];
end;

function TSimbaImage.SaveToFile(FileName: String; OverwriteIfExists: Boolean): Boolean;
var
Stream: TFileStream;
Expand Down Expand Up @@ -752,31 +744,20 @@ procedure TSimbaImage.LoadFromImage(Image: TSimbaImage);
Move(Image.FData^, FData^, FWidth * FHeight * SizeOf(TColorBGRA));
end;

procedure TSimbaImage.DrawATPA(ATPA: T2DPointArray; Color: TColor);
var
I: Integer;
procedure TSimbaImage.DrawTPA(const TPA: TPointArray; Color: TColor; Alpha: Byte);
begin
for I := 0 to High(ATPA) do
DrawTPA(ATPA[I], GetDistinctColor(Color, I));
if (Alpha = 0) then
_DrawTPA(TPA, Color)
else
_DrawTPAAlpha(TPA, Color, Alpha);
end;

procedure TSimbaImage.DrawTPA(Points: TPointArray; Color: TColor);
procedure TSimbaImage.DrawATPA(const ATPA: T2DPointArray; Color: TColor; Alpha: Byte);
var
I: Integer;
P: TPoint;
BGR: TColorBGRA;
begin
if (Length(Points) = 0) then
Exit;

BGR := ColorToBGRA(Color);

for I := 0 to High(Points) do
begin
P := Points[I];
if (P.X >= 0) and (P.Y >= 0) and (P.X < FWidth) and (P.Y < FHeight) then
FData[P.Y * FWidth + P.X] := BGR;
end;
for I := 0 to High(ATPA) do
DrawTPA(ATPA[I], GetDistinctColor(Color, I), Alpha);
end;

procedure TSimbaImage.DrawCrosshairs(ACenter: TPoint; Size: Integer; Color: TColor);
Expand Down Expand Up @@ -1229,20 +1210,6 @@ procedure TSimbaImage.ReplaceColors(OldColors, NewColors: TColorArray);
end;
end;

function GetRotatedSize(W, H: Integer; Angle: Single): TBox;
var
B: TPointArray;
begin
B := [
TSimbaGeometry.RotatePoint(Point(0, H), Angle, W div 2, H div 2),
TSimbaGeometry.RotatePoint(Point(W, H), Angle, W div 2, H div 2),
TSimbaGeometry.RotatePoint(Point(W, 0), Angle, W div 2, H div 2),
TSimbaGeometry.RotatePoint(Point(0, 0), Angle, W div 2, H div 2)
];

Result := B.Bounds();
end;

function TSimbaImage.RotateNN(Radians: Single; Expand: Boolean): TSimbaImage;
var
CosAngle, SinAngle: Single;
Expand Down Expand Up @@ -2252,6 +2219,40 @@ procedure TSimbaImage.Pad(Amount: Integer);
end;
end;

procedure TSimbaImage._DrawTPA(const TPA: TPointArray; Color: TColor);
var
BGRA: TColorBGRA;
Point: TPoint;
begin
BGRA := Color.ToBGRA();

for Point in TPA do
if (Point.X >= 0) and (Point.Y >= 0) and (Point.X < FWidth) and (Point.Y < FHeight) then
FData[Point.Y * FWidth + Point.X] := BGRA;
end;

procedure TSimbaImage._DrawTPAAlpha(const TPA: TPointArray; Color: TColor; Alpha: Byte);
var
R,G,B,A: Byte;
Point: TPoint;
Ptr: PColorBGRA;
begin
R := (Color.R * (255 - Alpha + 1)) shr 8;
G := (Color.G * (255 - Alpha + 1)) shr 8;
B := (Color.B * (255 - Alpha + 1)) shr 8;
A := Alpha + 1;

for Point in TPA do
if (Point.X >= 0) and (Point.Y >= 0) and (Point.X < FWidth) and (Point.Y < FHeight) then
begin
Ptr := @FData[Point.Y * FWidth + Point.X];
Ptr^.R := R + Ptr^.R * A shr 8;
Ptr^.G := G + Ptr^.G * A shr 8;
Ptr^.B := B + Ptr^.B * A shr 8;
Ptr^.A := Alpha;
end;
end;

procedure TSimbaImage._DrawBoxFilled(Box: TBox; Color: TColor);
var
BGRA: TColorBGRA;
Expand Down
43 changes: 41 additions & 2 deletions Source/image/simba.image_utils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,49 @@ interface
Classes, SysUtils,
simba.mufasatypes;

procedure FillData(Data: PColorBGRA; count: SizeInt; value: TColorBGRA);
// https://sashamaps.net/docs/resources/20-colors/
const
DISTINCT_COLORS: TIntegerArray = ($4B19E6, $4BB43C, $19E1FF, $D86343, $3182F5, $B41E91, $F4D442, $E632F0, $45EFBF, $D4BEFA, $909946, $FFBEDC, $24639A, $C8FAFF, $000080, $C3FFAA, $008080, $B1D8FF, $750000, $A9A9A9);

function GetDistinctColor(const Index: Integer): Integer; overload; inline;
function GetDistinctColor(const Color, Index: Integer): Integer; overload; inline;

function GetRotatedSize(W, H: Integer; Angle: Single): TBox;

procedure FillData(const Data: PColorBGRA; const count: SizeInt; const value: TColorBGRA);

implementation

uses
simba.tpa, simba.geometry;

function GetDistinctColor(const Index: Integer): Integer;
begin
Result := DISTINCT_COLORS[Index mod Length(DISTINCT_COLORS)];
end;

function GetDistinctColor(const Color, Index: Integer): Integer;
begin
if (Color > -1) then
Result := Color
else
Result := DISTINCT_COLORS[Index mod Length(DISTINCT_COLORS)];
end;

function GetRotatedSize(W, H: Integer; Angle: Single): TBox;
var
B: TPointArray;
begin
B := [
TSimbaGeometry.RotatePoint(Point(0, H), Angle, W div 2, H div 2),
TSimbaGeometry.RotatePoint(Point(W, H), Angle, W div 2, H div 2),
TSimbaGeometry.RotatePoint(Point(W, 0), Angle, W div 2, H div 2),
TSimbaGeometry.RotatePoint(Point(0, 0), Angle, W div 2, H div 2)
];

Result := B.Bounds();
end;

// in FPC trunk
{$IFDEF CPUX86_64}
procedure FillXxxx_MoreThanTwoXmms; assembler; nostackframe;
Expand Down Expand Up @@ -136,7 +175,7 @@ procedure FillDWord(var x;count:SizeInt;value:DWord);assembler;nostackframe;
end;
{$ENDIF}

procedure FillData(Data: PColorBGRA; count: SizeInt; value: TColorBGRA);
procedure FillData(const Data: PColorBGRA; const count: SizeInt; const value: TColorBGRA);
begin
FillDWord(Data^, Count, DWord(Value));
end;
Expand Down
42 changes: 34 additions & 8 deletions Source/script/imports/simbaclasses/simba.import_class_image.pas
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ implementation
=====
TImage is a data type that holds an image.
This is used anipulate and process an image such as resizing, rotating, bluring and much more.
This is used manipulate and process an image such as resizing, rotating, bluring and much more.
Or simply get/set a pixel color at a given (x,y) coord.
Note:
| For methods with a `Alpha` parameter "real" alpha blending is not performed.
| The background of the pixel is just mixed in.
| If `Alpha=127` half of the background will be blended in.
*)

(*
Expand Down Expand Up @@ -182,21 +189,25 @@ procedure _LapeImage_LoadFromFileEx(const Params: PParamArray); LAPE_WRAPPER_CAL
(*
TImage.DrawATPA
~~~~~~~~~~~~~~~
> procedure TImage.DrawATPA(ATPA: T2DPointArray; Color: TColor = -1);
> procedure TImage.DrawATPA(const ATPA: T2DPointArray; Color: TColor = -1; Alpha: Byte = 0);
Draws every TPA in the ATPA. Color by default is -1 which will display each TPA in a different color.
*)
procedure _LapeImage_DrawATPA(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.DrawATPA(P2DPointArray(Params^[1])^, PColor(Params^[2])^);
PSimbaImage(Params^[0])^.DrawATPA(P2DPointArray(Params^[1])^, PColor(Params^[2])^, PByte(Params^[3])^);
end;

(*
TImage.DrawTPA
~~~~~~~~~~~~~~
> procedure TImage.DrawTPA(TPA: TPointArray; Color: TColor);
> procedure TImage.DrawTPA(const Points: TPointArray; Color: TColor; Alpha: Byte = 0);
Draws a TPA the same color.
*)
procedure _LapeImage_DrawTPA(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.DrawTPA(PPointArray(Params^[1])^, PColor(Params^[2])^);
PSimbaImage(Params^[0])^.DrawTPA(PPointArray(Params^[1])^, PColor(Params^[2])^, PByte(Params^[3])^);
end;

(*
Expand Down Expand Up @@ -1238,24 +1249,39 @@ procedure _LapeImage_RowPtrs(const Params: PParamArray; const Result: Pointer);
TSimbaImageRowPtrs(Result^) := PSimbaImage(Params^[0])^.RowPtrs();
end;

(*
TImage.DrawLineAA
~~~~~~~~~~~~~~~~~~~~
> procedure TImage.DrawLineAA(Start, Stop: TPoint; Color: TColor; Thickness: Single = 1.5);
*)
procedure _LapeImage_DrawLineAA(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.DrawLineAA(PPoint(Params^[1])^, PPoint(Params^[2])^, PColor(Params^[3])^, PSingle(Params^[4])^);
end;

(*
TImage.DrawEllipseAA
~~~~~~~~~~~~~~~~~~~~
> procedure TImage.DrawEllipseAA(ACenter: TPoint; XRadius, YRadius: Integer; Color: TColor; Thickness: Single = 1.5);
*)
procedure _LapeImage_DrawEllipseAA(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.DrawEllipseAA(PPoint(Params^[1])^, Pinteger(Params^[2])^, PInteger(Params^[3])^, PColor(Params^[4])^, PSingle(Params^[5])^);
end;

(*
TImage.DrawCircleAA
~~~~~~~~~~~~~~~~~~~~
> procedure TImage.DrawCircleAA(ACenter: TPoint; Radius: Integer; Color: TColor; Thickness: Single = 1.5);
*)
procedure _LapeImage_DrawCircleAA(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.DrawCircleAA(PPoint(Params^[1])^, Pinteger(Params^[2])^, PColor(Params^[3])^, PSingle(Params^[4])^);
end;

(*
TImage.Finder
~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~
> function TImage.Finder: TSimbaFinder;
Returns a TSimbaFinder which is targetted to the image.
Expand Down Expand Up @@ -1362,8 +1388,8 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('procedure TImage.DrawText(Text: String; Box: TBox; Center: Boolean; Color: TColor); overload', @_LapeImage_DrawTextEx);
addGlobalFunc('procedure TImage.DrawTextLines(Text: TStringArray; Position: TPoint; Color: TColor);', @_LapeImage_DrawTextLines);

addGlobalFunc('procedure TImage.DrawATPA(ATPA: T2DPointArray; Color: TColor = -1)', @_LapeImage_DrawATPA);
addGlobalFunc('procedure TImage.DrawTPA(TPA: TPointArray; Color: TColor);', @_LapeImage_DrawTPA);
addGlobalFunc('procedure TImage.DrawATPA(const ATPA: T2DPointArray; Color: TColor = -1; Alpha: Byte = 0);', @_LapeImage_DrawATPA);
addGlobalFunc('procedure TImage.DrawTPA(const TPA: TPointArray; Color: TColor; Alpha: Byte = 0);', @_LapeImage_DrawTPA);

addGlobalFunc('procedure TImage.DrawCrosshairs(ACenter: TPoint; Size: Integer; Color: TColor);', @_LapeImage_DrawCrosshairs);
addGlobalFunc('procedure TImage.DrawCross(ACenter: TPoint; Radius: Integer; Color: TColor);', @_LapeImage_DrawCross);
Expand Down
2 changes: 1 addition & 1 deletion Source/simba.env.pas
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
interface

uses
classes, sysutils,
Classes, SysUtils,
simba.mufasatypes;

function FindInclude(var FileName: String; ExtraSearchDirs: TStringArray): Boolean;
Expand Down
16 changes: 8 additions & 8 deletions Source/simba.tpa.pas
Original file line number Diff line number Diff line change
Expand Up @@ -690,23 +690,23 @@ function TPointArrayHelper.Skeleton(FMin: Integer; FMax: Integer): TPointArray;
Change, PTS: TPointArray;
Matrix: TByteMatrix;
iter: Boolean;
Area: TBox;
B: TBox;
begin
Result := Default(TPointArray);

H := High(Self);
if (H > 0) then
begin
Area := Self.Bounds;
Area.x1 := Area.x1 - 2;
Area.y1 := Area.y1 - 2;
Matrix.SetSize(Area.Height + 2, Area.Width + 2);
B := Self.Bounds;
B.x1 := B.x1 - 2;
B.y1 := B.y1 - 2;
Matrix.SetSize(B.Height + 2, B.Width + 2);

SetLength(PTS, H + 1);
for i:=0 to H do
begin
x := (Self[i].x-Area.x1);
y := (Self[i].y-Area.y1);
x := (Self[i].x-B.x1);
y := (Self[i].y-B.y1);
PTS[i].x := X;
PTS[i].y := Y;
Matrix[y][x] := 1;
Expand Down Expand Up @@ -770,7 +770,7 @@ function TPointArrayHelper.Skeleton(FMin: Integer; FMax: Integer): TPointArray;

SetLength(Result, (MarkHigh + 1));
for i := 0 to MarkHigh do
Result[i] := TPoint.Create(PTS[i].x+Area.x1, PTS[i].y+Area.y1);
Result[i] := TPoint.Create(PTS[i].x+B.x1, PTS[i].y+B.y1);
end;
end;

Expand Down

0 comments on commit d085c4b

Please sign in to comment.