297 lines
7.6 KiB
ObjectPascal
297 lines
7.6 KiB
ObjectPascal
|
|
||
|
{******************************************}
|
||
|
{ }
|
||
|
{ FastReport VCL }
|
||
|
{ Graphic routines }
|
||
|
{ }
|
||
|
{ Copyright (c) 1998-2021 }
|
||
|
{ by Fast Reports Inc. }
|
||
|
{ }
|
||
|
{******************************************}
|
||
|
|
||
|
unit frxMetafileGraphics;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$I frx.inc}
|
||
|
|
||
|
uses
|
||
|
SysUtils,
|
||
|
{$IFNDEF FPC}
|
||
|
Windows, Messages,
|
||
|
{$ELSE}
|
||
|
LazHelper,
|
||
|
{$ENDIF}
|
||
|
Classes, Graphics, frxPictureGraphics;
|
||
|
|
||
|
const
|
||
|
frxWMFFileFormat = 1;
|
||
|
frxEMFFileFormat = 2;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses frxUtils;
|
||
|
|
||
|
type
|
||
|
TfrxBaseMetafileGraphicFormat = class(TfrxCustomVectorGraphicFormat)
|
||
|
protected
|
||
|
class function GetCanvasHelperClass: TfrxGraphicCanvasHelperClass; override;
|
||
|
public
|
||
|
class function ConvertFrom(Graphic: TGraphic; DestPixelFormat: TPixelFormat; DestQuality: Integer = 100): TGraphic; override;
|
||
|
class function CreateNew(Width: Integer; Height: Integer; PixelFormat: TPixelFormat; Transparent: Boolean; Quality: Integer = 100): TGraphic; override;
|
||
|
class function GetGraphicClass: TGraphicClass; override;
|
||
|
class function GetGraphicProps(Graphic: TGraphic): TfrxGraphicProps; override;
|
||
|
end;
|
||
|
|
||
|
|
||
|
TfrxMetaCanvasHelper = class(TfrxGraphicCanvasHelper)
|
||
|
private
|
||
|
FCanvas: TCanvas;
|
||
|
protected
|
||
|
function GetCanvas: TCanvas; override;
|
||
|
public
|
||
|
destructor Destroy; override;
|
||
|
procedure ReleaseCanvas; override;
|
||
|
end;
|
||
|
|
||
|
TfrxWMFGraphicFormat = class(TfrxBaseMetafileGraphicFormat)
|
||
|
public
|
||
|
class function GetGraphicMime: String; override;
|
||
|
class function GetGraphicName: String; override;
|
||
|
class function GetGraphicExt: String; override;
|
||
|
class function GetGraphicConst: Integer; override;
|
||
|
class function IsSupportedFormat(const Stream: TStream): Boolean; override;
|
||
|
end;
|
||
|
|
||
|
TfrxEMFGraphicFormat = class(TfrxBaseMetafileGraphicFormat)
|
||
|
public
|
||
|
class function CreateNew(Width: Integer; Height: Integer; PixelFormat: TPixelFormat; Transparent: Boolean; Quality: Integer = 100): TGraphic; override;
|
||
|
class function GetGraphicMime: String; override;
|
||
|
class function GetGraphicName: String; override;
|
||
|
class function GetGraphicExt: String; override;
|
||
|
class function GetGraphicConst: Integer; override;
|
||
|
class function IsSupportedFormat(const Stream: TStream): Boolean; override;
|
||
|
end;
|
||
|
|
||
|
TfrxFREMFGraphicFormat = class(TfrxEMFGraphicFormat)
|
||
|
public
|
||
|
class function GetGraphicName: String; override;
|
||
|
class function GetGraphicClass: TGraphicClass; override;
|
||
|
end;
|
||
|
|
||
|
FR_SMALL_RECT = record
|
||
|
Left: ShortInt;
|
||
|
Top: ShortInt;
|
||
|
Right: ShortInt;
|
||
|
Bottom: ShortInt;
|
||
|
end;
|
||
|
TSmallRect = FR_SMALL_RECT;
|
||
|
|
||
|
TMetafileHeader = packed record
|
||
|
Key: Longint;
|
||
|
Handle: SmallInt;
|
||
|
Box: TSmallRect;
|
||
|
Inch: Word;
|
||
|
Reserved: Longint;
|
||
|
CheckSum: Word;
|
||
|
end;
|
||
|
|
||
|
THackGraphic = class(TGraphic);
|
||
|
|
||
|
{ TfrxWMFGraphicFormat }
|
||
|
|
||
|
class function TfrxWMFGraphicFormat.GetGraphicConst: Integer;
|
||
|
begin
|
||
|
Result := frxWMFFileFormat;
|
||
|
end;
|
||
|
|
||
|
class function TfrxWMFGraphicFormat.GetGraphicExt: String;
|
||
|
begin
|
||
|
Result := '.wmf';
|
||
|
end;
|
||
|
|
||
|
class function TfrxWMFGraphicFormat.GetGraphicMime: String;
|
||
|
begin
|
||
|
Result := 'image/metafile';
|
||
|
end;
|
||
|
|
||
|
class function TfrxWMFGraphicFormat.GetGraphicName: String;
|
||
|
begin
|
||
|
Result := 'WMF';
|
||
|
end;
|
||
|
|
||
|
class function TfrxWMFGraphicFormat.IsSupportedFormat(
|
||
|
const Stream: TStream): Boolean;
|
||
|
const
|
||
|
WMFKey = Integer($9AC6CDD7);
|
||
|
WMFWord = $CDD7;
|
||
|
var
|
||
|
WMFHeader: TMetafileHeader;
|
||
|
pos: Integer;
|
||
|
begin
|
||
|
Result := False;
|
||
|
if (Stream.Size - Stream.Position) >= SizeOf(WMFHeader) then
|
||
|
begin
|
||
|
pos := Stream.Position;
|
||
|
Stream.ReadBuffer(WMFHeader, SizeOf(WMFHeader));
|
||
|
Stream.Position := pos;
|
||
|
if WMFHeader.Key = WMFKEY then
|
||
|
Result := True;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
{ TfrxEMFGraphicFormat }
|
||
|
|
||
|
class function TfrxEMFGraphicFormat.CreateNew(Width, Height: Integer;
|
||
|
PixelFormat: TPixelFormat; Transparent: Boolean; Quality: Integer): TGraphic;
|
||
|
begin
|
||
|
Result := inherited CreateNew(Width, Height, PixelFormat, Transparent, Quality);
|
||
|
TMetafile(Result).Enhanced := True;
|
||
|
end;
|
||
|
|
||
|
class function TfrxEMFGraphicFormat.GetGraphicConst: Integer;
|
||
|
begin
|
||
|
Result := frxEMFFileFormat;
|
||
|
end;
|
||
|
|
||
|
class function TfrxEMFGraphicFormat.GetGraphicExt: String;
|
||
|
begin
|
||
|
Result := '.emf';
|
||
|
end;
|
||
|
|
||
|
class function TfrxEMFGraphicFormat.GetGraphicMime: String;
|
||
|
begin
|
||
|
Result := 'image/metafile';
|
||
|
end;
|
||
|
|
||
|
class function TfrxEMFGraphicFormat.GetGraphicName: String;
|
||
|
begin
|
||
|
Result := 'EMF';
|
||
|
end;
|
||
|
|
||
|
class function TfrxEMFGraphicFormat.IsSupportedFormat(
|
||
|
const Stream: TStream): Boolean;
|
||
|
var
|
||
|
EMFHeader: TEnhMetaHeader;
|
||
|
pos: Integer;
|
||
|
begin
|
||
|
Result := False;
|
||
|
if (Stream.Size - Stream.Position) >= SizeOf(EMFHeader) then
|
||
|
begin
|
||
|
pos := Stream.Position;
|
||
|
Stream.ReadBuffer(EMFHeader, SizeOf(EMFHeader));
|
||
|
Stream.Position := pos;
|
||
|
if EMFHeader.dSignature = ENHMETA_SIGNATURE then
|
||
|
Result := True;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
{ TfrxBaseMetafileGraphicFormat }
|
||
|
|
||
|
class function TfrxBaseMetafileGraphicFormat.ConvertFrom(Graphic: TGraphic;
|
||
|
DestPixelFormat: TPixelFormat; DestQuality: Integer): TGraphic;
|
||
|
var
|
||
|
GHelper: TfrxCustomGraphicFormatClass;
|
||
|
Bitmap: TBitmap;
|
||
|
MetaF: TMetafile absolute Result;
|
||
|
Canvas: TMetafileCanvas;
|
||
|
begin
|
||
|
Result := CreateNew(Graphic.Width, Graphic.Height, DestPixelFormat, True, DestQuality);
|
||
|
if Graphic is TMetafile then
|
||
|
Result.Assign(Graphic)
|
||
|
else
|
||
|
begin
|
||
|
GHelper := GetGraphicFormats.FindByGraphic(TGraphicClass(Graphic.ClassType));
|
||
|
if Assigned(GHelper) then
|
||
|
begin
|
||
|
Bitmap := TBitmap(GHelper.ConvertToBitmap(Graphic, DestPixelFormat));
|
||
|
Canvas := TMetafileCanvas.Create(MetaF, 0);
|
||
|
Canvas.Lock;
|
||
|
try
|
||
|
Canvas.Draw(0, 0, Bitmap);
|
||
|
finally
|
||
|
Canvas.Unlock;
|
||
|
Canvas.Free;
|
||
|
Bitmap.Free;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
class function TfrxBaseMetafileGraphicFormat.CreateNew(Width, Height: Integer;
|
||
|
PixelFormat: TPixelFormat; Transparent: Boolean; Quality: Integer): TGraphic;
|
||
|
begin
|
||
|
Result := GetGraphicClass.Create;
|
||
|
Result.Width := Width;
|
||
|
Result.Height := Height;
|
||
|
end;
|
||
|
|
||
|
class function TfrxBaseMetafileGraphicFormat.GetCanvasHelperClass: TfrxGraphicCanvasHelperClass;
|
||
|
begin
|
||
|
Result := TfrxMetaCanvasHelper;
|
||
|
end;
|
||
|
|
||
|
class function TfrxBaseMetafileGraphicFormat.GetGraphicClass: TGraphicClass;
|
||
|
begin
|
||
|
Result := TMetafile;
|
||
|
end;
|
||
|
|
||
|
class function TfrxBaseMetafileGraphicFormat.GetGraphicProps(
|
||
|
Graphic: TGraphic): TfrxGraphicProps;
|
||
|
var
|
||
|
Metafile: TMetafile absolute Graphic;
|
||
|
begin
|
||
|
Result.HasAlpha := False;
|
||
|
Result.Transparent := Metafile.Transparent;
|
||
|
Result.TransparentColor := clNone;
|
||
|
Result.Quality := 100;
|
||
|
Result.PixelFormat := pfDevice;
|
||
|
end;
|
||
|
|
||
|
{ TfrxMetaCanvasHelper }
|
||
|
|
||
|
destructor TfrxMetaCanvasHelper.Destroy;
|
||
|
begin
|
||
|
ReleaseCanvas;
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
function TfrxMetaCanvasHelper.GetCanvas: TCanvas;
|
||
|
begin
|
||
|
if not Assigned(FCanvas) then
|
||
|
FCanvas := TMetafileCanvas.Create(TMetafile(FGraphic), 0);
|
||
|
Result := FCanvas;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxMetaCanvasHelper.ReleaseCanvas;
|
||
|
begin
|
||
|
FreeAndNil(FCanvas);
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
{ TfrxFREMFGraphicFormat }
|
||
|
|
||
|
class function TfrxFREMFGraphicFormat.GetGraphicClass: TGraphicClass;
|
||
|
begin
|
||
|
Result := TfrxMetafile;
|
||
|
end;
|
||
|
|
||
|
class function TfrxFREMFGraphicFormat.GetGraphicName: String;
|
||
|
begin
|
||
|
Result := 'FREMF';
|
||
|
end;
|
||
|
|
||
|
initialization
|
||
|
frxDefaultMetaCanvasClass := TMetafileCanvas;
|
||
|
GetGraphicFormats.RegisterFormat(TfrxWMFGraphicFormat);
|
||
|
GetGraphicFormats.RegisterFormat(TfrxEMFGraphicFormat);
|
||
|
GetGraphicFormats.RegisterFormat(TfrxFREMFGraphicFormat);
|
||
|
|
||
|
finalization
|
||
|
frxDefaultMetaCanvasClass := nil;
|
||
|
GetGraphicFormats.UnregisterFormat(TfrxEMFGraphicFormat);
|
||
|
GetGraphicFormats.UnregisterFormat(TfrxWMFGraphicFormat);
|
||
|
GetGraphicFormats.UnregisterFormat(TfrxFREMFGraphicFormat);
|
||
|
|
||
|
end.
|