FastReport_FMX_2.8.12/Source/FMX.frxBarcode.pas
2024-07-06 22:41:12 +02:00

303 lines
7.7 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport FMX v1.0 }
{ Barcode Add-in object }
{ }
{ Copyright (c) 1998-2013 }
{ by Alexander Tzyganenko, }
{ Fast Reports Inc. }
{ }
{******************************************}
unit FMX.frxBarcode;
interface
{$I fmx.inc}
{$I frx.inc}
{$I fmx.inc}
uses
System.SysUtils, System.Classes, System.Types, System.UIConsts, FMX.Types,
FMX.Objects, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Menus, FMX.frxBarcod,
FMX.frxClass, System.Variants
{$IFDEF DELPHI19}
, FMX.Graphics
{$ENDIF}
{$IFDEF DELPHI20}
, System.Math.Vectors
{$ENDIF}
{$IFDEF DELPHI28}
, FMX.BaseTypeAliases, FMX.FormTypeAliases
{$ENDIF};
type
{$I frxFMX_PlatformsAttribute.inc}
TfrxBarCodeObject = class(TComponent); // fake component
TfrxBarCodeView = class(TfrxView)
private
FBarCode: TfrxBarCode;
FBarType: TfrxBarcodeType;
FCalcCheckSum: Boolean;
FExpression: String;
FHAlign: TfrxHAlign;
FRotation: Integer;
FShowText: Boolean;
FText: String;
FWideBarRatio: Double;
FZoom: Double;
procedure BcFontChanged(Sender: TObject);
procedure SetRotation(const Value: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); override;
procedure GetData; override;
class function GetDescription: String; override;
function GetRealBounds: TfrxRect; override;
property BarCode: TfrxBarCode read FBarCode;
published
property BarType: TfrxBarcodeType read FBarType write FBarType;
property BrushStyle;
property CalcCheckSum: Boolean read FCalcCheckSum write FCalcCheckSum default False;
property Color;
property Cursor;
property DataField;
property DataSet;
property DataSetName;
property Expression: String read FExpression write FExpression;
property Frame;
property HAlign: TfrxHAlign read FHAlign write FHAlign default haLeft;
property Rotation: Integer read FRotation write SetRotation;
property ShowText: Boolean read FShowText write FShowText default True;
property TagStr;
property Text: String read FText write FText;
property URL;
property WideBarRatio: Double read FWideBarRatio write FWideBarRatio;
property Zoom: Double read FZoom write FZoom;
property Font;
end;
implementation
uses
{$IFNDEF NO_EDITORS}
FMX.frxBarcodeEditor,
{$ENDIF}
FMX.frxBarcodeRTTI, FMX.frxDsgnIntf, FMX.frxRes, FMX.frxUtils, FMX.frxPrinter;
const
cbDefaultText = '12345678';
{ TfrxBarCodeView }
constructor TfrxBarCodeView.Create(AOwner: TComponent);
begin
inherited;
FBarCode := TfrxBarCode.Create(nil);
FBarType := bcCode39;
FShowText := True;
FZoom := 1;
FText := cbDefaultText;
FWideBarRatio := 2;
Font.Name := 'Arial';
Font.Size := 9;
Font.OnChange := BcFontChanged;
end;
destructor TfrxBarCodeView.Destroy;
begin
FBarCode.Free;
inherited Destroy;
end;
class function TfrxBarCodeView.GetDescription: String;
begin
Result := frxResources.Get('obBarC');
end;
procedure TfrxBarCodeView.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX,
OffsetY: Extended);
var
SaveWidth: Extended;
ErrorText: String;
DrawRectA: TRectF;
CorrL, CorrR: Integer;
OutRect: TRect;
begin
FBarCode.Angle := FRotation;
Font.AssignToFont(FBarCode.Font);
FBarCode.Font.Size := FBarCode.Font.Size * FZoom;
FBarCode.FontColor := Font.Color;
FBarCode.Checksum := FCalcCheckSum;
FBarCode.Typ := FBarType;
FBarCode.Ratio := FWideBarRatio;
if Color = claNull then
FBarCode.Color := claWhite else
FBarCode.Color := Color;
SaveWidth := Width;
FBarCode.Text := AnsiString(FText);
ErrorText := '';
if FZoom < 0.0001 then
FZoom := 1;
{ frame correction for some bacrode types }
if FBarCode.Typ in [bcCodeUPC_E0, bcCodeUPC_E1, bcCodeUPC_A] then
CorrR := 9
else
CorrR := 0;
if FBarCode.Typ in [bcCodeEAN13, bcCodeUPC_A] then
CorrL := 8
else
CorrL := 0;
try
if (FRotation = 0) or (FRotation = 180) then
Width := (FBarCode.Width + CorrL + CorrR) * FZoom
else
Height := (FBarCode.Width + CorrL + CorrR) * FZoom;
except
on e: Exception do
begin
FBarCode.Text := '12345678';
ErrorText := e.Message;
end;
end;
if FHAlign = haRight then
Left := Left + SaveWidth - Width
else if FHAlign = haCenter then
Left := Left + (SaveWidth - Width) / 2;
BeginDraw(Canvas, ScaleX, ScaleY, OffsetX, OffsetY);
DrawBackground;
if (FRotation = 0) or (FRotation = 180) then
OutRect := Rect(FX + Round(CorrL * ScaleX) , FY, FX1 - Round(CorrR * ScaleX), FY1)
else
OutRect := Rect(FX, FY + Round(CorrL * ScaleX) , FX1, FY1 - Round(CorrR * ScaleX));
if ErrorText = '' then
FBarCode.DrawBarcode(Canvas, OutRect, FShowText, ScaleY, {$IFDEF DELPHI25}{$IFDEF MSWINDOWS}False{$ELSE}IsPrinting{$ENDIF}{$ELSE}IsPrinting{$ENDIF})
else
with Canvas do
begin
Font.Family := 'Arial';
Font.Size := Round(8 * ScaleY);
Fill.Color := claRed;
DrawRectA := RectF(FX + 2, FY + 2, FX1, FY1);
FillText(DrawRectA, ErrorText, True, 1, [], TTextAlign.taLeading, TTextAlign.taLeading);
end;
DrawFrame;
end;
procedure TfrxBarCodeView.GetData;
begin
inherited;
if IsDataField then
FText := VarToStr(DataSet.Value[DataField])
else if FExpression <> '' then
FText := VarToStr(Report.Calc(FExpression));
end;
function TfrxBarCodeView.GetRealBounds: TfrxRect;
var
extra1, extra2, txtWidth: Single;
bmp: TBitmap;
begin
bmp := TBitmap.Create(1,1);
bmp.Canvas.BeginScene;
try
Draw(bmp.Canvas, 1, 1, 0, 0);
Result := inherited GetRealBounds;
extra1 := 0;
extra2 := 0;
if (FRotation = 0) or (FRotation = 180) then
begin
Font.AssignToCanvas(bmp.Canvas);
with bmp.Canvas do
begin
{Font.Name := 'Arial';
Font.Size := 9;
Font.Style := []; }
//Font.Assign(Self.Font);
txtWidth := TextWidth(String(FBarcode.Text));
if Width < txtWidth then
begin
extra1 := Round((txtWidth - Width) / 2) + 2;
extra2 := extra1;
end;
end;
end;
finally
bmp.Canvas.EndScene;
end;
if FBarType in [bcCodeEAN13, bcCodeUPC_A] then
extra1 := 8;
if FBarType in [bcCodeUPC_A, bcCodeUPC_E0, bcCodeUPC_E1] then
extra2 := 8;
case FRotation of
0:
begin
Result.Left := Result.Left - extra1;
Result.Right := Result.Right + extra2;
end;
90:
begin
Result.Bottom := Result.Bottom + extra1;
Result.Top := Result.Top - extra2;
end;
180:
begin
Result.Left := Result.Left - extra2;
Result.Right := Result.Right + extra1;
end;
270:
begin
Result.Bottom := Result.Bottom + extra2;
Result.Top := Result.Top - extra1;
end;
end;
bmp.Free;
end;
procedure TfrxBarCodeView.SetRotation(const Value: Integer);
begin
case Round(Value) of
0 .. 44: FRotation := 0;
45 .. 135: FRotation := 90;
136 .. 224: FRotation := 180;
225 .. 315: FRotation := 270;
else
FRotation := 0;
end;
end;
procedure TfrxBarCodeView.BcFontChanged(Sender: TObject);
begin
if Font.Size > 9 then Font.Size := 9;
end;
initialization
StartClassGroup(TfmxObject);
ActivateClassGroup(TfmxObject);
//GroupDescendentsWith(TfrxBarCodeView, TfmxObject);
GroupDescendentsWith(TfrxBarCodeObject, TfmxObject);
RegisterFmxClasses([TfrxBarCodeObject]);
frxObjects.RegisterObject1(TfrxBarCodeView, nil, '', '', 0, 123);
finalization
frxObjects.UnRegister(TfrxBarCodeView);
end.