262 lines
6.9 KiB
ObjectPascal
262 lines
6.9 KiB
ObjectPascal
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
|
|
|
{ Implementation of BGRABitmap for MSEgui }
|
|
unit BGRAMSEguiBitmap;
|
|
{ It should NOT be added to the **uses** clause. }
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, BGRAClasses, BGRAGraphics, BGRABitmapTypes, BGRADefaultBitmap,
|
|
BGRAText, msebitmap;
|
|
|
|
type
|
|
{ Implementation of TBGRABitmap for MSEgui }
|
|
TBGRAMSEguiBitmap = class(TBGRADefaultBitmap)
|
|
protected
|
|
procedure CopyDataToBitmap(AData: Pointer; AWidth,AHeight: integer; ALineOrder: TRawImageLineOrder; ABitmap: TBitmap);
|
|
procedure RebuildBitmap; override;
|
|
procedure DoLoadFromBitmap; override;
|
|
function CreateDefaultFontRenderer: TBGRACustomFontRenderer; override;
|
|
function LoadFromRawImage({%H-}ARawImage: TRawImage; {%H-}DefaultOpacity: byte;
|
|
{%H-}AlwaysReplaceAlpha: boolean=False; {%H-}RaiseErrorOnInvalidPixelFormat: boolean
|
|
=True): boolean; override;
|
|
procedure FreeBitmap; override;
|
|
procedure NotAvailable;
|
|
procedure InternalAssignBitmapPixels(ASource: TBitmap);
|
|
function GetCanvas: TCanvas; override;
|
|
public
|
|
procedure Assign(ASource: TPersistent); override;
|
|
procedure AssignToBitmap(ADestination: TBitmap);
|
|
destructor Destroy; override;
|
|
procedure GetImageFromCanvas({%H-}CanvasSource: TCanvas; {%H-}x, {%H-}y: integer); override; //not available
|
|
procedure DataDrawTransparent({%H-}ACanvas: TCanvas; {%H-}Rect: TRect; {%H-}AData: Pointer;
|
|
{%H-}ALineOrder: TRawImageLineOrder; {%H-}AWidth, {%H-}AHeight: integer); override;
|
|
procedure DataDrawOpaque({%H-}ACanvas: TCanvas; {%H-}Rect: TRect; {%H-}AData: Pointer;
|
|
{%H-}ALineOrder: TRawImageLineOrder; {%H-}AWidth, {%H-}AHeight: integer); override;
|
|
procedure TakeScreenshot({%H-}ARect: TRect); override; //not available
|
|
procedure TakeScreenshotOfPrimaryMonitor; override; //not available
|
|
procedure LoadFromDevice({%H-}DC: HDC); override; //not available
|
|
procedure LoadFromDevice({%H-}DC: HDC; {%H-}ARect: TRect); override; //not available
|
|
end;
|
|
|
|
type
|
|
{ Tracker of bitmap changes }
|
|
TBitmapTracker = class(TMaskedBitmap)
|
|
protected
|
|
FUser: TBGRADefaultBitmap;
|
|
procedure DoChange; override;
|
|
public
|
|
constructor Create(AUser: TBGRADefaultBitmap); overload;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses msegraphics, msegraphutils, math;
|
|
|
|
{ TBitmapTracker }
|
|
|
|
constructor TBitmapTracker.Create(AUser: TBGRADefaultBitmap);
|
|
begin
|
|
FUser := AUser;
|
|
inherited Create(bmk_rgb);
|
|
end;
|
|
|
|
procedure TBitmapTracker.DoChange;
|
|
begin
|
|
if FUser <> nil then
|
|
FUser.NotifyBitmapChange;
|
|
inherited DoChange;
|
|
end;
|
|
|
|
{ TBGRAMSEguiBitmap }
|
|
|
|
procedure TBGRAMSEguiBitmap.CopyDataToBitmap(AData: Pointer; AWidth,AHeight: integer; ALineOrder: TRawImageLineOrder; ABitmap: TBitmap);
|
|
var
|
|
ppix: PLongword;
|
|
pbmp: PLongword;
|
|
pmask: PByte;
|
|
x,y,yBmp : integer;
|
|
setMask: boolean;
|
|
begin
|
|
ABitmap.Size := Size(AWidth, AHeight);
|
|
ppix := AData;
|
|
pmask := nil;
|
|
if ABitmap is TMaskedBitmap then
|
|
begin
|
|
setMask := true;
|
|
TMaskedBitmap(ABitmap).Masked := true;
|
|
TMaskedBitmap(ABitmap).MaskKind := bmk_gray;
|
|
end else
|
|
setMask := false;
|
|
for y := 0 to Height-1 do
|
|
begin
|
|
if ALineOrder = riloTopToBottom then
|
|
yBmp := y else yBmp := Height-1-y;
|
|
pbmp := ABitmap.Scanline[yBmp];
|
|
if setMask then pmask := TMaskedBitmap(ABitmap).Mask.Scanline[yBmp];
|
|
for x := 0 to Width-1 do
|
|
begin
|
|
pbmp^ := ppix^ and $ffffff;
|
|
if setMask then
|
|
begin
|
|
pmask^ := ppix^ shr 24;
|
|
inc(pmask);
|
|
end;
|
|
inc(ppix);
|
|
inc(pbmp);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.RebuildBitmap;
|
|
begin
|
|
if FBitmap = nil then
|
|
FBitmap := TBitmapTracker.Create(self);
|
|
|
|
CopyDataToBitmap(Data, Width, Height, LineOrder, FBitmap);
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.InternalAssignBitmapPixels(ASource: TBitmap);
|
|
var
|
|
ppix,pbmp: PLongword;
|
|
pmask: PByte;
|
|
getMask: boolean;
|
|
x,y,wm1: integer;
|
|
begin
|
|
if ASource is TMaskedBitmap then
|
|
getMask := TMaskedBitmap(ASource).Masked
|
|
else getMask := false;
|
|
wm1 := min(Width-1, ASource.Width-1);
|
|
for y := 0 to min(Height-1, ASource.Height-1) do
|
|
begin
|
|
ppix := plongword(GetScanlineFast(y));
|
|
pbmp := ASource.Scanline[y];
|
|
if getMask then pmask := TMaskedBitmap(ASource).Mask.Scanline[y];
|
|
for x := 0 to wm1 do
|
|
begin
|
|
if getMask then
|
|
begin
|
|
ppix^ := (pbmp^ and $ffffff) or (pmask^ shl 24);
|
|
inc(pmask);
|
|
end else
|
|
ppix^ := (pbmp^ and $ffffff) or $ff000000;
|
|
inc(ppix);
|
|
inc(pbmp);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TBGRAMSEguiBitmap.GetCanvas: TCanvas;
|
|
begin
|
|
result := inherited GetCanvas;
|
|
NotifyBitmapChange;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.Assign(ASource: TPersistent);
|
|
var bmp: TBitmap;
|
|
begin
|
|
if ASource is TBitmap then
|
|
begin
|
|
bmp := TBitmap(ASource);
|
|
SetSize(bmp.Width, bmp.Height);
|
|
InternalAssignBitmapPixels(bmp);
|
|
InvalidateBitmap;
|
|
end else
|
|
inherited Assign(ASource);
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.AssignToBitmap(ADestination: TBitmap);
|
|
begin
|
|
ADestination.Assign(Bitmap);
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.DoLoadFromBitmap;
|
|
begin
|
|
if Assigned(FBitmap) then
|
|
InternalAssignBitmapPixels(FBitmap);
|
|
end;
|
|
|
|
function TBGRAMSEguiBitmap.CreateDefaultFontRenderer: TBGRACustomFontRenderer;
|
|
begin
|
|
result := TMSEFontRenderer.Create;
|
|
end;
|
|
|
|
function TBGRAMSEguiBitmap.LoadFromRawImage(ARawImage: TRawImage;
|
|
DefaultOpacity: byte; AlwaysReplaceAlpha: boolean;
|
|
RaiseErrorOnInvalidPixelFormat: boolean): boolean;
|
|
begin
|
|
self.Assign(ARawImage);
|
|
result := true;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.FreeBitmap;
|
|
begin
|
|
FreeAndNil(FBitmap);
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.NotAvailable;
|
|
begin
|
|
raise exception.Create('Function not available with MSEgui');
|
|
end;
|
|
|
|
destructor TBGRAMSEguiBitmap.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.GetImageFromCanvas(CanvasSource: TCanvas; x,
|
|
y: integer);
|
|
begin
|
|
(Bitmap as TMaskedBitmap).Masked := false;
|
|
Bitmap.Canvas.CopyArea(CanvasSource, MakeRect(x,y,Bitmap.Width,Bitmap.Height),
|
|
Point(0,0));
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.DataDrawTransparent(ACanvas: TCanvas; Rect: TRect;
|
|
AData: Pointer; ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer);
|
|
var
|
|
bmp: TMaskedBitmap;
|
|
begin
|
|
bmp := TMaskedBitmap.Create(bmk_rgb);
|
|
CopyDataToBitmap(Data, Width, Height, ALineOrder, bmp);
|
|
bmp.Paint(ACanvas, Rect);
|
|
bmp.Free;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.DataDrawOpaque(ACanvas: TCanvas; Rect: TRect;
|
|
AData: Pointer; ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer);
|
|
var
|
|
bmp: TBitmap;
|
|
begin
|
|
bmp := TBitmap.Create(bmk_rgb);
|
|
CopyDataToBitmap(AData, AWidth, AHeight, ALineOrder, bmp);
|
|
bmp.Paint(ACanvas, Rect);
|
|
bmp.Free;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.TakeScreenshot(ARect: TRect);
|
|
begin
|
|
NotAvailable;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.TakeScreenshotOfPrimaryMonitor;
|
|
begin
|
|
NotAvailable;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.LoadFromDevice(DC: HDC);
|
|
begin
|
|
NotAvailable;
|
|
end;
|
|
|
|
procedure TBGRAMSEguiBitmap.LoadFromDevice(DC: HDC; ARect: TRect);
|
|
begin
|
|
NotAvailable;
|
|
end;
|
|
|
|
end.
|
|
|