mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-12 10:20:49 +01:00
* made the rasterimage rawimage public
git-svn-id: trunk@15850 -
This commit is contained in:
parent
2b8097dfd9
commit
7b10f5086e
@ -1108,11 +1108,6 @@ type
|
|||||||
Handle is interface dependent.
|
Handle is interface dependent.
|
||||||
To access the raw data, see TLazIntfImage in IntfGraphics.pas }
|
To access the raw data, see TLazIntfImage in IntfGraphics.pas }
|
||||||
|
|
||||||
TBitmapInternalStateFlag = (
|
|
||||||
bmisCreatingCanvas
|
|
||||||
);
|
|
||||||
TBitmapInternalState = set of TBitmapInternalStateFlag;
|
|
||||||
|
|
||||||
{ TRasterImage }
|
{ TRasterImage }
|
||||||
|
|
||||||
TRasterImage = class(TGraphic)
|
TRasterImage = class(TGraphic)
|
||||||
@ -1120,7 +1115,10 @@ type
|
|||||||
FCanvas: TCanvas;
|
FCanvas: TCanvas;
|
||||||
FTransparentColor: TColor;
|
FTransparentColor: TColor;
|
||||||
FTransparentMode: TTransparentMode;
|
FTransparentMode: TTransparentMode;
|
||||||
FInternalState: TBitmapInternalState;
|
FUpdateCount: Integer;
|
||||||
|
FUpdateCanvasOnly: Boolean;
|
||||||
|
|
||||||
|
procedure CanvasChanging(Sender: TObject);
|
||||||
procedure CreateCanvas;
|
procedure CreateCanvas;
|
||||||
procedure CreateMask(AColor: TColor = clDefault);
|
procedure CreateMask(AColor: TColor = clDefault);
|
||||||
procedure FreeCanvasContext;
|
procedure FreeCanvasContext;
|
||||||
@ -1130,7 +1128,6 @@ type
|
|||||||
FSharedImage: TSharedRasterImage;
|
FSharedImage: TSharedRasterImage;
|
||||||
function CanShareImage(AClass: TSharedRasterImageClass): Boolean; virtual;
|
function CanShareImage(AClass: TSharedRasterImageClass): Boolean; virtual;
|
||||||
procedure Changed(Sender: TObject); override;
|
procedure Changed(Sender: TObject); override;
|
||||||
procedure Changing(Sender: TObject); virtual;
|
|
||||||
function CreateDefaultBitmapHandle(const ADesc: TRawImageDescription): HBITMAP; virtual; abstract;
|
function CreateDefaultBitmapHandle(const ADesc: TRawImageDescription): HBITMAP; virtual; abstract;
|
||||||
procedure Draw(DestCanvas: TCanvas; const DestRect: TRect); override;
|
procedure Draw(DestCanvas: TCanvas; const DestRect: TRect); override;
|
||||||
function GetEmpty: Boolean; override;
|
function GetEmpty: Boolean; override;
|
||||||
@ -1155,11 +1152,11 @@ type
|
|||||||
procedure SetBitmapHandle(AValue: HBITMAP);
|
procedure SetBitmapHandle(AValue: HBITMAP);
|
||||||
procedure SetMaskHandle(AValue: HBITMAP);
|
procedure SetMaskHandle(AValue: HBITMAP);
|
||||||
procedure UnshareImage(CopyContent: boolean); virtual; abstract;
|
procedure UnshareImage(CopyContent: boolean); virtual; abstract;
|
||||||
function UpdateHandles(ABitmap, AMask: HBITMAP): Boolean; virtual; abstract; // called when handles are created from rawimage (true whan handle changed)
|
function UpdateHandles(ABitmap, AMask: HBITMAP): Boolean; virtual; abstract; // called when handles are created from rawimage (true when handle changed)
|
||||||
procedure SaveStreamNeeded;
|
procedure SaveStreamNeeded;
|
||||||
procedure FreeSaveStream;
|
procedure FreeSaveStream;
|
||||||
procedure ReadData(Stream: TStream); override;
|
procedure ReadData(Stream: TStream); override;
|
||||||
procedure ReadStream(AStream: TMemoryStream; ASize: Longint); virtual; abstract; // loads imagedata into rawimage, this method shouldn't call changed.
|
procedure ReadStream(AStream: TMemoryStream; ASize: Longint); virtual; abstract; // loads imagedata into rawimage, this method shouldn't call changed().
|
||||||
procedure SetSize(AWidth, AHeight: integer); virtual; abstract;
|
procedure SetSize(AWidth, AHeight: integer); virtual; abstract;
|
||||||
procedure SetHandle(AValue: THandle); virtual;
|
procedure SetHandle(AValue: THandle); virtual;
|
||||||
procedure SetHeight(AHeight: Integer); override;
|
procedure SetHeight(AHeight: Integer); override;
|
||||||
@ -1173,6 +1170,8 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Assign(Source: TPersistent); override;
|
procedure Assign(Source: TPersistent); override;
|
||||||
procedure Clear; override;
|
procedure Clear; override;
|
||||||
|
procedure BeginUpdate(ACanvasOnly: Boolean = False);
|
||||||
|
procedure EndUpdate;
|
||||||
procedure FreeImage;
|
procedure FreeImage;
|
||||||
function BitmapHandleAllocated: boolean; virtual; abstract;
|
function BitmapHandleAllocated: boolean; virtual; abstract;
|
||||||
function MaskHandleAllocated: boolean; virtual; abstract;
|
function MaskHandleAllocated: boolean; virtual; abstract;
|
||||||
@ -1198,6 +1197,7 @@ type
|
|||||||
property BitmapHandle: HBITMAP read GetBitmapHandle write SetBitmapHandle;
|
property BitmapHandle: HBITMAP read GetBitmapHandle write SetBitmapHandle;
|
||||||
property MaskHandle: HBITMAP read GetMaskHandle write SetMaskHandle;
|
property MaskHandle: HBITMAP read GetMaskHandle write SetMaskHandle;
|
||||||
property PixelFormat: TPixelFormat read GetPixelFormat write SetPixelFormat default pfDevice;
|
property PixelFormat: TPixelFormat read GetPixelFormat write SetPixelFormat default pfDevice;
|
||||||
|
property RawImagePtr: PRawImage read GetRawImage; // be carefull with this, modify only within a begin/endupdate
|
||||||
// property ScanLine[Row: Integer]: Pointer; -> Use TLazIntfImage for such things
|
// property ScanLine[Row: Integer]: Pointer; -> Use TLazIntfImage for such things
|
||||||
property TransparentColor: TColor read FTransparentColor
|
property TransparentColor: TColor read FTransparentColor
|
||||||
write SetTransparentColor default clDefault;
|
write SetTransparentColor default clDefault;
|
||||||
|
|||||||
@ -27,6 +27,8 @@
|
|||||||
constructor TBitmapCanvas.Create(AImage: TRasterImage);
|
constructor TBitmapCanvas.Create(AImage: TRasterImage);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
|
// set FImage after inherited create to make sure that the inherited Create
|
||||||
|
// won't trigger a call to FImage
|
||||||
FImage := AImage;
|
FImage := AImage;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -47,25 +47,27 @@ begin
|
|||||||
FSharedImage := SrcImage.FSharedImage;
|
FSharedImage := SrcImage.FSharedImage;
|
||||||
FSharedImage.Reference;
|
FSharedImage.Reference;
|
||||||
|
|
||||||
// We only can share images of the same type.
|
// We only can share images of the same type and when neither we or source is updating
|
||||||
// Since we "share" it first, the unshare code will create a copy
|
// Since we "share" it first, the unshare code will create a copy
|
||||||
if not CanShareImage(SrcImage.GetSharedImageClass)
|
if (FUpdateCount > 0)
|
||||||
|
or (SrcImage.FUpdateCount > 0)
|
||||||
|
or not CanShareImage(SrcImage.GetSharedImageClass)
|
||||||
then begin
|
then begin
|
||||||
UnshareImage(True);
|
UnshareImage(True);
|
||||||
FreeSaveStream;
|
FreeSaveStream;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Changed(Self);
|
if FUpdateCount = 0
|
||||||
|
then Changed(Self);
|
||||||
|
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Source is TFPCustomImage
|
if Source is TFPCustomImage
|
||||||
then begin
|
then begin
|
||||||
// MWE: no need for a changeall, the sethandles will handle this
|
// todo: base on rawimage
|
||||||
// ChangingAll(Self);
|
|
||||||
|
|
||||||
IntfImage := TLazIntfImage.Create(0,0);
|
IntfImage := TLazIntfImage.Create(0,0);
|
||||||
try
|
try
|
||||||
if BitmapHandleAllocated
|
if BitmapHandleAllocated
|
||||||
@ -77,7 +79,8 @@ begin
|
|||||||
finally
|
finally
|
||||||
IntfImage.Free;
|
IntfImage.Free;
|
||||||
end;
|
end;
|
||||||
Changed(Self);
|
if FUpdateCount = 0
|
||||||
|
then Changed(Self);
|
||||||
|
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
@ -86,13 +89,31 @@ begin
|
|||||||
inherited Assign(Source);
|
inherited Assign(Source);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TRasterImage.BeginUpdate(ACanvasOnly: Boolean);
|
||||||
|
begin
|
||||||
|
if FUpdateCount = 0
|
||||||
|
then begin
|
||||||
|
UnshareImage(True);
|
||||||
|
FUpdateCanvasOnly := ACanvasOnly;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// if we are updating all, then requesting a canvas only won't change it
|
||||||
|
// if we are updating canvas only, then requesting all is an error
|
||||||
|
if FUpdateCanvasOnly and not ACanvasOnly
|
||||||
|
then raise EInvalidGraphicOperation.Create('cannot begin update all when canvas only update in progress');
|
||||||
|
end;
|
||||||
|
|
||||||
|
Inc(FUpdateCount);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.Clear;
|
procedure TRasterImage.Clear;
|
||||||
begin
|
begin
|
||||||
if not Empty then
|
if not Empty then
|
||||||
begin
|
begin
|
||||||
FreeSaveStream;
|
FreeSaveStream;
|
||||||
SetSize(0, 0);
|
SetSize(0, 0);
|
||||||
Changed(Self);
|
if FUpdateCount = 0
|
||||||
|
then Changed(Self);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -203,6 +224,20 @@ begin
|
|||||||
DestCanvas.Changed;
|
DestCanvas.Changed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TRasterImage.EndUpdate;
|
||||||
|
begin
|
||||||
|
if FUpdatecount = 0
|
||||||
|
then raise EInvalidGraphicOperation.Create('Endupdate while no update in progress');
|
||||||
|
|
||||||
|
Dec(FUpdatecount);
|
||||||
|
if FUpdatecount > 0 then Exit;
|
||||||
|
|
||||||
|
if not FUpdateCanvasOnly
|
||||||
|
then FreeCanvasContext;
|
||||||
|
FreeSaveStream;
|
||||||
|
Changed(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TRasterImage.Create;
|
constructor TRasterImage.Create;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
@ -236,16 +271,10 @@ end;
|
|||||||
procedure TRasterImage.CreateCanvas;
|
procedure TRasterImage.CreateCanvas;
|
||||||
begin
|
begin
|
||||||
if FCanvas <> nil then Exit;
|
if FCanvas <> nil then Exit;
|
||||||
if bmisCreatingCanvas in FInternalState then Exit;
|
|
||||||
|
|
||||||
Include(FInternalState, bmisCreatingCanvas);
|
FCanvas := TBitmapCanvas.Create(Self);
|
||||||
try
|
FCanvas.OnChanging := @CanvasChanging;
|
||||||
FCanvas := TBitmapCanvas.Create(Self);
|
FCanvas.OnChange := @Changed;
|
||||||
FCanvas.OnChanging := @Changing;
|
|
||||||
FCanvas.OnChange := @Changed;
|
|
||||||
finally
|
|
||||||
Exclude(FInternalState,bmisCreatingCanvas);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.FreeImage;
|
procedure TRasterImage.FreeImage;
|
||||||
@ -319,6 +348,8 @@ end;
|
|||||||
|
|
||||||
procedure TRasterImage.Changed(Sender: TObject);
|
procedure TRasterImage.Changed(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
|
if FUpdateCount > 0 then Exit;
|
||||||
|
|
||||||
//FMaskBitsValid := False;
|
//FMaskBitsValid := False;
|
||||||
if Sender = FCanvas
|
if Sender = FCanvas
|
||||||
then FreeSaveStream;
|
then FreeSaveStream;
|
||||||
@ -326,15 +357,14 @@ begin
|
|||||||
inherited Changed(Sender);
|
inherited Changed(Sender);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.Changing(Sender: TObject);
|
procedure TRasterImage.CanvasChanging(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
// called before the bitmap is modified
|
if FUpdateCount > 0 then Exit;
|
||||||
|
|
||||||
|
// called before the canvas is modified
|
||||||
// -> make sure the handle is unshared (otherwise the modifications will also
|
// -> make sure the handle is unshared (otherwise the modifications will also
|
||||||
// modify all copies)
|
// modify all copies)
|
||||||
// -> When canvas changing: Savestream will be freed when changed (so it can
|
// -> Savestream will be freed when changed (so it can be loaded by canvas)
|
||||||
// be loaded by canvas)
|
|
||||||
if Sender <> FCanvas
|
|
||||||
then FreeSaveStream;
|
|
||||||
UnshareImage(True);
|
UnshareImage(True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -380,7 +410,8 @@ begin
|
|||||||
// if something went wrong, free the workstream
|
// if something went wrong, free the workstream
|
||||||
WorkStream.Free;
|
WorkStream.Free;
|
||||||
end;
|
end;
|
||||||
Changed(Self);
|
if FUpdateCount = 0
|
||||||
|
then Changed(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.GetSupportedSourceMimeTypes(List: TStrings);
|
procedure TRasterImage.GetSupportedSourceMimeTypes(List: TStrings);
|
||||||
@ -509,7 +540,8 @@ begin
|
|||||||
FreeCanvasContext;
|
FreeCanvasContext;
|
||||||
UnshareImage(False);
|
UnshareImage(False);
|
||||||
FSharedImage.FHandle := AValue;
|
FSharedImage.FHandle := AValue;
|
||||||
Changed(Self);
|
if FUpdateCount = 0
|
||||||
|
then Changed(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.SetMaskHandle(AValue: HBITMAP);
|
procedure TRasterImage.SetMaskHandle(AValue: HBITMAP);
|
||||||
@ -546,6 +578,10 @@ procedure TRasterImage.SaveStreamNeeded;
|
|||||||
var
|
var
|
||||||
WorkStream: TMemoryStream;
|
WorkStream: TMemoryStream;
|
||||||
begin
|
begin
|
||||||
|
if FUpdateCount > 0
|
||||||
|
then raise EInvalidGraphicOperation.Create('Cannot save image wile update in progress');
|
||||||
|
|
||||||
|
|
||||||
if FSharedImage.SaveStream <> nil then Exit;
|
if FSharedImage.SaveStream <> nil then Exit;
|
||||||
|
|
||||||
WorkStream := TMemoryStream.Create;
|
WorkStream := TMemoryStream.Create;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user