
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9473 8e941d3f-bd1b-0410-a28a-d453659cc2b4
367 lines
9.4 KiB
ObjectPascal
367 lines
9.4 KiB
ObjectPascal
{ Default drawing engine based on LCL-only routines
|
|
Copyright (C) 2019 Werner Pamler (user wpat Lazarus forum https://forum.lazarus.freepascal.org)
|
|
|
|
License: modified LGPL with linking exception (like RTL, FCL and LCL)
|
|
|
|
See the file COPYING.modifiedLGPL.txt, included in the Lazarus distribution,
|
|
for details about the license.
|
|
|
|
See also: https://wiki.lazarus.freepascal.org/FPC_modified_LGPL
|
|
}
|
|
|
|
unit mvDE_LCL;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Graphics, Types, IntfGraphics, fpReadJPEG, fpReadPNG,
|
|
mvDrawingEngine, mvCache;
|
|
|
|
type
|
|
|
|
{ TLCLCacheItem }
|
|
|
|
TLCLCacheItem = class(TPictureCacheItem)
|
|
private
|
|
FImage: TCustomBitmap;
|
|
function GetImage: TCustomBitmap;
|
|
protected
|
|
function GetImageObject: TObject; override;
|
|
public
|
|
constructor Create(AStream: TStream); override;
|
|
destructor Destroy; override;
|
|
property Image: TCustomBitmap read GetImage;
|
|
end;
|
|
|
|
|
|
{ TMvLCLDrawingEngine }
|
|
|
|
TMvLCLDrawingEngine = class(TMvCustomDrawingEngine)
|
|
private
|
|
FBuffer: TBitmap;
|
|
protected
|
|
function GetBrushColor: TColor; override;
|
|
function GetBrushStyle: TBrushStyle; override;
|
|
function GetFontColor: TColor; override;
|
|
function GetFontName: String; override;
|
|
function GetFontSize: Integer; override;
|
|
function GetFontStyle: TFontStyles; override;
|
|
function GetPenColor: TColor; override;
|
|
function GetPenStyle: TPenstyle; override;
|
|
function GetPenWidth: Integer; override;
|
|
function GetOpacity: Single; override;
|
|
procedure SetOpacity({%H-}AValue: Single); override;
|
|
procedure SetBrushColor(AValue: TColor); override;
|
|
procedure SetBrushStyle(AValue: TBrushStyle); override;
|
|
procedure SetFontColor(AValue: TColor); override;
|
|
procedure SetFontName(AValue: String); override;
|
|
procedure SetFontSize(AValue: Integer); override;
|
|
procedure SetFontStyle(AValue: TFontStyles); override;
|
|
procedure SetPenColor(AValue: TColor); override;
|
|
procedure SetPenStyle(AValue: TPenStyle); override;
|
|
procedure SetPenWidth(AValue: Integer); override;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure CreateBuffer(AWidth, AHeight: Integer); override;
|
|
procedure DrawBitmap(X, Y: Integer; ABitmap: TCustomBitmap;
|
|
{%H-}UseAlphaChannel: Boolean); override;
|
|
procedure DrawCacheItem(X, Y: Integer; AImg: TPictureCacheItem;
|
|
{%H-}ADrawMode: TItemDrawMode = idmDraw; {%H-}AOpacity: Single = 1.0 ); override;
|
|
procedure DrawScaledCacheItem(DestRect, SrcRect: TRect; ASrcImg: TPictureCacheItem); override;
|
|
procedure Ellipse(X1, Y1, X2, Y2: Integer); override;
|
|
procedure FillPixels(X1, Y1, X2, Y2: Integer; AColor: TColor); override;
|
|
procedure FillRect(X1, Y1, X2, Y2: Integer); override;
|
|
procedure Line(X1, Y1, X2, Y2: Integer); override;
|
|
procedure Polyline(const Points: array of TPoint); override;
|
|
procedure Polygon(const Points: array of TPoint); override;
|
|
procedure PolyBezier(const Points: array of TPoint; Filled: Boolean = False;
|
|
Continuous: Boolean = True); override;
|
|
procedure PaintToCanvas(ACanvas: TCanvas; Origin: TPoint); override;
|
|
procedure Rectangle(X1, Y1, X2, Y2: Integer); override;
|
|
function SaveToImage(AClass: TRasterImageClass): TRasterImage; override;
|
|
function TextExtent(const AText: String): TSize; override;
|
|
procedure TextOut(X, Y: Integer; const AText: String); override;
|
|
function GetCacheItemClass: TPictureCacheItemClass; override;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
LCLType, FPImage, mvTypes;
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents(PALETTE_PAGE, [TMvLCLDrawingEngine]);
|
|
end;
|
|
|
|
{ TLCLCacheItem }
|
|
|
|
function TLCLCacheItem.GetImage: TCustomBitmap;
|
|
begin
|
|
Result := FImage;
|
|
end;
|
|
|
|
function TLCLCacheItem.GetImageObject: TObject;
|
|
begin
|
|
Result := FImage;
|
|
end;
|
|
|
|
constructor TLCLCacheItem.Create(AStream: TStream);
|
|
var
|
|
reader: TFPCustomImageReader;
|
|
begin
|
|
FImage := Nil;
|
|
reader := GetImageReader(AStream);
|
|
if reader is TFPReaderJPEG then
|
|
FImage := TJpegImage.Create
|
|
else
|
|
if reader is TFPReaderPNG then
|
|
FImage := TPortableNetworkGraphic.Create
|
|
else
|
|
raise EInvalidGraphic.Create('PNG/JPG expected.');
|
|
try
|
|
try
|
|
FImage.LoadFromStream(AStream);
|
|
except
|
|
FreeAndNil(FImage);
|
|
end;
|
|
finally
|
|
reader.Free;
|
|
end;
|
|
end;
|
|
|
|
destructor TLCLCacheItem.Destroy;
|
|
begin
|
|
FImage.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
|
|
{ TMvLCLDrawingEngine }
|
|
|
|
destructor TMvLCLDrawingEngine.Destroy;
|
|
begin
|
|
FBuffer.Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.CreateBuffer(AWidth, AHeight: Integer);
|
|
begin
|
|
FBuffer.Free;
|
|
FBuffer := TBitmap.Create;
|
|
FBuffer.PixelFormat := pf32Bit;
|
|
FBuffer.SetSize(AWidth, AHeight);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.DrawBitmap(X, Y: Integer; ABitmap: TCustomBitmap;
|
|
UseAlphaChannel: Boolean);
|
|
begin
|
|
FBuffer.Canvas.Draw(X, Y, ABitmap);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.DrawCacheItem(X, Y: Integer;
|
|
AImg: TPictureCacheItem; ADrawMode: TItemDrawMode; AOpacity: Single);
|
|
var
|
|
item: TLCLCacheItem;
|
|
begin
|
|
item := AImg as TLCLCacheItem;
|
|
FBuffer.Canvas.Draw(X, Y, item.Image);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.DrawScaledCacheItem(DestRect,
|
|
SrcRect: TRect; ASrcImg: TPictureCacheItem);
|
|
var
|
|
item: TLCLCacheItem;
|
|
begin
|
|
item := ASrcImg as TLCLCacheItem;
|
|
FBuffer.Canvas.CopyRect(DestRect, item.Image.Canvas, SrcRect);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.Ellipse(X1, Y1, X2, Y2: Integer);
|
|
begin
|
|
FBuffer.Canvas.Ellipse(X1,Y1, X2, Y2);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.FillPixels(X1, Y1, X2, Y2: Integer; AColor: TColor);
|
|
begin
|
|
if (X1 >= FBuffer.Width) or (X2 < 0) or (Y1 >= FBuffer.Height) or (Y2 < 0) then
|
|
exit;
|
|
|
|
if X1 < 0 then X1 := 0;
|
|
if Y1 < 0 then Y1 := 0;
|
|
if X2 >= FBuffer.Width then X2 := FBuffer.Width - 1;
|
|
if Y2 >= FBuffer.Height then Y2 := FBuffer.Height - 1;
|
|
|
|
FBuffer.Canvas.Brush.Color := AColor;
|
|
FBuffer.Canvas.FillRect(X1, Y1, X2, Y2);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.FillRect(X1, Y1, X2, Y2: Integer);
|
|
begin
|
|
FBuffer.Canvas.FillRect(X1,Y1, X2, Y2);
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetBrushColor: TColor;
|
|
begin
|
|
Result := FBuffer.Canvas.Brush.Color;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetBrushStyle: TBrushStyle;
|
|
begin
|
|
Result := FBuffer.Canvas.Brush.Style
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetCacheItemClass: TPictureCacheItemClass;
|
|
begin
|
|
Result := TLCLCacheItem;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetFontColor: TColor;
|
|
begin
|
|
Result := FBuffer.Canvas.Font.Color
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetFontName: String;
|
|
begin
|
|
Result := FBuffer.Canvas.Font.Name;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetFontSize: Integer;
|
|
begin
|
|
Result := FBuffer.Canvas.Font.Size;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetFontStyle: TFontStyles;
|
|
begin
|
|
Result := FBuffer.Canvas.Font.Style;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetPenColor: TColor;
|
|
begin
|
|
Result := FBuffer.Canvas.Pen.Color;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetPenStyle: TPenstyle;
|
|
begin
|
|
Result := FBuffer.Canvas.Pen.Style;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetPenWidth: Integer;
|
|
begin
|
|
Result := FBuffer.Canvas.Pen.Width;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.GetOpacity: Single;
|
|
begin
|
|
Result := 1.0;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetOpacity(AValue: Single);
|
|
begin
|
|
;// TODO
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.Line(X1, Y1, X2, Y2: Integer);
|
|
begin
|
|
FBuffer.Canvas.Line(X1, Y1, X2, Y2);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.Polyline(const Points: array of TPoint);
|
|
begin
|
|
FBuffer.Canvas.Polyline(Points);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.Polygon(const Points: array of TPoint);
|
|
begin
|
|
FBuffer.Canvas.Polygon(Points);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.PolyBezier(const Points: array of TPoint;
|
|
Filled: Boolean; Continuous: Boolean);
|
|
begin
|
|
FBuffer.Canvas.PolyBezier(Points, Filled, Continuous);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.PaintToCanvas(ACanvas: TCanvas; Origin: TPoint);
|
|
begin
|
|
ACanvas.Draw(Origin.X, Origin.Y, FBuffer);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.Rectangle(X1, Y1, X2, Y2: Integer);
|
|
begin
|
|
FBuffer.Canvas.Rectangle(X1,Y1, X2, Y2);
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.SaveToImage(AClass: TRasterImageClass): TRasterImage;
|
|
begin
|
|
Result := AClass.Create;
|
|
Result.Width := FBuffer.Width;
|
|
Result.Height := FBuffer.Height;
|
|
Result.Canvas.FillRect(0, 0, Result.Width, Result.Height);
|
|
Result.Canvas.Draw(0, 0, FBuffer);
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetBrushColor(AValue: TColor);
|
|
begin
|
|
FBuffer.Canvas.Brush.Color := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetBrushStyle(AValue: TBrushStyle);
|
|
begin
|
|
FBuffer.Canvas.Brush.Style := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetFontColor(AValue: TColor);
|
|
begin
|
|
FBuffer.Canvas.Font.Color := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetFontName(AValue: String);
|
|
begin
|
|
FBuffer.Canvas.Font.Name := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetFontSize(AValue: Integer);
|
|
begin
|
|
FBuffer.Canvas.Font.Size := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetFontStyle(AValue: TFontStyles);
|
|
begin
|
|
FBuffer.Canvas.Font.Style := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetPenColor(AValue: TColor);
|
|
begin
|
|
FBuffer.Canvas.Pen.Color := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetPenStyle(AValue: TPenStyle);
|
|
begin
|
|
FBuffer.Canvas.Pen.Style := AValue;
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.SetPenWidth(AValue: Integer);
|
|
begin
|
|
FBuffer.Canvas.Pen.Width := AValue;
|
|
end;
|
|
|
|
function TMvLCLDrawingEngine.TextExtent(const AText: String): TSize;
|
|
begin
|
|
Result := FBuffer.Canvas.TextExtent(AText)
|
|
end;
|
|
|
|
procedure TMvLCLDrawingEngine.TextOut(X, Y: Integer; const AText: String);
|
|
begin
|
|
if (AText <> '') then
|
|
FBuffer.Canvas.TextOut(X, Y, AText);
|
|
end;
|
|
|
|
end.
|
|
|