diff --git a/Examples/form.simba b/Examples/form.simba
index 9a2700623..d67f75b7e 100644
--- a/Examples/form.simba
+++ b/Examples/form.simba
@@ -38,6 +38,8 @@ var
List: TLazListBox;
Lbl: TLazLabel;
Panel: TLazPanel;
+ Img: TLazImage;
+ SimbaImg: TImage;
begin
Form := TLazForm.Create();
Form.SetCaption('Example form');
@@ -49,6 +51,16 @@ begin
Form.SetColor(Colors.DARK_GREY);
Form.SetBorderStyle(bsSingle); // Do not allow resizing
+ SimbaImg := TImage.CreateFromTarget([0,0,400,400]);
+
+ Img := TLazImage.Create(Form);
+ Img.SetParent(Form);
+ Img.SetBounds(400,200,200,200);
+ Img.SetStretch(True);
+ Img.GetPicture().SetBitmap(SimbaImg.ToLazBitmap());
+
+ SimbaImg.Free();
+
Button := TLazButton.Create(Form);
Button.SetParent(Form);
Button.SetAutoSize(True);
diff --git a/Examples/image_drawtext.simba b/Examples/image_drawtext.simba
new file mode 100644
index 000000000..4b3c1e6a9
--- /dev/null
+++ b/Examples/image_drawtext.simba
@@ -0,0 +1,23 @@
+var
+ myImage: TImage;
+ myBox: TBox;
+begin
+ myImage := TImage.Create(500,1000);
+ myImage.Fill(Colors.DARK_GRAY);
+
+ myImage.SetFontAntialiasing(True);
+ myImage.SetFontSize(20);
+
+ myImage.DrawTextLines(TImage.FontNames, [10,10], Colors.BLACK);
+
+ myBox := [225,25,450,240];
+ myImage.DrawBox(myBox, Colors.RED);
+ myImage.DrawText(FormatDateTime('c', Now()), myBox, [ETextDrawAlignment.CENTER, ETextDrawAlignment.VERTICAL_CENTER], Colors.BLACK);
+
+ myImage.SetFontBold(True);
+ myImage.SetFontSize(50);
+ myImage.DrawText(IntToStr(Random(10000)), [225, 300], Colors.NAVY);
+
+ myImage.Show();
+ myImage.Free();
+end.
diff --git a/Source/Simba.lpi b/Source/Simba.lpi
index 3010a6ce6..2212305e9 100644
--- a/Source/Simba.lpi
+++ b/Source/Simba.lpi
@@ -17,7 +17,7 @@
-
+
@@ -29,6 +29,7 @@
+
diff --git a/Source/Simba.res b/Source/Simba.res
index cdc30e75f..38407db4b 100644
Binary files a/Source/Simba.res and b/Source/Simba.res differ
diff --git a/Source/forms/simba.openexampleform.pas b/Source/forms/simba.openexampleform.pas
index b6e3b3aa5..b0517b216 100644
--- a/Source/forms/simba.openexampleform.pas
+++ b/Source/forms/simba.openexampleform.pas
@@ -207,6 +207,7 @@ procedure TSimbaOpenExampleForm.FormCreate(Sender: TObject);
AddNode('JSON', 'EXAMPLE_JSON' );
AddNode('Form', 'EXAMPLE_FORM' );
AddNode('IRC', 'EXAMPLE_IRC' );
+ AddNode('Draw Text', 'EXAMPLE_DRAWTEXT' );
end;
procedure TSimbaOpenExampleForm.DoTreeViewSelectionChanged(Sender: TObject);
diff --git a/Source/image/simba.image.pas b/Source/image/simba.image.pas
index b20d08516..3eccb11b3 100644
--- a/Source/image/simba.image.pas
+++ b/Source/image/simba.image.pas
@@ -39,6 +39,7 @@ TSimbaImage = class(TSimbaBaseClass)
FTextDrawer: TSimbaTextDrawer;
+ procedure RaiseOutOfImageException(X, Y: Integer);
procedure NotifyUnfreed; override;
procedure _DrawTPA(TPA: TPointArray; Color: TColor);
@@ -82,7 +83,7 @@ TSimbaImage = class(TSimbaBaseClass)
public
class var SaveUnfreedImages: ShortString;
class function LoadFonts(Dir: String): Boolean;
- class function LoadedFontNames: TStringArray;
+ class function FontNames: TStringArray;
public
DefaultPixel: TColorBGRA;
@@ -96,7 +97,7 @@ TSimbaImage = class(TSimbaBaseClass)
destructor Destroy; override;
- property Data: PColorBGRA read FData write FData;
+ property Data: PColorBGRA read FData;
property DataOwner: Boolean read FDataOwner write FDataOwner;
property DataSize: SizeUInt read FDataSize;
@@ -116,8 +117,7 @@ TSimbaImage = class(TSimbaBaseClass)
property FontBold: Boolean read GetFontBold write SetFontBold;
property FontItalic: Boolean read GetFontItalic write SetFontItalic;
- function InImage(const X, Y: Integer): Boolean; inline;
- procedure AssertInImage(const Method: String; const X, Y: Integer);
+ function InImage(const X, Y: Integer): Boolean;
function Equals(Other: TObject): Boolean; override;
function Equals(Other: TSimbaImage): Boolean; overload;
@@ -127,7 +127,7 @@ TSimbaImage = class(TSimbaBaseClass)
function TextSize(Text: String): TPoint;
procedure DrawText(Text: String; Position: TPoint; Color: TColor); overload;
- procedure DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor); overload;
+ procedure DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor); overload;
procedure DrawTextLines(Text: TStringArray; Position: TPoint; Color: TColor);
procedure SetSize(NewWidth, NewHeight: Integer);
@@ -204,6 +204,7 @@ TSimbaImage = class(TSimbaBaseClass)
procedure Clear(Box: TBox); overload;
procedure ClearInverted(Box: TBox);
+ procedure SplitChannels(out B,G,R,A: TByteArray);
function GetColors: TColorArray;
procedure ReplaceColor(OldColor, NewColor: TColor);
procedure ReplaceColors(OldColors, NewColors: TColorArray);
@@ -226,7 +227,7 @@ TSimbaImage = class(TSimbaBaseClass)
procedure Pad(Amount: Integer);
function ToLazBitmap: TBitmap;
- procedure LoadFromLazBitmap(LazBitmap: TBitmap);
+ procedure FromLazBitmap(LazBitmap: TBitmap);
function ToGreyMatrix: TByteMatrix;
function ToMatrix: TIntegerMatrix; overload;
@@ -235,15 +236,14 @@ TSimbaImage = class(TSimbaBaseClass)
function ThresholdAdaptive(Alpha, Beta: Byte; AInvert: Boolean; Method: ESimbaImageThreshMethod; K: Integer): TSimbaImage;
function ThresholdSauvola(Radius: Integer; AInvert: Boolean = False; R: Single = 128; K: Single = 0.5): TSimbaImage;
- function SaveToFile(FileName: String; OverwriteIfExists: Boolean = False): Boolean;
+ procedure Load(FileName: String); overload;
+ procedure Load(FileName: String; Area: TBox); overload;
+ function Save(FileName: String; OverwriteIfExists: Boolean = False): Boolean;
function SaveToString: String;
- procedure LoadFromStream(Stream: TStream; FileName: String);
- procedure LoadFromFile(FileName: String); overload;
- procedure LoadFromFile(FileName: String; Area: TBox); overload;
- procedure LoadFromString(Str: String);
- procedure LoadFromData(AWidth, AHeight: Integer; AData: PColorBGRA; ADataWidth: Integer);
- procedure LoadFromImage(Image: TSimbaImage);
+ procedure FromStream(Stream: TStream; FileName: String);
+ procedure FromString(Str: String);
+ procedure FromData(AWidth, AHeight: Integer; AData: PColorBGRA; ADataWidth: Integer);
function Compare(Other: TSimbaImage): Single;
@@ -264,22 +264,20 @@ implementation
simba.image_lazbridge, simba.image_integral, simba.image_gaussblur,
simba.image_bitmaparealoader, simba.image_stringconv;
-function TSimbaImage.SaveToFile(FileName: String; OverwriteIfExists: Boolean): Boolean;
+function TSimbaImage.Save(FileName: String; OverwriteIfExists: Boolean): Boolean;
var
Stream: TFileStream;
WriterClass: TFPCustomImageWriterClass;
- Writer: TFPCustomImageWriter;
begin
Result := False;
if FileExists(FileName) and (not OverwriteIfExists) then
- SimbaException('TSimbaImage.SaveToFile: File already exists "%s"', [FileName]);
+ SimbaException('TSimbaImage.Save: File already exists "%s"', [FileName]);
WriterClass := TFPCustomImage.FindWriterFromFileName(FileName);
if (WriterClass = nil) then
- SimbaException('TSimbaImage.SaveToFile: Unknown image format "%s"', [FileName]);
+ SimbaException('TSimbaImage.Save: Unknown image format "%s"', [FileName]);
- Writer := WriterClass.Create();
Stream := nil;
try
if FileExists(FileName) then
@@ -287,21 +285,17 @@ function TSimbaImage.SaveToFile(FileName: String; OverwriteIfExists: Boolean): B
else
Stream := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite);
- SimbaImage_ToFPImageWriter(Self, Writer, Stream);
+ SimbaImage_ToFPImageWriter(Self, WriterClass, Stream);
Result := True;
finally
- if (Stream <> nil) then
- Stream.Free();
- if (Writer <> nil) then
- Writer.Free();
+ Stream.Free();
end;
end;
-procedure TSimbaImage.LoadFromFile(FileName: String);
+procedure TSimbaImage.Load(FileName: String);
var
ReaderClass: TFPCustomImageReaderClass;
- Reader: TFPCustomImageReader;
Stream: TFileStream;
begin
if (not FileExists(FileName)) then
@@ -310,18 +304,16 @@ procedure TSimbaImage.LoadFromFile(FileName: String);
ReaderClass := TFPCustomImage.FindReaderFromFileName(FileName);
if (ReaderClass = nil) then
SimbaException('TSimbaImage.LoadFromFile: Unknown image format "%s"', [FileName]);
- Reader := ReaderClass.Create();
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
- SimbaImage_FromFPImageReader(Self, Reader, Stream);
+ SimbaImage_FromFPImageReader(Self, ReaderClass, Stream);
finally
- Reader.Free();
Stream.Free();
end;
end;
-procedure TSimbaImage.LoadFromFile(FileName: String; Area: TBox);
+procedure TSimbaImage.Load(FileName: String; Area: TBox);
begin
if (not FileExists(FileName)) then
SimbaException('TSimbaImage.LoadFromFile: File not found "%s"', [FileName]);
@@ -330,7 +322,7 @@ procedure TSimbaImage.LoadFromFile(FileName: String; Area: TBox);
SimbaImage_LoadBitmapArea(Self, FileName, Area)
else
begin
- LoadFromFile(FileName);
+ Load(FileName);
Area := Area.Clip(TBox.Create(0, 0, FWidth - 1, FHeight - 1));
if (Area.Width > 1) and (Area.Height > 1) then
@@ -350,8 +342,8 @@ function TSimbaImage.Copy(X1, Y1, X2, Y2: Integer): TSimbaImage;
var
Y: Integer;
begin
- AssertInImage('Copy', X1, Y1);
- AssertInImage('Copy', X2, Y2);
+ if (not InImage(X1, Y1)) then RaiseOutOfImageException(X1, Y1);
+ if (not InImage(X2, Y2)) then RaiseOutOfImageException(X2, Y2);
Result := TSimbaImage.Create();
Result.SetSize(X2-X1+1, Y2-Y1+1);
@@ -363,8 +355,8 @@ procedure TSimbaImage.Crop(X1, Y1, X2, Y2: Integer);
var
Y: Integer;
begin
- AssertInImage('Crop', X1, Y1);
- AssertInImage('Crop', X2, Y2);
+ if (not InImage(X1, Y1)) then RaiseOutOfImageException(X1, Y1);
+ if (not InImage(X2, Y2)) then RaiseOutOfImageException(X2, Y2);
for Y := Y1 to Y2 do
Move(FData[Y * FWidth + X1], FData[(Y-Y1) * FWidth], FWidth * SizeOf(TColorBGRA));
@@ -408,8 +400,8 @@ function TSimbaImage.ToMatrix(X1, Y1, X2, Y2: Integer): TIntegerMatrix;
var
X, Y: Integer;
begin
- AssertInImage('ToMatrix', X1, Y1);
- AssertInImage('ToMatrix', X2, Y2);
+ if (not InImage(X1, Y1)) then RaiseOutOfImageException(X1, Y1);
+ if (not InImage(X2, Y2)) then RaiseOutOfImageException(X2, Y2);
Result.SetSize(X2-X1+1, Y2-Y1+1);
@@ -422,7 +414,6 @@ function TSimbaImage.ToMatrix(X1, Y1, X2, Y2: Integer): TIntegerMatrix;
procedure TSimbaImage.DrawMatrix(Matrix: TIntegerMatrix);
var
X, Y, W, H: Integer;
- Color: Integer;
begin
SetSize(Matrix.Width, Matrix.Height);
@@ -430,11 +421,11 @@ procedure TSimbaImage.DrawMatrix(Matrix: TIntegerMatrix);
H := FHeight - 1;
for Y := 0 to H do
for X := 0 to W do
- begin
- Color := Matrix[Y, X];
-
- FData[Y * FWidth + X] := TColorBGRA((Color shr B_BIT and $FF) or (Color shr G_BIT and $FF) shl G_BIT or (Color shr R_BIT and $FF) shl B_BIT);
- end;
+ FData[Y * FWidth + X] := TColorBGRA(
+ (Matrix[Y, X] shr B_BIT and $FF) or
+ (Matrix[Y, X] shr G_BIT and $FF) shl G_BIT or
+ (Matrix[Y, X] shr R_BIT and $FF) shl B_BIT
+ );
end;
procedure TSimbaImage.DrawMatrix(Matrix: TSingleMatrix; ColorMapID: Integer = 0);
@@ -494,25 +485,23 @@ function TSimbaImage.SaveToString: String;
Result := SimbaImage_ToString(Self);
end;
-procedure TSimbaImage.LoadFromString(Str: String);
+procedure TSimbaImage.FromString(Str: String);
begin
SimbaImage_FromString(Self, Str);
end;
-procedure TSimbaImage.LoadFromStream(Stream: TStream; FileName: String);
+procedure TSimbaImage.FromStream(Stream: TStream; FileName: String);
var
ReaderClass: TFPCustomImageReaderClass;
- Reader: TFPCustomImageReader;
begin
ReaderClass := TFPCustomImage.FindReaderFromFileName(FileName);
if (ReaderClass = nil) then
SimbaException('TSimbaImage.LoadFromStream: Unknown image format "%s"', [FileName]);
- Reader := ReaderClass.Create();
- SimbaImage_FromFPImageReader(Self, Reader, Stream);
- Reader.Free();
+
+ SimbaImage_FromFPImageReader(Self, ReaderClass, Stream);
end;
-procedure TSimbaImage.LoadFromData(AWidth, AHeight: Integer; AData: PColorBGRA; ADataWidth: Integer);
+procedure TSimbaImage.FromData(AWidth, AHeight: Integer; AData: PColorBGRA; ADataWidth: Integer);
var
Y: Integer;
begin
@@ -521,10 +510,9 @@ procedure TSimbaImage.LoadFromData(AWidth, AHeight: Integer; AData: PColorBGRA;
Exit;
if (ADataWidth <> AWidth) then
- begin
for Y := 0 to AHeight - 1 do
Move(AData[Y * ADataWidth], FData[Y * FWidth], FWidth * SizeOf(TColorBGRA))
- end else
+ else
Move(AData^, FData^, FWidth * FHeight * SizeOf(TColorBGRA));
end;
@@ -678,7 +666,7 @@ function TSimbaImage.PixelDifferenceTPA(Other: TSimbaImage): TPointArray;
for X := 0 to W do
begin
if (not P1^.EqualsIgnoreAlpha(P2^)) then
- Buffer.Add(X, Y);
+ {%H-}Buffer.Add(X, Y);
Inc(P1);
Inc(P2);
@@ -717,14 +705,14 @@ function TSimbaImage.PixelDifferenceTPA(Other: TSimbaImage; Tolerance: Single):
Result := Buffer.ToArray(False);
end;
-procedure TSimbaImage.LoadFromLazBitmap(LazBitmap: TBitmap);
+procedure TSimbaImage.FromLazBitmap(LazBitmap: TBitmap);
var
TempBitmap: TSimbaImage;
begin
SetSize(0, 0);
TempBitmap := LazImage_ToSimbaImage(LazBitmap);
- TempBitmap.DataOwner := False;
+ TempBitmap.FDataOwner := False;
FData := TempBitmap.Data;
FWidth := TempBitmap.Width;
@@ -733,13 +721,6 @@ procedure TSimbaImage.LoadFromLazBitmap(LazBitmap: TBitmap);
TempBitmap.Free();
end;
-procedure TSimbaImage.LoadFromImage(Image: TSimbaImage);
-begin
- SetSize(Image.Width, Image.Height);
-
- Move(Image.FData^, FData^, FWidth * FHeight * SizeOf(TColorBGRA));
-end;
-
procedure TSimbaImage.DrawTPA(TPA: TPointArray; Color: TColor; Alpha: Byte);
begin
if (Alpha = 0) then
@@ -1129,6 +1110,28 @@ procedure TSimbaImage.ClearInverted(Box: TBox);
Self.Clear(TBox.Create(Box.X2 + 1, Box.Y2 + 1, FWidth-1, FHeight - 1)); //Btm Right
end;
+procedure TSimbaImage.SplitChannels(out B,G,R,A: TByteArray);
+var
+ I: Integer;
+ Ptr: PColorBGRA;
+begin
+ SetLength(B, FWidth*FHeight);
+ SetLength(G, FWidth*FHeight);
+ SetLength(R, FWidth*FHeight);
+ SetLength(A, FWidth*FHeight);
+
+ Ptr := FData;
+ for I := 0 to FWidth * FHeight - 1 do
+ begin
+ B[I] := Ptr^.B;
+ G[I] := Ptr^.G;
+ R[I] := Ptr^.R;
+ A[I] := Ptr^.A;
+
+ Inc(Ptr);
+ end;
+end;
+
procedure TSimbaImage.DrawImage(Image: TSimbaImage; Location: TPoint; Alpha: Byte = 0);
begin
if (Alpha = 0) then
@@ -1611,7 +1614,7 @@ function TSimbaImage.BoxBlur(Radius: Integer): TSimbaImage;
for Y := 0 to H do
for X := 0 to W do
begin
- if (FData[Y * FWidth + X].A > 0) then
+ if (FData[Y * FWidth + X].A > ALPHA_TRANSPARENT) then
begin
B.X1 := Max(X-Radius, 0);
B.Y1 := Max(Y-Radius, 0);
@@ -1643,6 +1646,40 @@ function TSimbaImage.BoxBlur(Radius: Integer): TSimbaImage;
end;
end;
+function TSimbaImage.GaussBlur(Radius: Double): TSimbaImage;
+var
+ B,G,R,A: TByteArray;
+ Ignore: TBooleanArray;
+ I: Integer;
+ Ptr: PColorBGRA;
+begin
+ Result := TSimbaImage.Create(FWidth, FHeight);
+ if (FWidth * FHeight = 0) then
+ Exit;
+
+ SplitChannels(B,G,R,A);
+
+ SetLength(Ignore, Length(A));
+ for I := 0 to High(Ignore) do
+ Ignore[I] := (A[I] = ALPHA_TRANSPARENT);
+
+ imgGaussBlur(Radius, R,G,B, Ignore, FWidth, FHeight);
+
+ Ptr := Result.Data;
+ for i := 0 to (FWidth * FHeight) - 1 do
+ begin
+ Ptr^.A := A[I];
+ if (Ptr^.A > ALPHA_TRANSPARENT) then
+ begin
+ Ptr^.B := B[I];
+ Ptr^.G := G[I];
+ Ptr^.R := R[I];
+ end;
+
+ Inc(Ptr);
+ end;
+end;
+
function TSimbaImage.Convolute(Matrix: TDoubleMatrix): TSimbaImage;
var
X, Y, YY, XX, CX, CY: Integer;
@@ -1718,58 +1755,9 @@ function TSimbaImage.Mirror(Style: ESimbaImageMirrorStyle): TSimbaImage;
for X := FHeight - 1 downto 0 do
Result.FData[X*FHeight+Y] := FData[Y*FWidth+X];
end;
- end;
-end;
-
-function TSimbaImage.GaussBlur(Radius: Double): TSimbaImage;
-var
- r,g,b: TByteArray;
- i: Integer;
- ptr: PColorBGRA;
- ptrR, ptrG, ptrB: PByte;
-begin
- Result := TSimbaImage.Create(FWidth, FHeight);
- if (FWidth = 0) or (FHeight = 0) then
- Exit;
-
- SetLength(r, FWidth*FHeight);
- SetLength(g, FWidth*FHeight);
- SetLength(b, FWidth*FHeight);
-
- ptr := FData;
- ptrR := @r[0];
- ptrG := @g[0];
- ptrB := @b[0];
-
- for i := 0 to (FWidth * FHeight) - 1 do
- begin
- ptrR^ := ptr^.R;
- ptrG^ := ptr^.G;
- ptrB^ := ptr^.B;
-
- Inc(ptr);
- Inc(ptrR);
- Inc(ptrG);
- Inc(ptrB);
- end;
-
- imgGaussBlur(Radius, r,g,b, FWidth, FHeight);
-
- ptr := Result.FData;
- ptrR := @r[0];
- ptrG := @g[0];
- ptrB := @b[0];
- for i := 0 to (FWidth * FHeight) - 1 do
- begin
- ptr^.R := ptrR^;
- ptr^.G := ptrG^;
- ptr^.B := ptrB^;
-
- Inc(ptr);
- Inc(ptrR);
- Inc(ptrG);
- Inc(ptrB);
+ else
+ Result := nil;
end;
end;
@@ -1901,7 +1889,7 @@ function TSimbaImage.GetFontName: String;
Result := FTextDrawer.FontName;
end;
-class function TSimbaImage.LoadedFontNames: TStringArray;
+class function TSimbaImage.FontNames: TStringArray;
begin
Result := SimbaFreeTypeFontLoader.FontNames;
end;
@@ -1971,7 +1959,7 @@ procedure TSimbaImage.DrawText(Text: String; Position: TPoint; Color: TColor);
FTextDrawer.DrawText(Text, Position, Color);
end;
-procedure TSimbaImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor);
+procedure TSimbaImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor);
begin
FTextDrawer.DrawText(Text, Box, Alignments, Color);
end;
@@ -2187,7 +2175,9 @@ function TSimbaImage.GetPixels(Points: TPointArray): TColorArray;
for I := 0 to High(Points) do
with Points[I] do
begin
- AssertInImage('GetPixels', X, Y);
+ if (X < 0) or (Y < 0) or (X >= FWidth) or (Y >= FHeight) then
+ RaiseOutOfImageException(X, Y);
+
with FData[Y * FWidth + X] do
Result[I] := TColor(R or G shl G_BIT or B shl B_BIT);
end;
@@ -2203,7 +2193,8 @@ procedure TSimbaImage.SetPixels(Points: TPointArray; Colors: TColorArray);
for I := 0 to High(Points) do
with Points[I] do
begin
- AssertInImage('SetPixels', X, Y);
+ if (X < 0) or (Y < 0) or (X >= FWidth) or (Y >= FHeight) then
+ RaiseOutOfImageException(X, Y);
FData[Y * FWidth + X] := Colors[I].ToBGRA();
end;
@@ -2766,13 +2757,18 @@ procedure TSimbaImage._DrawImageAlpha(Image: TSimbaImage; P: TPoint; Alpha: Byte
end;
end;
+procedure TSimbaImage.RaiseOutOfImageException(X, Y: Integer);
+begin
+ SimbaException('%d,%d is outside the image bounds (0,0,%d,%d)', [X, Y, FWidth-1, FHeight-1]);
+end;
+
procedure TSimbaImage.NotifyUnfreed;
begin
inherited NotifyUnfreed();
if (SaveUnfreedImages <> '') then
try
- SaveToFile(IncludeTrailingPathDelimiter(SetDirSeparators(SaveUnfreedImages)) + IntToStr(PtrUInt(Self)) + '.bmp');
+ Save(IncludeTrailingPathDelimiter(SetDirSeparators(SaveUnfreedImages)) + IntToStr(PtrUInt(Self)) + '.bmp');
except
on E: Exception do
DebugLn(E.ToString);
@@ -2781,7 +2777,8 @@ procedure TSimbaImage.NotifyUnfreed;
function TSimbaImage.GetPixel(const X, Y: Integer): TColor;
begin
- AssertInImage('GetPixel', X, Y);
+ if (X < 0) or (Y < 0) or (X >= FWidth) or (Y >= FHeight) then
+ RaiseOutOfImageException(X, Y);
with FData[Y * FWidth + X] do
Result := R or G shl G_BIT or B shl B_BIT;
@@ -2789,7 +2786,8 @@ function TSimbaImage.GetPixel(const X, Y: Integer): TColor;
procedure TSimbaImage.SetPixel(X, Y: Integer; Color: TColor);
begin
- AssertInImage('SetPixel', X, Y);
+ if (X < 0) or (Y < 0) or (X >= FWidth) or (Y >= FHeight) then
+ RaiseOutOfImageException(X, Y);
FData[Y * FWidth + X] := Color.ToBGRA();
end;
@@ -2799,12 +2797,6 @@ function TSimbaImage.InImage(const X, Y: Integer): Boolean;
Result := (X >= 0) and (Y >= 0) and (X < FWidth) and (Y < FHeight);
end;
-procedure TSimbaImage.AssertInImage(const Method: String; const X, Y: Integer);
-begin
- if (X < 0) or (Y < 0) or (X >= FWidth) or (Y >= FHeight) then
- SimbaException('TSimbaImage.%s: %d,%d is outside the image bounds: %d,%d,%d,%d', [Method, X, Y, 0,0,FWidth-1,FHeight-1]);
-end;
-
procedure TSimbaImage.DrawLineAA(Start, Stop: TPoint; Color: TColor; Thickness: Single);
var
RGB: TColorBGRA;
@@ -3087,7 +3079,7 @@ constructor TSimbaImage.CreateFromFile(FileName: String);
begin
Create();
- LoadFromFile(FileName);
+ Load(FileName);
end;
constructor TSimbaImage.CreateFromZip(ZipFileName, ZipEntryName: String);
@@ -3098,7 +3090,7 @@ constructor TSimbaImage.CreateFromZip(ZipFileName, ZipEntryName: String);
if ZipExtractOne(ZipFileName, ZipEntryName, Stream) then
try
- LoadFromStream(Stream, ZipEntryName);
+ FromStream(Stream, ZipEntryName);
finally
Stream.Free();
end;
@@ -3108,14 +3100,14 @@ constructor TSimbaImage.CreateFromString(Str: String);
begin
Create();
- LoadFromString(Str);
+ FromString(Str);
end;
constructor TSimbaImage.CreateFromData(AWidth, AHeight: Integer; AData: PColorBGRA; ADataWidth: Integer);
begin
Create();
- LoadFromData(AWidth, AHeight, AData, ADataWidth);
+ FromData(AWidth, AHeight, AData, ADataWidth);
end;
constructor TSimbaImage.CreateFromWindow(Window: TWindowHandle);
@@ -3128,7 +3120,7 @@ constructor TSimbaImage.CreateFromWindow(Window: TWindowHandle);
if SimbaNativeInterface.GetWindowBounds(Window, B) and
SimbaNativeInterface.GetWindowImage(Window, 0, 0, B.Width - 1, B.Height - 1, ImageData) then
try
- LoadFromData(B.Width - 1, B.Height - 1, ImageData, B.Width - 1);
+ FromData(B.Width - 1, B.Height - 1, ImageData, B.Width - 1);
finally
FreeMem(ImageData);
end;
@@ -3139,8 +3131,7 @@ destructor TSimbaImage.Destroy;
if FDataOwner then
SetSize(0, 0);
- if (FTextDrawer <> nil) then
- FreeAndNil(FTextDrawer);
+ FreeAndNil(FTextDrawer);
inherited Destroy();
end;
diff --git a/Source/image/simba.image_gaussblur.pas b/Source/image/simba.image_gaussblur.pas
index d92077cd9..55aa524e8 100644
--- a/Source/image/simba.image_gaussblur.pas
+++ b/Source/image/simba.image_gaussblur.pas
@@ -1,4 +1,7 @@
// https://blog.ivank.net/fastest-gaussian-blur.html
+// Olly:
+// Hacked in `ignore` param to ignore a pixel, seems to work at first glance.
+// This does mean the edges will be sharp, but might be useful.
unit simba.image_gaussblur;
{$i simba.inc}
@@ -9,7 +12,7 @@ interface
Classes, SysUtils,
simba.base;
-procedure imgGaussBlur(radius: Double; var r,g,b: TByteArray; width, height: Integer);
+procedure imgGaussBlur(radius: Double; var r,g,b: TByteArray; ignore: TBooleanArray; width, height: Integer);
implementation
@@ -42,7 +45,7 @@ function boxesForGauss(sigma: Double; n: Integer): TIntegerArray;
end;
end;
-procedure boxBlurH_4(var scl, tcl: TByteArray; w, h: Integer; r: Integer);
+procedure boxBlurH_4(var scl, tcl: TByteArray; ignore: TBooleanArray; w, h: Integer; r: Integer);
var
iarr: Double;
i,j: Integer;
@@ -54,6 +57,9 @@ procedure boxBlurH_4(var scl, tcl: TByteArray; w, h: Integer; r: Integer);
for i := 0 to h-1 do
begin
ti := i * w;
+ if (ignore[ti]) then
+ Continue;
+
li := ti;
ri := Round(ti + r);
fv := scl[ti];
@@ -90,7 +96,7 @@ procedure boxBlurH_4(var scl, tcl: TByteArray; w, h: Integer; r: Integer);
end;
end;
-procedure boxBlurT_4(var scl, tcl: TByteArray; w, h: Integer; r: Integer);
+procedure boxBlurT_4(var scl, tcl: TByteArray; ignore: TBooleanArray; w, h: Integer; r: Integer);
var
iarr: Double;
i,j: Integer;
@@ -138,25 +144,22 @@ procedure boxBlurT_4(var scl, tcl: TByteArray; w, h: Integer; r: Integer);
end;
end;
-procedure boxBlur_4(var scl, tcl: TByteArray; w,h: Integer; r: Integer);
-var
- i: Integer;
+procedure boxBlur_4(var scl, tcl: TByteArray; skip: TBooleanArray; w,h: Integer; r: Integer);
begin
- for i:=0 to High(scl) do
- tcl[i] := scl[i];
+ Move(scl[0], tcl[0], Length(scl) * SizeOf(Byte));
- boxBlurH_4(tcl, scl, w, h, r);
- boxBlurT_4(scl, tcl, w, h, r);
+ boxBlurH_4(tcl, scl, skip, w, h, r);
+ boxBlurT_4(scl, tcl, skip, w, h, r);
end;
-procedure gaussBlur_4(var scl, tcl: TByteArray; w,h: Integer; r: Double; bxs: TIntegerArray);
+procedure gaussBlur_4(var scl, tcl: TByteArray; skip: TBooleanArray; w,h: Integer; r: Double; bxs: TIntegerArray);
begin
- boxBlur_4(scl, tcl, w, h, (bxs[0] - 1) div 2);
- boxBlur_4(tcl, scl, w, h, (bxs[1] - 1) div 2);
- boxBlur_4(scl, tcl, w, h, (bxs[2] - 1) div 2);
+ boxBlur_4(scl, tcl, skip, w, h, (bxs[0] - 1) div 2);
+ boxBlur_4(tcl, scl, skip, w, h, (bxs[1] - 1) div 2);
+ boxBlur_4(scl, tcl, skip, w, h, (bxs[2] - 1) div 2);
end;
-procedure imgGaussBlur(radius: Double; var r, g, b: TByteArray; width, height: Integer);
+procedure imgGaussBlur(radius: Double; var r, g, b: TByteArray; ignore: TBooleanArray; width, height: Integer);
var
outR, outG, outB: TByteArray;
boxes: TIntegerArray;
@@ -167,9 +170,9 @@ procedure imgGaussBlur(radius: Double; var r, g, b: TByteArray; width, height: I
boxes := boxesForGauss(radius, 3);
- gaussBlur_4(r, outR, width, height, radius, boxes);
- gaussBlur_4(g, outG, width, height, radius, boxes);
- gaussBlur_4(b, outB, width, height, radius, boxes);
+ gaussBlur_4(r, outR, ignore, width, height, radius, boxes);
+ gaussBlur_4(g, outG, ignore, width, height, radius, boxes);
+ gaussBlur_4(b, outB, ignore, width, height, radius, boxes);
r := outR;
g := outG;
diff --git a/Source/image/simba.image_lazbridge.pas b/Source/image/simba.image_lazbridge.pas
index c2806be96..b4d7f891e 100644
--- a/Source/image/simba.image_lazbridge.pas
+++ b/Source/image/simba.image_lazbridge.pas
@@ -18,7 +18,7 @@ interface
{$scopedenums on}
type
- ELazPixelFormat = (BGR, BGRA, RGB, RGBA, ARGB);
+ ELazPixelFormat = (UNKNOWN, BGR, BGRA, RGB, RGBA, ARGB);
{$scopedenums off}
procedure LazImage_CopyRow_BGR(Source: PColorBGRA; SourceUpper: PtrUInt; Dest: PColorBGR); inline;
@@ -30,8 +30,8 @@ procedure LazImage_FromSimbaImage(LazImage: TBitmap; SimbaImage: TSimbaImage);
function LazImage_ToSimbaImage(LazImage: TBitmap): TSimbaImage;
function LazImage_PixelFormat(LazImage: TBitmap): ELazPixelFormat;
-procedure SimbaImage_ToFPImageWriter(SimbaImage: TSimbaImage; Writer: TFPCustomImageWriter; Stream: TStream);
-procedure SimbaImage_FromFPImageReader(SimbaImage: TSimbaImage; Reader: TFPCustomImageReader; Stream: TStream);
+procedure SimbaImage_ToFPImageWriter(SimbaImage: TSimbaImage; WriterClass: TFPCustomImageWriterClass; Stream: TStream);
+procedure SimbaImage_FromFPImageReader(SimbaImage: TSimbaImage; ReaderClass: TFPCustomImageReaderClass; Stream: TStream);
function SimbaImage_ToRawImage(SimbaImage: TSimbaImage): TRawImage;
function SimbaImage_ToLazImage(SimbaImage: TSimbaImage): TBitmap;
@@ -264,6 +264,8 @@ function LazImage_PixelFormat(LazImage: TBitmap): ELazPixelFormat;
var
ChannelCount: Integer;
begin
+ Result := ELazPixelFormat.UNKNOWN;
+
with LazImage.RawImage.Description do
begin
if ((BitsPerPixel and 7) <> 0) then
@@ -298,15 +300,17 @@ function LazImage_PixelFormat(LazImage: TBitmap): ELazPixelFormat;
end;
end;
-procedure SimbaImage_ToFPImageWriter(SimbaImage: TSimbaImage; Writer: TFPCustomImageWriter; Stream: TStream);
+procedure SimbaImage_ToFPImageWriter(SimbaImage: TSimbaImage; WriterClass: TFPCustomImageWriterClass; Stream: TStream);
var
Img: TLazIntfImage;
+ Writer: TFPCustomImageWriter;
begin
Img := nil;
+ Writer := nil;
try
+ Writer := WriterClass.Create();
Img := TLazIntfImage.Create(SimbaImage_ToRawImage(SimbaImage), False);
-
Writer.ImageWrite(Stream, Img);
finally
if Assigned(Img) then
@@ -314,21 +318,25 @@ procedure SimbaImage_ToFPImageWriter(SimbaImage: TSimbaImage; Writer: TFPCustomI
end;
end;
-procedure SimbaImage_FromFPImageReader(SimbaImage: TSimbaImage; Reader: TFPCustomImageReader; Stream: TStream);
+procedure SimbaImage_FromFPImageReader(SimbaImage: TSimbaImage; ReaderClass: TFPCustomImageReaderClass; Stream: TStream);
var
Img: TLazIntfImage;
+ Reader: TFPCustomImageReader;
begin
Img := nil;
+ Reader := nil;
try
+ Reader := ReaderClass.Create();
+
Img := TLazIntfImage.Create(0, 0);
Img.DataDescription := SimbaRawImgDescription;
Reader.ImageRead(Stream, Img);
- SimbaImage.LoadFromData(Img.Width, Img.Height, PColorBGRA(Img.PixelData), Img.Width);
+ SimbaImage.FromData(Img.Width, Img.Height, PColorBGRA(Img.PixelData), Img.Width);
finally
- if Assigned(Img) then
- Img.Free();
+ Img.Free();
+ Reader.Free();
end;
end;
diff --git a/Source/image/simba.image_textdrawer.pas b/Source/image/simba.image_textdrawer.pas
index c6dc849b0..ffc3f4959 100644
--- a/Source/image/simba.image_textdrawer.pas
+++ b/Source/image/simba.image_textdrawer.pas
@@ -15,8 +15,6 @@ interface
type
TSimbaFreeTypeFontLoader = class
- private
- function GetFontNames: TStringArray;
protected
type
TFontCacheEntry = record
@@ -31,6 +29,8 @@ TFontCacheEntry = record
FSystemFontsLoaded: Boolean;
procedure LoadSystemFonts;
+
+ function GetFontNames: TStringArray;
public
function LoadFonts(Dir: String): Boolean;
function GetFont(AName: String; ASize: Single; AAntialised, ABold, AItalic: Boolean): TFreeTypeFont;
@@ -39,8 +39,8 @@ TFontCacheEntry = record
end;
{$scopedenums on}
- ETextDrawAlignment = (LEFT, CENTER, RIGHT, JUSTIFY, TOP, VERTICAL_CENTER, BASE_LINE, BOTTOM);
- ETextDrawAlignmentSet = set of ETextDrawAlignment;
+ ETextDrawAlign = (LEFT, CENTER, RIGHT, JUSTIFY, TOP, VERTICAL_CENTER, BASE_LINE, BOTTOM);
+ ETextDrawAlignSet = set of ETextDrawAlign;
{$scopedenums off}
TSimbaTextDrawer = class(TFPImageFreeTypeDrawer)
@@ -81,7 +81,7 @@ TSimbaTextDrawer = class(TFPImageFreeTypeDrawer)
property DrawnBox: TBox read FDrawnBox;
procedure DrawText(Text: String; Position: TPoint; Color: TColor); overload;
- procedure DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor); overload;
+ procedure DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor); overload;
function TextWidth(Text: String): Integer;
function TextHeight(Text: String): Integer;
@@ -97,7 +97,7 @@ implementation
uses
Forms, FileUtil, LazFileUtils, LazFreeTypeFontCollection,
- simba.image, simba.image_utils;
+ simba.image, simba.image_utils, simba.fonthelpers;
function TSimbaFreeTypeFontLoader.GetFontNames: TStringArray;
begin
@@ -363,6 +363,7 @@ constructor TSimbaTextDrawer.Create(SimbaImage: TObject);
FSimbaImage := SimbaImage;
FSize := 20;
FFontAntialised := False;
+ FFontName := GetDefaultFontName();
end;
procedure TSimbaTextDrawer.DrawText(Text: String; Position: TPoint; Color: TColor);
@@ -375,7 +376,7 @@ procedure TSimbaTextDrawer.DrawText(Text: String; Position: TPoint; Color: TColo
end;
end;
-procedure TSimbaTextDrawer.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor);
+procedure TSimbaTextDrawer.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor);
var
FreeTypeAlignments: TFreeTypeAlignments absolute Alignments;
begin
diff --git a/Source/script/imports/simba.import_externalimage.pas b/Source/script/imports/simba.import_externalimage.pas
index 0dbb05534..367f40e48 100644
--- a/Source/script/imports/simba.import_externalimage.pas
+++ b/Source/script/imports/simba.import_externalimage.pas
@@ -198,7 +198,7 @@ procedure _LapeExternalImage_DrawText(const Params: PParamArray); LAPE_WRAPPER_C
*)
procedure _LapeExternalImage_DrawTextEx(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaExternalImage(Params^[0])^.DrawText(PString(Params^[1])^, PBox(Params^[2])^, ETextDrawAlignmentSet(Params^[3]^), PColor(Params^[4])^);
+ PSimbaExternalImage(Params^[0])^.DrawText(PString(Params^[1])^, PBox(Params^[2])^, ETextDrawAlignSet(Params^[3]^), PColor(Params^[4])^);
end;
(*
@@ -420,7 +420,7 @@ procedure ImportSimbaExternalImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('function TExternalImage.TextSize(Text: String): TPoint;', @_LapeExternalImage_TextSize);
addGlobalFunc('procedure TExternalImage.DrawText(Text: String; Position: TPoint; Color: TColor); overload', @_LapeExternalImage_DrawText);
- addGlobalFunc('procedure TExternalImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor); overload', @_LapeExternalImage_DrawTextEx);
+ addGlobalFunc('procedure TExternalImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor); overload', @_LapeExternalImage_DrawTextEx);
addGlobalFunc('procedure TExternalImage.DrawTextLines(Text: TStringArray; Position: TPoint; Color: TColor);', @_LapeExternalImage_DrawTextLines);
addGlobalFunc('procedure TExternalImage.Fill(Color: TColor; Alpha: Byte)', @_LapeExternalImage_Fill);
diff --git a/Source/script/imports/simba.import_image.pas b/Source/script/imports/simba.import_image.pas
index 8e585a777..92a071a90 100644
--- a/Source/script/imports/simba.import_image.pas
+++ b/Source/script/imports/simba.import_image.pas
@@ -124,7 +124,7 @@ procedure _LapeImage_Height_Read(const Params: PParamArray; const Result: Pointe
~~~~~~~~~~~~~~~~~~~~~~
> procedure TImage.SetExternalData(AData: PColorBGRA; AWidth, AHeight: Integer);
*)
-procedure _LapeImage_SetPersistentMemory(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_SetExternalData(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.SetExternalData(PPointer(Params^[1])^, PInteger(Params^[2])^, PInteger(Params^[3])^);
end;
@@ -134,7 +134,7 @@ procedure _LapeImage_SetPersistentMemory(const Params: PParamArray); LAPE_WRAPPE
~~~~~~~~~~~~~~~~~~~~~~~~
> procedure TImage.ResetExternalData;
*)
-procedure _LapeImage_ResetPersistentMemory(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_ResetExternalData(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.ResetExternalData();
end;
@@ -144,9 +144,9 @@ procedure _LapeImage_ResetPersistentMemory(const Params: PParamArray); LAPE_WRAP
~~~~~~~~~~~~~~~~~
> function TImage.SaveToFile(FileName: String; OverwriteIfExists: Boolean = False): Boolean;
*)
-procedure _LapeImage_SaveToFile(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_Save(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
- PBoolean(Result)^ := PSimbaImage(Params^[0])^.SaveToFile(PString(Params^[1])^, PBoolean(Params^[2])^);
+ PBoolean(Result)^ := PSimbaImage(Params^[0])^.Save(PString(Params^[1])^, PBoolean(Params^[2])^);
end;
(*
@@ -164,9 +164,9 @@ procedure _LapeImage_SaveToString(const Params: PParamArray; const Result: Point
~~~~~~~~~~~~~~~~~~~
> procedure TImage.LoadFromFile(FileName: String);
*)
-procedure _LapeImage_LoadFromFile(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_Load1(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaImage(Params^[0])^.LoadFromFile(PString(Params^[1])^);
+ PSimbaImage(Params^[0])^.Load(PString(Params^[1])^);
end;
(*
@@ -174,9 +174,9 @@ procedure _LapeImage_LoadFromFile(const Params: PParamArray); LAPE_WRAPPER_CALLI
~~~~~~~~~~~~~~~~~~~
> procedure TImage.LoadFromFile(FileName: String; Area: TBox);
*)
-procedure _LapeImage_LoadFromFileEx(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_Load2(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaImage(Params^[0])^.LoadFromFile(PString(Params^[1])^, PBox(Params^[2])^);
+ PSimbaImage(Params^[0])^.Load(PString(Params^[1])^, PBox(Params^[2])^);
end;
(*
@@ -328,9 +328,9 @@ procedure _LapeImage_ToLazBitmap(const Params: PParamArray; const Result: Pointe
~~~~~~~~~~~~~~~~~~~~~~~~
> procedure TImage.LoadFromLazBitmap(LazBitmap: TLazBitmap);
*)
-procedure _LapeImage_LoadFromLazBitmap(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_FromLazBitmap(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaImage(Params^[0])^.LoadFromLazBitmap(PBitmap(Params^[1])^);
+ PSimbaImage(Params^[0])^.FromLazBitmap(PBitmap(Params^[1])^);
end;
(*
@@ -935,7 +935,7 @@ procedure _LapeImage_DrawText(const Params: PParamArray); LAPE_WRAPPER_CALLING_C
*)
procedure _LapeImage_DrawTextEx(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaImage(Params^[0])^.DrawText(PString(Params^[1])^, PBox(Params^[2])^, ETextDrawAlignmentSet(Params^[3]^), PColor(Params^[4])^);
+ PSimbaImage(Params^[0])^.DrawText(PString(Params^[1])^, PBox(Params^[2])^, ETextDrawAlignSet(Params^[3]^), PColor(Params^[4])^);
end;
(*
@@ -1045,9 +1045,9 @@ procedure _LapeImage_PixelDifferenceToleranceTPA(const Params: PParamArray; cons
~~~~~~~~~~~~~~~~~~~~~
> procedure TImage.LoadFromString(Str: String);
*)
-procedure _LapeImage_LoadFromString(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_FromString(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaImage(Params^[0])^.LoadFromString(PString(Params^[1])^);
+ PSimbaImage(Params^[0])^.FromString(PString(Params^[1])^);
end;
(*
@@ -1055,19 +1055,9 @@ procedure _LapeImage_LoadFromString(const Params: PParamArray); LAPE_WRAPPER_CAL
~~~~~~~~~~~~~~~~~~~
> procedure TImage.LoadFromData(AWidth, AHeight: Integer; Memory: PColorBGRA; DataWidth: Integer);
*)
-procedure _LapeImage_LoadFromData(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_FromData(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
- PSimbaImage(Params^[0])^.LoadFromData(PInteger(Params^[1])^, PInteger(Params^[2])^, PPointer(Params^[3])^, PInteger(Params^[4])^);
-end;
-
-(*
-TImage.LoadFromImage
-~~~~~~~~~~~~~~~~~~~~
-> procedure TImage.LoadFromImage(Image: TImage);
-*)
-procedure _LapeImage_LoadFromImage(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
-begin
- PSimbaImage(Params^[0])^.LoadFromImage(PSimbaImage(Params^[1])^);
+ PSimbaImage(Params^[0])^.FromData(PInteger(Params^[1])^, PInteger(Params^[2])^, PPointer(Params^[3])^, PInteger(Params^[4])^);
end;
(*
@@ -1163,15 +1153,15 @@ procedure _LapeImage_LoadFonts(const Params: PParamArray; const Result: Pointer)
end;
(*
-TImage.GetFontNames
-~~~~~~~~~~~~~~~~~~~
-> function TImage.GetFontNames: TStringArray; static;
+TImage.FontNames
+~~~~~~~~~~~~~~~~
+> function TImage.FontNames: TStringArray; static;
Returns all the available font names.
*)
-procedure _LapeImage_LoadedFontNames(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeImage_FontNames(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
- PStringArray(Result)^ := TSimbaImage.LoadedFontNames();
+ PStringArray(Result)^ := TSimbaImage.FontNames();
end;
(*
@@ -1282,28 +1272,26 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addClass('TImage');
addGlobalType('array of TImage', 'TImageArray');
- addGlobalType('array of PColorBGRA', 'TImageRowPtrs');
addGlobalType('enum(WIDTH, HEIGHT, LINE)', 'EImageMirrorStyle');
addGlobalType('enum(MEAN, MIN_MAX)', 'EImageThreshMethod');
- addGlobalType('enum(LEFT, CENTER, RIGHT, JUSTIFY, TOP, VERTICAL_CENTER, BASE_LINE, BOTTOM)', 'ETextDrawAlignment');
- addGlobalType('set of ETextDrawAlignment', 'ETextDrawAlignmentSet');
+ addGlobalType('enum(LEFT, CENTER, RIGHT, JUSTIFY, TOP, VERTICAL_CENTER, BASE_LINE, BOTTOM)', 'ETextDrawAlign');
+ addGlobalType('set of ETextDrawAlign', 'ETextDrawAlignSet');
- addClassVar('TImage', 'Data', 'PColorBGRA', @_LapeImage_Data_Read);
addClassVar('TImage', 'Name', 'String', @_LapeImage_Name_Read, @_LapeImage_Name_Write);
- addClassVar('TImage', 'Width', 'Integer', @_LapeImage_Width_Read);
- addClassVar('TImage', 'Height', 'Integer', @_LapeImage_Height_Read);
- addClassVar('TImage', 'Center', 'TPoint', @_LapeImage_Center_Read);
-
addClassVar('TImage', 'FontName', 'String', @_LapeImage_FontName_Read, @_LapeImage_FontName_Write);
addClassVar('TImage', 'FontSize', 'Single', @_LapeImage_FontSize_Read, @_LapeImage_FontSize_Write);
addClassVar('TImage', 'FontAntialiasing', 'Boolean', @_LapeImage_FontAntialiasing_Read, @_LapeImage_FontAntialiasing_Write);
addClassVar('TImage', 'FontBold', 'Boolean', @_LapeImage_FontBold_Read, @_LapeImage_FontBold_Write);
addClassVar('TImage', 'FontItalic', 'Boolean', @_LapeImage_FontItalic_Read, @_LapeImage_FontItalic_Write);
- addGlobalFunc('function TImage.LoadedFontNames: TStringArray; static;', @_LapeImage_LoadedFontNames);
+ addGlobalFunc('function TImage.FontNames: TStringArray; static;', @_LapeImage_FontNames);
addGlobalFunc('function TImage.LoadFonts(Dir: String): Boolean; static;', @_LapeImage_LoadFonts);
+ addGlobalFunc('function TImage.Width: Integer', @_LapeImage_Width_Read);
+ addGlobalFunc('function TImage.Height: Integer', @_LapeImage_Height_Read);
+ addGlobalFunc('function TImage.Data: PColorBGRA', @_LapeImage_Data_Read);
+ addGlobalFunc('function TImage.Center: TPoint', @_LapeImage_Center_Read);
addGlobalFunc('function TImage.InImage(X, Y: Integer): Boolean', @_LapeImage_InImage);
addGlobalFunc('function TImage.Create: TImage; static; overload', @_LapeImage_Create);
@@ -1334,7 +1322,7 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('function TImage.TextHeight(Text: String): Integer;', @_LapeImage_TextHeight);
addGlobalFunc('function TImage.TextSize(Text: String): TPoint;', @_LapeImage_TextSize);
addGlobalFunc('procedure TImage.DrawText(Text: String; Position: TPoint; Color: TColor); overload', @_LapeImage_DrawText);
- addGlobalFunc('procedure TImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor); overload', @_LapeImage_DrawTextEx);
+ addGlobalFunc('procedure TImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; 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; Alpha: Byte = 0);', @_LapeImage_DrawATPA);
@@ -1380,8 +1368,8 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('procedure TImage.DrawMatrix(Matrix: TSingleMatrix; ColorMapID: Integer = 0); overload', @_LapeImage_DrawMatrixF);
addGlobalFunc('procedure TImage.SetSize(AWidth, AHeight: Integer);', @_LapeImage_SetSize);
- addGlobalFunc('procedure TImage.SetPersistentMemory(Memory: PtrUInt; AWidth, AHeight: Integer);', @_LapeImage_SetPersistentMemory);
- addGlobalFunc('procedure TImage.ResetPersistentMemory;', @_LapeImage_ResetPersistentMemory);
+ addGlobalFunc('procedure TImage.SetExternalData(Memory: PtrUInt; AWidth, AHeight: Integer);', @_LapeImage_SetExternalData);
+ addGlobalFunc('procedure TImage.ResetExternalData;', @_LapeImage_ResetExternalData);
addGlobalFunc('function TImage.ResizeNN(AWidth, AHeight: Integer): TImage', @_LapeImage_ResizeNN);
addGlobalFunc('function TImage.ResizeBilinear(AWidth, AHeight: Integer): TImage', @_LapeImage_ResizeBilinear);
@@ -1414,17 +1402,16 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('function TImage.ThresholdSauvola(Radius: Integer; Invert: Boolean = False; R: Single = 128; K: Single = 0.5): TImage', @_LapeImage_ThresholdSauvola);
addGlobalFunc('procedure TImage.Pad(Amount: Integer)', @_LapeImage_Pad);
- addGlobalFunc('procedure TImage.LoadFromFile(FileName: String); overload', @_LapeImage_LoadFromFile);
- addGlobalFunc('procedure TImage.LoadFromFile(FileName: String; Area: TBox); overload', @_LapeImage_LoadFromFileEx);
- addGlobalFunc('procedure TImage.LoadFromString(Str: String)', @_LapeImage_LoadFromString);
- addGlobalFunc('procedure TImage.LoadFromData(AWidth, AHeight: Integer; AData: PColorBGRA; DataWidth: Integer)', @_LapeImage_LoadFromData);
- addGlobalFunc('procedure TImage.LoadFromImage(Image: TImage);', @_LapeImage_LoadFromImage);
-
- addGlobalFunc('function TImage.SaveToFile(FileName: String; OverwriteIfExists: Boolean = False): Boolean;', @_LapeImage_SaveToFile);
+ addGlobalFunc('procedure TImage.Load(FileName: String); overload', @_LapeImage_Load1);
+ addGlobalFunc('procedure TImage.Load(FileName: String; Area: TBox); overload', @_LapeImage_Load2);
+ addGlobalFunc('function TImage.Save(FileName: String; OverwriteIfExists: Boolean = False): Boolean;', @_LapeImage_Save);
addGlobalFunc('function TImage.SaveToString: String;', @_LapeImage_SaveToString);
+ addGlobalFunc('procedure TImage.FromString(Str: String)', @_LapeImage_FromString);
+ addGlobalFunc('procedure TImage.FromData(AWidth, AHeight: Integer; AData: PColorBGRA; DataWidth: Integer)', @_LapeImage_FromData);
+
addGlobalFunc('function TImage.ToLazBitmap: TLazBitmap;', @_LapeImage_ToLazBitmap);
- addGlobalFunc('procedure TImage.LoadFromLazBitmap(LazBitmap: TLazBitmap);', @_LapeImage_LoadFromLazBitmap);
+ addGlobalFunc('procedure TImage.FromLazBitmap(LazBitmap: TLazBitmap);', @_LapeImage_FromLazBitmap);
addGlobalFunc('function TImage.Compare(Other: TImage): Single;', @_LapeImage_Compare);
addGlobalFunc('procedure TImage.SaveUnfreedImages(Directory: String); static;', @_LapeImage_SaveUnfreedImages);
diff --git a/Source/script/imports/simba.import_matchtemplate.pas b/Source/script/imports/simba.import_matchtemplate.pas
index c9c4aac12..49f76fccf 100644
--- a/Source/script/imports/simba.import_matchtemplate.pas
+++ b/Source/script/imports/simba.import_matchtemplate.pas
@@ -34,7 +34,7 @@ implementation
~~~~~~~~~~~~~~~~~~~~~~~~~~
> function TMatchTemplateCache.Create(Image, Template: TIntegerMatrix; Formula: ETMFormula): TMatchTemplateCache; static;
*)
-procedure _LapeMatchTemplateCache_Create(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplateCache_Create1(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PMatchTemplateCacheBase(Result)^ := MatchTemplateCache(PIntegerMatrix(Params^[0])^, PIntegerMatrix(Params^[1])^, PTMFormula(Params^[2])^);
end;
@@ -44,7 +44,7 @@ procedure _LapeMatchTemplateCache_Create(const Params: PParamArray; const Result
~~~~~~~~~~~~~~~~~~~~~~~~~~
> function TMatchTemplateCache.Create(Image, Template: TImage; Formula: ETMFormula): TMatchTemplateCache; static;
*)
-procedure _LapeMatchTemplateCache_CreateEx(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplateCache_Create2(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PMatchTemplateCacheBase(Result)^ := MatchTemplateCache(PSimbaImage(Params^[0])^, PSimbaImage(Params^[1])^, PTMFormula(Params^[2])^);
end;
@@ -64,27 +64,17 @@ procedure _LapeMatchTemplateCache_FreeOnTerminate(const Params: PParamArray); LA
~~~~~~~~~~~~~~~~~
> function MatchTemplateMask(Cache: TMatchTemplateCache; Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix;
*)
-procedure _LapeMatchTemplateMaskCache(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplateMaskCache1(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PSingleMatrix(Result)^ := MatchTemplateMask(PMatchTemplateCacheBase(Params^[0])^, PIntegerMatrix(Params^[1])^, PTMFormula(Params^[2])^);
end;
-(*
-MatchTemplateMask
-~~~~~~~~~~~~~~~~~
-> function MatchTemplateMask(Cache: TMatchTemplateCache; Template: TImage; Formula: ETMFormula): TSingleMatrix;
-*)
-procedure _LapeMatchTemplateMaskCacheEx(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
-begin
- PSingleMatrix(Result)^ := MatchTemplateMask(PMatchTemplateCacheBase(Params^[0])^, PSimbaImage(Params^[1])^, PTMFormula(Params^[2])^);
-end;
-
(*
MatchTemplateMask
~~~~~~~~~~~~~~~~~
> function MatchTemplateMask(Image, Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix;
*)
-procedure _LapeMatchTemplateMask(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplateMask1(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PSingleMatrix(Result)^ := MatchTemplateMask(PIntegerMatrix(Params^[0])^, PIntegerMatrix(Params^[1])^, PTMFormula(Params^[2])^);
end;
@@ -94,27 +84,37 @@ procedure _LapeMatchTemplateMask(const Params: PParamArray; const Result: Pointe
~~~~~~~~~~~~~
> function MatchTemplate(Image, Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix;
*)
-procedure _LapeMatchTemplate(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplate1(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PSingleMatrix(Result)^ := MatchTemplate(PIntegerMatrix(Params^[0])^, PIntegerMatrix(Params^[1])^, PTMFormula(Params^[2])^);
end;
(*
-TImage.MatchTemplate
-~~~~~~~~~~~~~~~~~~~~
-> function TImage.MatchTemplate(Template: TImage; Formula: ETMFormula): TSingleMatrix;
+MatchTemplateMask
+~~~~~~~~~~~~~~~~~
+> function MatchTemplateMask(Cache: TMatchTemplateCache; Template: TImage; Formula: ETMFormula): TSingleMatrix;
+*)
+procedure _LapeMatchTemplateMaskCache2(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+begin
+ PSingleMatrix(Result)^ := MatchTemplateMask(PMatchTemplateCacheBase(Params^[0])^, PSimbaImage(Params^[1])^, PTMFormula(Params^[2])^);
+end;
+
+(*
+MatchTemplate
+~~~~~~~~~~~~~
+> function MatchTemplate(Image, Template: TImage; Formula: ETMFormula): TSingleMatrix;
*)
-procedure _LapeImage_MatchTemplate(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplate2(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PSingleMatrix(Result)^ := MatchTemplate(PSimbaImage(Params^[0])^, PSimbaImage(Params^[1])^, PTMFormula(Params^[2])^);
end;
(*
-TImage.MatchTemplateMask
-~~~~~~~~~~~~~~~~~~~~~~~~
-> function TImage.MatchTemplateMask(Template: TImage; Formula: ETMFormula): TSingleMatrix;
+MatchTemplateMask
+~~~~~~~~~~~~~~~~~
+> function MatchTemplateMask(Image, Template: TImage; Formula: ETMFormula): TSingleMatrix;
*)
-procedure _LapeImage_MatchTemplateMask(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
+procedure _LapeMatchTemplateMask2(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PSingleMatrix(Result)^ := MatchTemplateMask(PSimbaImage(Params^[0])^, PSimbaImage(Params^[1])^, PTMFormula(Params^[2])^);
end;
@@ -130,19 +130,19 @@ procedure ImportMatchTemplate(Compiler: TSimbaScript_Compiler);
addClass('TMatchTemplateCache');
addGlobalType('(TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED, TM_SQDIFF, TM_SQDIFF_NORMED)', 'ETMFormula');
- addGlobalFunc('function TMatchTemplateCache.Create(Image, Template: TIntegerMatrix; Formula: ETMFormula): TMatchTemplateCache; static; overload', @_LapeMatchTemplateCache_Create);
- addGlobalFunc('function TMatchTemplateCache.Create(Image, Template: TImage; Formula: ETMFormula): TMatchTemplateCache; static; overload', @_LapeMatchTemplateCache_CreateEx);
+ addGlobalFunc('function TMatchTemplateCache.Create(Image, Template: TIntegerMatrix; Formula: ETMFormula): TMatchTemplateCache; static; overload', @_LapeMatchTemplateCache_Create1);
+ addGlobalFunc('function TMatchTemplateCache.Create(Image, Template: TImage; Formula: ETMFormula): TMatchTemplateCache; static; overload', @_LapeMatchTemplateCache_Create2);
addGlobalFunc('procedure TMatchTemplateCache.FreeOnTerminate(Enable: Boolean);', @_LapeMatchTemplateCache_FreeOnTerminate);
// TIntegerMatrix
- addGlobalFunc('function MatchTemplateMask(Cache: TMatchTemplateCache; Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMaskCache);
- addGlobalFunc('function MatchTemplateMask(Image, Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMask);
- addGlobalFunc('function MatchTemplate(Image, Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplate);
+ addGlobalFunc('function MatchTemplateMask(Cache: TMatchTemplateCache; Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMaskCache1);
+ addGlobalFunc('function MatchTemplateMask(Image, Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMask1);
+ addGlobalFunc('function MatchTemplate(Image, Template: TIntegerMatrix; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplate1);
// TSimbaImage
- addGlobalFunc('function TImage.MatchTemplateMask(Cache: TMatchTemplateCache; Template: TImage; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMaskCacheEx);
- addGlobalFunc('function TImage.MatchTemplateMask(Template: TImage; Formula: ETMFormula): TSingleMatrix; overload', @_LapeImage_MatchTemplateMask);
- addGlobalFunc('function TImage.MatchTemplate(Template: TImage; Formula: ETMFormula): TSingleMatrix; overload', @_LapeImage_MatchTemplate);
+ addGlobalFunc('function MatchTemplateMask(Cache: TMatchTemplateCache; Template: TImage; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMaskCache2);
+ addGlobalFunc('function MatchTemplateMask(Image, Template: TImage; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplateMask2);
+ addGlobalFunc('function MatchTemplate(Image, Template: TImage; Formula: ETMFormula): TSingleMatrix; overload', @_LapeMatchTemplate2);
ImportingSection := '';
end;
diff --git a/Source/simba.externalimage.pas b/Source/simba.externalimage.pas
index 89f72d845..3d469b0c1 100644
--- a/Source/simba.externalimage.pas
+++ b/Source/simba.externalimage.pas
@@ -98,7 +98,7 @@ TSimbaExternalImage = class(TSimbaBaseClass)
function TextSize(Text: String): TPoint;
procedure DrawText(Text: String; Position: TPoint; Color: TColor); overload;
- procedure DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor); overload;
+ procedure DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor); overload;
procedure DrawTextLines(Text: TStringArray; Position: TPoint; Color: TColor);
// Image
@@ -436,7 +436,7 @@ procedure TSimbaExternalImage.DrawText(Text: String; Position: TPoint; Color: TC
addDirty(FBackBuffer.TextDrawer.DrawnBox);
end;
-procedure TSimbaExternalImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignmentSet; Color: TColor);
+procedure TSimbaExternalImage.DrawText(Text: String; Box: TBox; Alignments: ETextDrawAlignSet; Color: TColor);
begin
CheckInUpdate();
diff --git a/Source/simba.fonthelpers.pas b/Source/simba.fonthelpers.pas
index 24f107df7..fdf692844 100644
--- a/Source/simba.fonthelpers.pas
+++ b/Source/simba.fonthelpers.pas
@@ -17,6 +17,8 @@ function GetFontSize(Control: TWinControl; IncAmount: Integer = 0): Integer;
function IsFontFixed(FontName: String): Boolean;
function GetFixedFonts: TStringArray;
+function GetDefaultFontName: String;
+
implementation
uses
@@ -111,5 +113,15 @@ function GetFixedFonts: TStringArray;
end;
end;
+function GetDefaultFontName: String;
+begin
+ with TBitmap.Create() do
+ try
+ Result := GetFontData(Canvas.Font.Reference.Handle).Name;
+ finally
+ Free();
+ end;
+end;
+
end.
diff --git a/Tests/finder_color.simba b/Tests/finder_color.simba
index f611247c2..9260c15c3 100644
--- a/Tests/finder_color.simba
+++ b/Tests/finder_color.simba
@@ -28,7 +28,7 @@ var
I: Integer;
begin
Bitmap := TImage.Create(500, 500);
- Bitmap.DrawHSLCircle(Bitmap.GetCenter(), 200);
+ Bitmap.DrawHSLCircle(Bitmap.Center(), 200);
Target.SetImage(Bitmap);
diff --git a/Tests/matchtemplatemask.simba b/Tests/matchtemplatemask.simba
index 19506a7ed..be92012eb 100644
--- a/Tests/matchtemplatemask.simba
+++ b/Tests/matchtemplatemask.simba
@@ -51,7 +51,7 @@ begin
img := TImage.CreateFromString('IMG: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');
templ := img.Copy(50, 50, 100, 100);
- templ.DrawCircleInverted(templ.GetCenter(), 20, 0);
+ templ.DrawCircleInverted(templ.Center(), 20, 0);
try
test(TM_CCOEFF, [83, 1], [50, 50]);
diff --git a/Third-Party/syncompletion_simba.pas b/Third-Party/syncompletion_simba.pas
index 2aea25d66..67cbe1395 100644
--- a/Third-Party/syncompletion_simba.pas
+++ b/Third-Party/syncompletion_simba.pas
@@ -1475,8 +1475,11 @@ procedure TSynBaseCompletion.Execute(s: string; x, y: integer);
CurrentString := s;
- if p >= 0 then
- Position := p;
+ //if p >= 0 then
+ // Position := p;
+
+ TheForm.Position := 0;
+ TheForm.Scroll.Position := 0;
if Assigned(OnExecute) then
OnExecute(Self);