You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7019 8e941d3f-bd1b-0410-a28a-d453659cc2b4
738 lines
19 KiB
ObjectPascal
738 lines
19 KiB
ObjectPascal
{
|
|
Authors: Felipe Monteiro de Carvalho, Yang JiXian
|
|
|
|
License: The same modifying LGPL with static linking exception as the LCL
|
|
|
|
This unit implements the TDLBitmap class which has similar property "ScanLine"
|
|
of Delphi TBitmap. With this property we can reuse some classic code of delphi
|
|
to yield our platform independent bitmap class. We hope it simple and powerful.
|
|
|
|
Also some useful image process function has been added into the class.
|
|
}
|
|
|
|
unit DLBitmap;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LCLType, LCLIntf, LMessages, LCLProc, Controls, Graphics,
|
|
Forms, Types, IntfGraphics, FPImage, Math, FPImgCanv, FPCanvas, StdCtrls,
|
|
ClipBrd, ExtCtrls;
|
|
|
|
type
|
|
tagRGBATRIPLE = record
|
|
rgbtBlue: byte;
|
|
rgbtGreen: byte;
|
|
rgbtRed: byte;
|
|
rgbtAlpha: byte;
|
|
end;
|
|
PRGBATriple = ^TRGBATriple;
|
|
{$ifdef MSWINDOWS}
|
|
TRGBATriple = tagRGBTRIPLE;
|
|
{$else}
|
|
TRGBATriple = tagRGBATRIPLE;
|
|
{$endif}
|
|
PRGBATripleArray = ^TRGBATripleArray;
|
|
TRGBATripleArray = array[word] of TRGBATriple;
|
|
|
|
TDLBitmap = class(TBitmap)
|
|
private
|
|
FIntfImgA: TLazIntfImage;
|
|
FFillColor: TColor;
|
|
FOutlineColor: TColor;
|
|
FPaperColor: TColor;
|
|
function GetScanline(Row: integer): pRGBATriple;
|
|
function GetFillColor: TColor;
|
|
function GetOutlineColor: TColor;
|
|
function GetPaperColor: TColor;
|
|
procedure SetFillColor(const AValue: TColor);
|
|
procedure SetOutlineColor(const AValue: TColor);
|
|
procedure SetPaperColor(const AValue: TColor);
|
|
function GetScanLinePixel(X, Y: Integer): TColor;
|
|
procedure SetScanLinePixel(X, Y: Integer; Value: TColor);
|
|
protected
|
|
ImgHandle, ImgMaskHandle: HBitmap;
|
|
procedure SetWidth(Value: integer); override;
|
|
procedure SetHeight(Value: integer); override;
|
|
procedure Changed(Sender: TObject); override;
|
|
procedure InitializeReader(AImage: TLazIntfImage; AReader: TFPCustomImageReader); override;
|
|
procedure InitializeWriter(AImage: TLazIntfImage; AWriter: TFPCustomImageWriter); override;
|
|
procedure FinalizeWriter(AWriter: TFPCustomImageWriter); override;
|
|
public
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
procedure ResetScanLine;
|
|
procedure InvalidateScanLine;
|
|
procedure InvalidateScanLineRect(aRect: TRect);
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure Clear; virtual;
|
|
procedure ClearWhite; virtual;
|
|
procedure Invert; virtual;
|
|
procedure Grayscale; virtual;
|
|
procedure FlipHorz; virtual;
|
|
procedure FlipVert; virtual;
|
|
procedure Rotate90; virtual;
|
|
procedure Rotate180; virtual;
|
|
procedure Rotate270; virtual;
|
|
procedure RGBDelta(RedChange, GreenChange, BlueChange: integer);
|
|
procedure Brightness(ValueChange: integer);
|
|
procedure Contrast(ValueChange: integer);
|
|
procedure RegularPolygon(Center, ThePoint: TPoint; Count: integer);
|
|
procedure ColorReplace(ColorFrom, ColorTo: TColor);
|
|
procedure ReplaceRectColor(ColorFrom, ColorTo: TColor; aRect: TRect; R: integer; Shape: TShapeType);
|
|
property ScanLine[Row: integer]: pRGBATriple read GetScanLine;
|
|
procedure FillEllipse(X1, Y1, X2, Y2: integer); virtual;
|
|
procedure CutToClipboard; virtual;
|
|
procedure CopyToClipboard; virtual;
|
|
procedure PasteFromClipboard; virtual;
|
|
procedure Delete; virtual;
|
|
procedure FloodFill(x, y: integer);
|
|
procedure Spray(x, y, radian: integer; PColor: TColor);
|
|
property FillColor: TColor read GetFillColor write SetFillColor;
|
|
property OutlineColor: TColor read GetOutlineColor write SetOutlineColor;
|
|
property PaperColor: TColor read GetPaperColor write SetPaperColor;
|
|
property Pixels[X, Y: Integer]: TColor read GetScanLinePixel write SetScanLinePixel;
|
|
end;
|
|
|
|
TTextEditor = class;
|
|
|
|
TTextEdit = class(TCustomEdit)
|
|
private
|
|
FCanvas: TCanvas;
|
|
protected
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure DoEnter; override;
|
|
procedure DoExit; override;
|
|
public
|
|
Editor: TTextEditor;
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure EraseBackground(DC: HDC); override;
|
|
property Canvas: TCanvas read FCanvas write FCanvas;
|
|
end;
|
|
|
|
TTextEditor = class(TCustomControl)
|
|
private
|
|
FEdit: TTextEdit;
|
|
FTimer: TIdleTimer;
|
|
flashnum: integer;
|
|
protected
|
|
procedure Paint; override;
|
|
procedure DrawFlashLine(Sender: TObject);
|
|
procedure Changing(Sender: TObject);
|
|
public
|
|
IMGCanvas: TCanvas;
|
|
PositionIndex, StartX, StartY, TextX, TextY: integer;
|
|
procedure StartEdit(ContainerX, ContainerY, IMGX, IMGY: integer);
|
|
procedure StopEdit;
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure EraseBackground(DC: HDC); override;
|
|
property Editor: TTextEdit read FEdit write FEdit;
|
|
end;
|
|
|
|
procedure LazBMPRotate90(const aBitmap: TDLBitmap; IsTurnRight: boolean);
|
|
procedure BMPRotate90(const Bitmap: TDLBitmap);
|
|
procedure DrawSamePixel(ABitmap: TDLBitmap; Value: integer);
|
|
procedure BMPRotate180(const Bitmap: TDLBitmap);
|
|
procedure BMPRotate270(const Bitmap: TDLBitmap);
|
|
function RotateBitmap(Bitmap: TDLBitmap; Angle: integer; BackColor: TColor): TDLBitmap;
|
|
function BitmapFlip(const Vertical: boolean; const Horizontal: boolean;
|
|
var BitmapIn: TDLBitmap; out BitmapOut: TDLBitmap): boolean;
|
|
procedure InvertBitmap(aBitmap: TDLBitmap);
|
|
procedure ChangeRGB(SrcBmp: TDLBitmap; RedChange, GreenChange, BlueChange: integer);
|
|
procedure ChangeBrightness(SrcBmp: TDLBitmap; ValueChange: integer);
|
|
procedure ChangeContrast(SrcBmp: TDLBitmap; ValueChange: integer);
|
|
procedure SprayPoints(DLBmp: TDLBitmap; X, Y: integer; Radians: integer; PColor: TColor);
|
|
function GetRColor(const Color: TColor): byte;
|
|
function GetGColor(const Color: TColor): byte;
|
|
function GetBColor(const Color: TColor): byte;
|
|
procedure SprayPoints(aCanvas: TCanvas; X, Y: integer; Radians: integer; PColor: TColor);
|
|
procedure DLBMPColorReplace(aBitmap: TDLBitmap; ColorFrom, ColorTo: TColor);
|
|
operator + (const A, B: TRGBATriple): TRGBATriple;
|
|
operator - (const A, B: TRGBATriple): TRGBATriple;
|
|
operator * (const A, B: TRGBATriple): TRGBATriple;
|
|
operator = (A, B: TRGBATriple): Boolean;
|
|
operator div (const A, B: TRGBATriple): TRGBATriple;
|
|
function DWordTrans(SrcRow: TRGBATriple): DWORD;
|
|
function DWordToTriple(SrcRow: DWORD): TRGBATriple;
|
|
procedure StretchLinear(Dest, Src: TDLBitmap);
|
|
procedure StretchDLBMP(ACanvas: TCanvas; Src: TDLBitmap; NewLeft, NewTop, NewWidth, NewHeight: integer);
|
|
procedure StretchDLBMPEx(ACanvas: TCanvas; Src: TDLBitmap;
|
|
NewLeft, NewTop, NewWidth, NewHeight: integer; Posx, Posy, aWidth, aHeight: integer);
|
|
procedure DrawRegularPolygon(aCanvas: TCanvas; Center, ThePoint: TPoint; Count: integer);
|
|
|
|
implementation
|
|
|
|
{$I DLBmpUtils.inc}
|
|
|
|
operator + (const A, B: TRGBATriple): TRGBATriple;
|
|
begin
|
|
Result.rgbtBlue := A.rgbtBlue + B.rgbtBlue;
|
|
Result.rgbtRed := A.rgbtRed + B.rgbtRed;
|
|
Result.rgbtGreen := A.rgbtBlue + B.rgbtGreen;
|
|
end;
|
|
|
|
operator - (const A, B: TRGBATriple): TRGBATriple;
|
|
begin
|
|
Result.rgbtBlue := A.rgbtBlue - B.rgbtBlue;
|
|
Result.rgbtRed := A.rgbtRed - B.rgbtRed;
|
|
Result.rgbtGreen := A.rgbtBlue - B.rgbtGreen;
|
|
end;
|
|
|
|
operator * (const A, B: TRGBATriple): TRGBATriple;
|
|
begin
|
|
Result.rgbtBlue := A.rgbtBlue * B.rgbtBlue;
|
|
Result.rgbtRed := A.rgbtRed * B.rgbtRed;
|
|
Result.rgbtGreen := A.rgbtBlue * B.rgbtGreen;
|
|
end;
|
|
|
|
operator div (const A, B: TRGBATriple): TRGBATriple;
|
|
begin
|
|
Result.rgbtBlue := A.rgbtBlue div B.rgbtBlue;
|
|
Result.rgbtRed := A.rgbtRed div B.rgbtRed;
|
|
Result.rgbtGreen := A.rgbtBlue div B.rgbtGreen;
|
|
end;
|
|
|
|
operator = (A, B: TRGBATriple): Boolean;
|
|
begin
|
|
A.rgbtBlue := B.rgbtBlue;
|
|
A.rgbtRed := B.rgbtRed;
|
|
A.rgbtBlue := B.rgbtGreen;
|
|
Result := True;
|
|
end;
|
|
|
|
function DWordTrans(SrcRow: TRGBATriple): DWORD;
|
|
var RR, GG, BB: integer;
|
|
begin
|
|
RR := SrcRow.rgbtRed;
|
|
GG := SrcRow.rgbtGreen;
|
|
BB := SrcRow.rgbtBlue;
|
|
Result := RR + (GG shl 8) and $FF00 + (BB shl 16) and $FF0000;
|
|
end;
|
|
|
|
function DWordToTriple(SrcRow: DWORD): TRGBATriple;
|
|
begin
|
|
Result.rgbtBlue := (SrcRow shr 16) and $FF0000;
|
|
Result.rgbtGreen := (SrcRow shr 8) and $FF00;
|
|
Result.rgbtRed := SrcRow and $FF;
|
|
end;
|
|
|
|
constructor TDLBitmap.Create;
|
|
begin
|
|
inherited;
|
|
PixelFormat := pf24bit;
|
|
FIntfImgA := TLazIntfImage.Create(0, 0);
|
|
end;
|
|
|
|
destructor TDLBitmap.Destroy;
|
|
begin
|
|
FIntfImgA.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TDLBitmap.GetScanLine(Row: integer): pRGBATriple;
|
|
begin
|
|
if FIntfImgA <> nil then
|
|
Result := FIntfImgA.GetDataLineStart(Row);
|
|
end;
|
|
|
|
procedure TDLBitmap.ResetScanLine;
|
|
begin
|
|
FIntfImgA.LoadFromBitmap(Handle, MaskHandle);
|
|
end;
|
|
|
|
procedure TDLBitmap.InvalidateScanLine;
|
|
begin
|
|
FIntfImgA.CreateBitmaps(ImgHandle, ImgMaskHandle, True);
|
|
Handle := ImgHandle;
|
|
MaskHandle := ImgMaskHandle;
|
|
end;
|
|
|
|
procedure TDLBitmap.InvalidateScanLineRect(aRect: TRect);
|
|
var
|
|
TmpBmp: TDLBitmap;
|
|
begin
|
|
TmpBmp := TDLBitmap.Create;
|
|
FIntfImgA.CreateBitmaps(ImgHandle, ImgMaskHandle, True);
|
|
TmpBmp.Handle := ImgHandle;
|
|
TmpBmp.MaskHandle := ImgMaskHandle;
|
|
Empty;
|
|
Width := TmpBmp.Width;
|
|
Height := TmpBmp.Height;
|
|
Canvas.CopyRect(aRect, TmpBmp.Canvas, aRect);
|
|
TmpBmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.CutToClipboard;
|
|
begin
|
|
CopyToClipboard;
|
|
Delete;
|
|
end;
|
|
|
|
procedure TDLBitmap.CopyToClipboard;
|
|
begin
|
|
ClipBoard.Assign(Self);
|
|
end;
|
|
|
|
procedure TDLBitmap.PasteFromClipboard;
|
|
var
|
|
oBmp: TPicture;
|
|
begin
|
|
oBmp := TPicture.Create;
|
|
try
|
|
oBmp.LoadFromClipboardFormat(PredefinedClipboardFormat(pcfBitmap));
|
|
Width := oBmp.Width;
|
|
Height := oBmp.Height;
|
|
Canvas.Draw(0, 0, oBmp.Graphic);
|
|
finally
|
|
oBmp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TDLBitmap.Delete;
|
|
begin
|
|
Canvas.Brush.Style := bsSolid;
|
|
Canvas.Brush.Color := PaperColor;
|
|
Canvas.FillRect(0, 0, Width, Height);
|
|
end;
|
|
|
|
procedure TDLBitmap.Assign(Source: TPersistent);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function TDLBitmap.GetFillColor: TColor;
|
|
begin
|
|
Result := FFillColor;
|
|
end;
|
|
|
|
function TDLBitmap.GetOutlineColor: TColor;
|
|
begin
|
|
Result := FOutlineColor;
|
|
end;
|
|
|
|
function TDLBitmap.GetPaperColor: TColor;
|
|
begin
|
|
Result := FPaperColor;
|
|
end;
|
|
|
|
procedure TDLBitmap.SetFillColor(const AValue: TColor);
|
|
begin
|
|
FFillColor := AValue;
|
|
end;
|
|
|
|
procedure TDLBitmap.SetOutlineColor(const AValue: TColor);
|
|
begin
|
|
FOutlineColor := AValue;
|
|
end;
|
|
|
|
procedure TDLBitmap.SetPaperColor(const AValue: TColor);
|
|
begin
|
|
FPaperColor := AValue;
|
|
end;
|
|
|
|
procedure TDLBitmap.SetWidth(Value: integer);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TDLBitmap.SetHeight(Value: integer);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TDLBitmap.Changed(Sender: TObject);
|
|
begin
|
|
inherited;
|
|
ResetScanLine;
|
|
end;
|
|
|
|
procedure TDLBitmap.Clear;
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TDLBitmap.ClearWhite;
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TDLBitmap.Invert;
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
InvertBitmap(Tmp);
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.Grayscale;
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
ConvertBitmapToGrayScale(Tmp);
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.FlipHorz;
|
|
var
|
|
tmp, tmp2: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp2 := TDLBitmap.Create;
|
|
tmp2.Width := Width;
|
|
tmp2.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
BitmapFlip(False, True, tmp, tmp2);
|
|
Canvas.Draw(0, 0, tmp2);
|
|
tmp.Free;
|
|
tmp2.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.FlipVert;
|
|
var
|
|
tmp, tmp2: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp2 := TDLBitmap.Create;
|
|
tmp2.Width := Width;
|
|
tmp2.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
BitmapFlip(True, False, tmp, tmp2);
|
|
Canvas.Draw(0, 0, tmp2);
|
|
tmp.Free;
|
|
tmp2.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.Rotate90;
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
BMPRotate90(Tmp);
|
|
Self.Width := tmp.Width;
|
|
Self.Height := tmp.Height;
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.Rotate180;
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
BMPRotate180(Tmp);
|
|
Self.Width := tmp.Width;
|
|
Self.Height := tmp.Height;
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.Rotate270;
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
BMPRotate270(Tmp);
|
|
Self.Width := tmp.Width;
|
|
Self.Height := tmp.Height;
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.RGBDelta(RedChange, GreenChange, BlueChange: integer);
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
ChangeRGB(Tmp, RedChange, GreenChange, BlueChange);
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.Brightness(ValueChange: integer);
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
ChangeBrightness(Tmp, ValueChange);
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.Contrast(ValueChange: integer);
|
|
var
|
|
tmp: TDLBitmap;
|
|
begin
|
|
tmp := TDLBitmap.Create;
|
|
tmp.Width := Width;
|
|
tmp.Height := Height;
|
|
tmp.Canvas.Draw(0, 0, Self);
|
|
ChangeContrast(Tmp, ValueChange);
|
|
Canvas.Draw(0, 0, tmp);
|
|
tmp.Free;
|
|
end;
|
|
|
|
procedure TDLBitmap.RegularPolygon(Center, ThePoint: TPoint; Count: integer);
|
|
begin
|
|
DrawRegularPolygon(Canvas, Center, ThePoint, Count);
|
|
end;
|
|
|
|
procedure TDLBitmap.FloodFill(x, y: integer);
|
|
begin
|
|
Canvas.Brush.Color := FFillColor;
|
|
Canvas.FloodFill(x, y, Canvas.Pixels[x, y], fsSurface);
|
|
end;
|
|
|
|
function TDLBitmap.GetScanLinePixel(X, Y: Integer): TColor;
|
|
var SrcRow: pRGBATriple; RR, GG, BB: integer;
|
|
begin
|
|
if (x >= 0) and (x < Width) and (y >= 0) and (y < Height) then
|
|
begin
|
|
SrcRow := ScanLine[y];
|
|
RR := SrcRow[x].rgbtRed;
|
|
GG := SrcRow[x].rgbtGreen;
|
|
BB := SrcRow[x].rgbtBlue;
|
|
end;
|
|
Result := RR + (GG shl 8) and $FF00 + (BB shl 16) and $FF0000;
|
|
end;
|
|
|
|
procedure TDLBitmap.SetScanLinePixel(X, Y: Integer; Value: TColor);
|
|
var SrcRow: pRGBATriple;
|
|
begin
|
|
if (x >= 0) and (x < Width) and (y >= 0) and (y < Height) then
|
|
begin
|
|
SrcRow := ScanLine[y];
|
|
SrcRow[x].rgbtRed:=GetRColor(Value);
|
|
SrcRow[x].rgbtGreen:=GetGColor(Value);
|
|
SrcRow[x].rgbtBlue:=GetBColor(Value);
|
|
end;
|
|
end;
|
|
|
|
procedure TDLBitmap.Spray(x, y, radian: integer; PColor: TColor);
|
|
begin
|
|
SprayPoints(Self, x, y, radian, PColor);
|
|
end;
|
|
|
|
procedure TDLBitmap.InitializeReader(AImage: TLazIntfImage; AReader: TFPCustomImageReader);
|
|
begin
|
|
inherited;
|
|
FIntfImgA := AImage;
|
|
end;
|
|
|
|
procedure TDLBitmap.InitializeWriter(AImage: TLazIntfImage; AWriter: TFPCustomImageWriter);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TDLBitmap.FinalizeWriter(AWriter: TFPCustomImageWriter);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TDLBitmap.FillEllipse(X1, Y1, X2, Y2: integer);
|
|
begin
|
|
Canvas.Brush.Style := bsSolid;
|
|
Canvas.Ellipse(X1, Y1, X2, Y2);
|
|
end;
|
|
|
|
procedure TDLBitmap.ColorReplace(ColorFrom, ColorTo: TColor);
|
|
begin
|
|
DLBMPColorReplace(Self, ColorFrom, ColorTo);
|
|
end;
|
|
|
|
procedure TDLBitmap.ReplaceRectColor(ColorFrom, ColorTo: TColor; aRect: TRect; R: integer; Shape: TShapeType);
|
|
var maskbmp: TDLBitmap; i, j: integer;
|
|
begin
|
|
maskbmp := TDLBitmap.Create;
|
|
maskbmp.Width := aRect.Right - aRect.Left;
|
|
maskbmp.Height := aRect.Bottom - aRect.Top;
|
|
maskbmp.Canvas.Brush.Color := clWhite;
|
|
maskbmp.Canvas.Brush.Style := bsSolid;
|
|
maskbmp.Canvas.Pen.Color := clWhite;
|
|
maskbmp.Canvas.Rectangle(0, 0, Width, Height);
|
|
maskbmp.Canvas.Brush.Color := clBlack;
|
|
maskbmp.Canvas.Pen.Color := clBlack;
|
|
case Shape of
|
|
stRectangle: maskbmp.Canvas.Rectangle(0, 0, maskbmp.Width, maskbmp.Height);
|
|
stRoundRect: maskbmp.Canvas.RoundRect(0, 0, maskbmp.Width, maskbmp.Height, R, R);
|
|
stEllipse : maskbmp.Canvas.Ellipse(0, 0, maskbmp.Width, maskbmp.Height);
|
|
end;
|
|
for i := 0 to maskbmp.Width do
|
|
for j := 0 to maskbmp.Height do
|
|
if maskbmp.Pixels[i, j] = clBlack then
|
|
if Pixels[aRect.Left + i, aRect.Top + j] = ColorFrom then
|
|
Pixels[aRect.Left + i, aRect.Top + j] := ColorTo;
|
|
InvalidateScanline;
|
|
maskbmp.Free;
|
|
end;
|
|
|
|
constructor TTextEdit.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
BorderStyle := bsNone;
|
|
Width := 1;
|
|
Parent := TWinControl(AOwner);
|
|
FCanvas := TCanvas.Create;
|
|
FCanvas.Handle := GetDC(Self.Handle);
|
|
FCanvas.Brush.Style := bsClear;
|
|
end;
|
|
|
|
destructor TTextEdit.Destroy;
|
|
begin
|
|
inherited;
|
|
FCanvas.Free;
|
|
end;
|
|
|
|
procedure TTextEdit.EraseBackground(DC: HDC);
|
|
begin
|
|
inherited EraseBackground(DC);
|
|
|
|
end;
|
|
|
|
procedure TTextEdit.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
inherited;
|
|
if Editor.PositionIndex <> SelStart then
|
|
begin
|
|
Editor.PositionIndex := Length(Text); //SelStart;
|
|
Editor.DrawFlashLine(nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TTextEdit.DoEnter;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TTextEdit.DoExit;
|
|
begin
|
|
inherited;
|
|
Editor.StopEdit;
|
|
end;
|
|
|
|
constructor TTextEditor.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
BorderStyle := bsNone;
|
|
Width := 1;
|
|
Height := 16;
|
|
Parent := TWinControl(AOwner);
|
|
FEdit := TTextEdit.Create(AOwner);
|
|
FEdit.Parent := Self;
|
|
FEdit.Left := 3;
|
|
FEdit.Top := 0;
|
|
FEdit.Editor := Self;
|
|
FEdit.Show;
|
|
FTimer := TIdleTimer.Create(AOwner);
|
|
FTimer.OnTimer := @DrawFlashLine;
|
|
FTimer.Interval := 500;
|
|
FTimer.Enabled := False;
|
|
FEdit.OnChange := @Changing;
|
|
Visible := False;
|
|
end;
|
|
|
|
destructor TTextEditor.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TTextEditor.EraseBackground(DC: HDC);
|
|
begin
|
|
inherited EraseBackground(DC);
|
|
|
|
end;
|
|
|
|
procedure TTextEditor.Paint;
|
|
begin
|
|
inherited Paint;
|
|
end;
|
|
|
|
procedure TTextEditor.DrawFlashLine(Sender: TObject);
|
|
var FlashLeft: integer; LeftText: string;
|
|
begin
|
|
flashnum := flashnum + 1;
|
|
if flashnum > 1000 then
|
|
flashnum := 0;
|
|
if flashnum mod 2 = 0 then
|
|
Canvas.Pen.Color := clWhite
|
|
else
|
|
Canvas.Pen.Color := clBlack;
|
|
FEdit.Font.Assign(IMGCanvas.Font);
|
|
Height := FEdit.Height - 3;
|
|
LeftText := Copy(FEdit.Text, 1, PositionIndex);
|
|
FlashLeft := StartX + IMGCanvas.TextWidth(LeftText);
|
|
Left := FlashLeft;
|
|
Top := StartY;
|
|
Canvas.Line(0, 0, 0, Height);
|
|
end;
|
|
|
|
procedure TTextEditor.StartEdit(ContainerX, ContainerY, IMGX, IMGY: integer);
|
|
begin
|
|
if IMGCanvas = nil then
|
|
Exit;
|
|
Left := ContainerX;
|
|
Top := ContainerY;
|
|
StartX := ContainerX;
|
|
StartY := ContainerY;
|
|
TextX := IMGX;
|
|
TextY := IMGY;
|
|
FEdit.Text := '';
|
|
Show;
|
|
FTimer.Enabled := True;
|
|
FEdit.SetFocus;
|
|
end;
|
|
|
|
procedure TTextEditor.StopEdit;
|
|
begin
|
|
FTimer.Enabled := False;
|
|
Hide;
|
|
end;
|
|
|
|
procedure TTextEditor.Changing(Sender: TObject);
|
|
var TextLeft: integer; LeftText, RightText: string;
|
|
begin
|
|
LeftText := Copy(FEdit.Text, 1, PositionIndex);
|
|
RightText := Copy(FEdit.Text, PositionIndex + 1, Length(FEdit.text));
|
|
TextLeft := TextX + IMGCanvas.TextWidth(LeftText);
|
|
if IMGCanvas = nil then
|
|
Exit;
|
|
IMGCanvas.Brush.Style := bsClear;
|
|
IMGCanvas.TextOut(TextLeft, TextY, RightText);
|
|
PositionIndex := Length(FEdit.Text);
|
|
end;
|
|
|
|
end.
|
|
|