FastReport_2022_VCL/LibD28/frxVectorCanvas.pas
2024-01-01 16:13:08 +01:00

231 lines
6.1 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport VCL }
{ EMF to SVG Export }
{ }
{ Copyright (c) 1998-2021 }
{ by Fast Reports Inc. }
{ }
{******************************************}
unit frxVectorCanvas;
interface
uses
Contnrs,
{$IFNDEF FPC}
Windows,
{$ELSE}
LCLType, LCLIntf, LCLProc,
{$ENDIF}
Classes, Types, Graphics;
{$I frx.inc}
type
TVectorCanvas = class(TObjectList)
public
constructor Create;
{$IFNDEF FPC}
procedure ExtTextOutW(X, Y: Integer; Options: Longint; Rect: PRect;
Str: Pointer {PWideStr}; aCount: Longint; Dx: PInteger);
procedure ExtTextOutA(X, Y: Integer; Options: Longint; Rect: PRect;
Str: Pointer {PAnsiStr}; aCount: Longint; Dx: PInteger);
{$ELSE}
procedure ExtTextOut(X, Y: Integer; Options: Longint; Rect: PRect;
Str: PChar; aCount: Longint; Dx: PInteger; Font: TFont);
{$ENDIF}
end;
TCharacterDistance = array of Integer;
// https://docs.microsoft.com/ru-ru/windows/desktop/api/wingdi/nf-wingdi-exttextoutw
// https://docs.microsoft.com/ru-ru/windows/desktop/api/wingdi/nf-wingdi-exttextouta
TVector_ExtTextOut = class
private
FX: Integer;
FY: Integer;
FOptions: Longint;
FRect: TRect;
FDx: TCharacterDistance;
FStr: {$IFDEF FPCUNICODE}String{$ELSE}WideString{$ENDIF};
public
constructor Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
ACount: Longint; ADx: PInteger);
destructor Destroy; override;
function AsString: String;
function TextLength: Integer;
property X: Integer read FX;
property Y: Integer read FY;
property Options: Longint read FOptions;
property Rect: TRect read FRect;
property Dx: TCharacterDistance read FDx;
property Str: {$IFDEF FPCUNICODE}String{$ELSE}WideString{$ENDIF} read FStr;
end;
{$IFNDEF FPC}
TVector_ExtTextOutW = class (TVector_ExtTextOut)
public
constructor Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
AStr: Pointer {PWideStr}; ACount: Longint; ADx: PInteger);
end;
TVector_ExtTextOutA = class (TVector_ExtTextOut)
public
constructor Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
AStr: Pointer {PAnsiStr}; ACount: Longint; ADx: PInteger);
end;
{$ELSE}
TLazVector_ExtTextOut = class (TVector_ExtTextOut)
private
FFont: TFont;
public
constructor Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
AStr: PChar; ACount: Longint; ADx: PInteger; AFont: TFont);
destructor Destroy; override;
property Font: TFont read FFont;
end;
{$ENDIF}
function isFRExtTextOut(VCO: TObject): Boolean;
implementation
uses
SysUtils, frxPlatformServices;
{ TVectorCanvas }
constructor TVectorCanvas.Create;
begin
inherited Create;
OwnsObjects := True;
end;
{$IFNDEF FPC}
procedure TVectorCanvas.ExtTextOutA(X, Y: Integer; Options: Longint; Rect: PRect;
Str: Pointer {PAnsiStr}; aCount: Longint; Dx: PInteger);
begin
Add(TVector_ExtTextOutA.Create(X, Y, Options, Rect, Str, aCount, Dx));
end;
procedure TVectorCanvas.ExtTextOutW(X, Y: Integer; Options: Longint; Rect: PRect;
Str: Pointer {PWideStr}; aCount: Longint; Dx: PInteger);
begin
Add(TVector_ExtTextOutW.Create(X, Y, Options, Rect, Str, aCount, Dx));
end;
{$ELSE}
procedure TVectorCanvas.ExtTextOut(X, Y: Integer; Options: Longint; Rect: PRect;
Str: PChar; aCount: Longint; Dx: PInteger; Font: TFont);
begin
Add(TLazVector_ExtTextOut.Create(X, Y, Options, Rect, Str, aCount, Dx, Font));
end;
{$ENDIF}
{ TVector_ExtTextOut }
function TVector_ExtTextOut.AsString: String;
var
st: String;
i: Integer;
begin
st := '';
if Dx <> nil then
for i := 0 to High(Dx) do
st := st + ' ' + IntToStr(Dx[i]);
Result := 'ExtTextOutW' +
#13#10' X, Y, Options: ' + IntToStr(X) + ', ' + IntToStr(Y) + ', ' + IntToStr(Options) +
#13#10' Rect: ' + IntToStr(Rect.Left) + ' ' + IntToStr(Rect.Top) + ' ' + IntToStr(Rect.Right) + ' ' + IntToStr(Rect.Bottom) +
#13#10' Text: ' + Str +
#13#10' Dx:' + st;
end;
constructor TVector_ExtTextOut.Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
ACount: Longint; ADx: PInteger);
begin
FX := AX;
FY := AY;
FOptions := AOptions;
FRect := ARect^;
if Assigned(ADx) then
begin
SetLength(FDx, ACount);
Move(ADx^, FDx[0], ACount * SizeOf(ADx^));
end
else
FDx := nil;
end;
destructor TVector_ExtTextOut.Destroy;
begin
SetLength(FDx, 0);
inherited;
end;
function TVector_ExtTextOut.TextLength: Integer;
var
i: Integer;
begin
Result := 0;
if Dx <> nil then
for i := 0 to High(Dx) do
Result := Result + Dx[i];
end;
{$IFNDEF FPC}
{ TVector_ExtTextOutW }
constructor TVector_ExtTextOutW.Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
AStr: Pointer {PWideStr}; ACount: Longint; ADx: PInteger);
begin
inherited Create (AX, AY, AOptions, ARect, ACount, ADx);
SetLength(FStr, ACount);
Move(AStr^, FStr[1], ACount * SizeOf(WideChar));
end;
{ TVector_ExtTextOutA }
constructor TVector_ExtTextOutA.Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
AStr: Pointer {PAnsiStr}; ACount: Longint; ADx: PInteger);
var
st: AnsiString;
begin
inherited Create (AX, AY, AOptions, ARect, ACount, ADx);
SetLength(st, ACount);
Move(AStr^, st[1], ACount * SizeOf(AnsiChar));
FStr := WideString(st);
end;
{$ELSE}
constructor TLazVector_ExtTextOut.Create(AX, AY: Integer; AOptions: Longint; ARect: PRect;
AStr: PChar; ACount: Longint; ADx: PInteger; AFont: TFont);
begin
SetLength(FStr, ACount);
Move(AStr^, FStr[1], ACount * SizeOf({$IFDEF FPCUNICODE}Char{$ELSE}PWideChar{$ENDIF}));
FFont := TFont.Create;
FFont.Assign(AFont);
inherited Create (AX, AY, AOptions, ARect, frxLength(FStr), ADx);
end;
destructor TLazVector_ExtTextOut.Destroy;
begin
FFont.Free;
end;
{$ENDIF}
function isFRExtTextOut(VCO: TObject): Boolean;
begin
{$IFNDEF FPC}
Result := (VCO is TVector_ExtTextOutW) or (VCO is TVector_ExtTextOutA);
{$ELSE}
Result := (VCO is TLazVector_ExtTextOut);
{$ENDIF}
end;
end.