lazarus-ccr/components/systools/source/general/run/st2dbarc.pas
wp_xxyyzz 543cdf06d9 systools: Rearrange units and packages
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6159 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2018-01-30 16:17:37 +00:00

5255 lines
189 KiB
ObjectPascal

// Upgraded to Delphi 2009: Sebastian Zierer
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower SysTools
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1996-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* SysTools: St2DBarC.pas 4.04 *}
{*********************************************************}
{* SysTools: Two-Dimensional Barcodes *}
{*********************************************************}
{$IFDEF FPC}
{$mode DELPHI}
{$ENDIF}
//{$I StDefine.inc}
unit St2DBarC;
interface
uses
{$IFDEF FPC}
LCLIntf, LCLType, LMessages,
{$ELSE}
Windows, Messages,
{$ENDIF}
SysUtils,
Classes,
Controls,
Graphics,
StdCtrls,
Math,
ClipBrd,
StConst;
resourcestring
StEBadBarHeight = 'Bar Height cannot be less than one';
StEBadBarHeightToWidth = 'BarHeightToWidth cannot be less than one';
StEBadBarWidth = 'Bar Width cannot be less than one';
StEBadCountryCode = 'Invalid Country Code';
StEBadNumCols = 'Invalid Number of columns';
StEBadNumRows = 'Invalid number of rows';
StEBadPostalCode = 'Invalid Postal Code';
StEBadServiceClass = 'Invalid Service Class';
StEBadQuietZone = 'Invalid Quiet Zone';
StECodeTooLarge = 'Code too large for barcode';
StEGLIOutOfRange = 'GLI value out of range';
StEInvalidCodeword = 'Invalid Codeword';
StENeedBarHeight = 'Either BarHeight or BarHeightToWidth is required';
StENeedHorz = 'Horizontal size needs to be specified';
StENeedVert = 'Vertical size needs to be specified';
type
{ Generic 2D barcode types and constants }
TStDataMode = (dmBinary, dmText, dmNumeric);
{ PDF417 types and constants }
TStPDF417CodewordList = array [0..2700] of Word;
TStPDF417ECCLevels = (ecAuto, ecLevel0, ecLevel1, ecLevel2, ecLevel3,
ecLevel4, ecLevel5, ecLevel6, ecLevel7, ecLevel8);
{ MaxiCode types and constants }
TStMaxiCodeMode = (cmMode2, cmMode3, cmMode4, cmMode5, cmMode6);
const
StMaxiCodeGaloisField = 64; { Galois field to work in }
StMaxiCodeECCPoly = 67; { Primary polynomial - }
StMaxMaxiCodeECCDataSize = 144; { Max amount of data }
type
TStMaxiCodeECCData = array [0..StMaxMaxiCodeECCDataSize] of Byte;
TStMaxiCodeECCPoly = (epPrimary, epStandard, epEnhanced);
TStMaxiCodeECCInterleave = (imNone, imEven, imOdd);
{ E2DBarcodeError }
E2DBarcodeError = class (Exception);
{ TStCustom2DBarcode }
TStCustom2DBarcode = class (TGraphicControl)
protected { private }
FCode : string;
FBarWidth : Integer;
FBackgroundColor : TColor;
FCaption : string;
FECCLevel : Integer;
FExtendedSyntax : Boolean;
FRelativeBarHeight : Boolean;
FBarHeightToWidth : Integer;
FBarHeight : Integer;
FQuietZone : Integer;
FAlignment : TAlignment;
FCaptionLayout : TTextLayout;
FBarCodeRect : TRect;
FUsedCodewords : Integer;
FFreeCodewords : Integer;
FUsedECCCodewords : Integer;
FTotalCodewords : Integer;
{ protected }
FBitmap : TBitmap;
function CalculateBarCodeWidth (PaintableWidth : Integer) : Integer;
virtual; abstract;
function CalculateBarCodeHeight (PaintableHeight : Integer) : Integer;
virtual; abstract;
procedure DrawBarcode; virtual; abstract;
procedure GenerateBarcodeBitmap (BCWidth : Integer;
BCHeight : Integer);
procedure GenerateCodewords; virtual; abstract;
function GetBarCodeHeight : Integer;
function GetBarCodeWidth : Integer;
procedure GetCurrentResolution (var ResX : Integer; var ResY : Integer);
function GetVersion : string;
procedure Paint; override;
procedure SetAlignment (const v : TAlignment);
procedure SetBackgroundColor (const v : TColor);
procedure SetBarHeight (const v : Integer); virtual;
procedure SetBarHeightToWidth (const v : Integer); virtual;
procedure SetBarWidth (const v : Integer); virtual;
procedure SetBitmap (const v : TBitmap);
procedure SetCaption (const v : string);
procedure SetCaptionLayout (const v : TTextLayout);
procedure SetCode (const v : string);
procedure SetECCLevel (const v : Integer);
procedure SetExtendedSyntax (const v : Boolean);
procedure SetRelativeBarHeight (const v : Boolean); virtual;
procedure SetQuietZone (const v : Integer);
procedure SetVersion(const Value : string);
public
constructor Create (AOwner : TComponent); override;
destructor Destroy; override;
procedure CopyToClipboard;
procedure CopyToClipboardRes (ResX : Integer; ResY : Integer);
procedure PaintToCanvas (ACanvas : TCanvas; Position : TPoint);
procedure PaintToCanvasRes (ACanvas : TCanvas; Position : TPoint;
ResX : Integer; ResY : Integer);
procedure PaintToCanvasSize (ACanvas : TCanvas; X, Y, H : Double);
procedure PaintToDC (DC : hDC; Position : TPoint);
procedure PaintToDCRes (DC : hDC; Position : TPoint;
ResX : Integer; ResY : Integer);
procedure PaintToPrinterCanvas (ACanvas : TCanvas; Position : TPoint);
procedure PaintToPrinterCanvasRes (ACanvas : TCanvas; Position : TPoint;
ResX : Integer; ResY : Integer);
procedure PaintToPrinterCanvasSize (ACanvas : TCanvas; X, Y, H : Double);
procedure PaintToPrinterDC (DC : hDC; Position : TPoint);
procedure PaintToPrinterDCRes (DC : hDC; Position : TPoint;
ResX : Integer; ResY : Integer);
procedure RenderToResolution (var OutBitmap : TBitmap;
ResX : Integer;
ResY : Integer;
var SizeX : Integer;
var SizeY : Integer); virtual; abstract;
procedure SaveToFile (const FileName : string);
procedure SaveToFileRes (const FileName : string;
ResX : Integer; ResY : Integer);
property Alignment : TAlignment read FAlignment write SetAlignment
default taCenter;
property BackgroundColor : TColor
read FBackgroundColor write SetBackgroundColor default clWhite;
property BarCodeHeight : Integer read GetBarCodeHeight;
property BarCodeRect : TRect read FBarCodeRect;
property BarCodeWidth : Integer read GetBarCodeWidth;
property BarHeight : Integer read FBarHeight write SetBarHeight
default 2;
property BarHeightToWidth : Integer
read FBarHeightToWidth write SetBarHeightToWidth default 4;
property BarWidth : Integer read FBarWidth write SetBarWidth default 2;
property Bitmap : TBitmap read FBitmap write SetBitmap stored False;
property Caption : string read FCaption write SetCaption;
property CaptionLayout : TTextLayout
read FCaptionLayout write SetCaptionLayout
default tlBottom;
property Code : string read FCode write SetCode;
property ECCLevel : Integer read FECCLevel write SetECCLevel default 0;
property ExtendedSyntax : Boolean
read FExtendedSyntax write SetExtendedSyntax default True;
property FreeCodewords : Integer read FFreeCodewords;
property RelativeBarHeight : Boolean
read FRelativeBarHeight write SetRelativeBarHeight
default False;
property QuietZone : Integer read FQuietZone write SetQuietZone
default 8;
property TotalCodewords : Integer read FTotalCodewords;
property UsedCodewords : Integer read FUsedCodewords;
property UsedECCCodewords : Integer read FUsedECCCodewords;
property Color default clBlack;
published
property Version : string read GetVersion write SetVersion stored False;
{ Properties }
property Align;
property Cursor;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property ShowHint;
property Visible;
{ Events }
property OnClick;
property OnDblClick;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
{ TStPDF417Barcode }
TStPDF417Barcode = class (TStCustom2DBarcode)
private
FTruncated : Boolean;
FCodewords : TStPDF417CodewordList;
FNumCodewords : Integer;
FNewTextCodeword : Boolean;
FHighlight : Boolean;
FNumRows : Integer;
FNumColumns : Integer;
protected
procedure AddCodeword (Value : Word);
function CalculateBarCodeWidth (PaintableWidth : Integer) : Integer;
override;
function CalculateBarCodeHeight (PaintableHeight : Integer) : Integer;
override;
procedure CalculateECC (NumCodewords : Integer; ECCLen : Integer);
procedure CalculateSize (var XSize : Integer;
var YSize : Integer);
function CodewordToBitmask (RowNumber : Integer;
Codeword : Integer) : DWord;
procedure ConvertBytesToBase900 (const S : array of byte;
var A : array of integer);
procedure ConvertToBase900 (const S : string;
var A : array of integer;
var LenA : integer);
procedure DrawBarcode; override;
procedure DrawCodeword (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer;
Pattern : string);
procedure DrawCodewordBitmask (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer;
Bitmask : DWord);
procedure DrawLeftRowIndicator (RowNumber : Integer;
WorkBarHeight : Integer;
NumRows : Integer;
NumCols : Integer);
procedure DrawRightRowIndicator (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer;
NumRows : Integer;
NumCols : Integer);
procedure DrawStartPattern (RowNumber : Integer;
WorkBarHeight : Integer);
procedure DrawStopPattern (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer);
procedure EncodeBinary (var Position : Integer; CodeLen : Integer);
procedure EncodeNumeric (var Position : Integer; CodeLen : Integer);
procedure EncodeText (var Position : Integer; CodeLen : Integer);
procedure GenerateCodewords; override;
procedure GetNextCharacter (var NewChar : Integer;
var Codeword : Boolean;
var Position : Integer;
CodeLen : Integer);
function GetPDF417ECCLevel : TStPDF417ECCLevels;
function GetRealErrorLevel : Integer;
function GoodForNumericCompaction (Position : Integer;
CodeLen : Integer;
var Count : Integer) : Boolean;
function GoodForTextCompaction (Position : Integer;
CodeLen : Integer;
var Count : Integer) : Boolean;
function IsNumericString (const S : string) : boolean;
procedure SetBarHeight (const v : Integer); override;
procedure SetBarHeightToWidth (const v : Integer); override;
procedure SetBarWidth (const v : Integer); override;
procedure SetNumColumns (const v : Integer);
procedure SetNumRows (const v : Integer);
procedure SetPDF417ECCLevel (const v : TStPDF417ECCLevels);
procedure SetRelativeBarHeight (const v : Boolean); override;
procedure SetTruncated (const v : Boolean);
procedure TextToCodewords;
public
constructor Create (AOwner : TComponent); override;
procedure RenderToResolution (var OutBitmap : TBitmap;
ResX : Integer;
ResY : Integer;
var SizeX : Integer;
var SizeY : Integer); override;
published
property ECCLevel : TStPDF417ECCLevels
read GetPDF417ECCLevel write SetPDF417ECCLevel default ecAuto;
property NumColumns : Integer read FNumColumns write SetNumColumns
default 0;
property NumRows : Integer read FNumRows write SetNumRows
default 0;
property Truncated : Boolean read FTruncated write SetTruncated
default False;
property Alignment;
property BackgroundColor;
property BarCodeHeight;
property BarCodeWidth;
property BarHeight;
property BarHeightToWidth;
property BarWidth;
property Bitmap;
property CaptionLayout;
property Code;
property ExtendedSyntax;
property Height default 81;
property RelativeBarHeight;
property QuietZone;
property Width default 273;
property Caption;
property Color;
property Font;
end;
{ TStMaxiCodeBarcode }
TStMaxiCodeBarcode = class (TStCustom2DBarcode)
private
FMode : TStMaxiCodeMode;
FCodewords : TStMaxiCodeECCData;
FNumCodewords : Integer;
FHighlight : Boolean;
FShowCodewords : Boolean;
FShowAll : Boolean;
FMessage : TStMaxiCodeECCData;
FCarrierCountryCode : Integer;
FCarrierPostalCode : string;
FCarrierServiceClass : Integer;
FAutoScale : Boolean;
FHorPixelsPerMM : Extended;
FVerPixelsPerMM : Extended;
FMaxiHexWidth : Extended;
FMaxiHexHeight : Extended;
FMaxiHexVOffset : Extended;
FMaxiHexHOffset : Extended;
{ Log and AnitLog data for Galois field arithmetic }
FLog : array [0..StMaxiCodeGaloisField] of Integer;
FAntiLog : array [0..StMaxiCodeGaloisField] of Integer;
protected
procedure AddCodeword (Value : Integer);
function CalculateBarCodeWidth (PaintableWidth : Integer) : Integer;
override;
function CalculateBarCodeHeight (PaintableHeight : Integer) : Integer;
override;
procedure DrawBarcode; override;
procedure DrawFinder;
procedure DrawHex (XPos, YPos : Integer);
procedure GenerateCodewords; override;
procedure GenerateECC;
procedure GetNextCharacter (var NewChar : Integer;
var Codeword : Boolean;
var Position : Integer;
CodeLen : Integer);
procedure GetSizes;
procedure GetSizesEx (ResX : Integer; ResY : Integer);
procedure PlotCell (Row : Integer; Col : Integer);
procedure SetAutoScale (const v : Boolean);
procedure SetBarHeight (const v : Integer); override;
procedure SetBarWidth (const v : Integer); override;
procedure SetCarrierCountryCode (const v : Integer);
procedure SetCarrierPostalCode (const v : string);
procedure SetCarrierServiceClass (const v : Integer);
procedure SetMode (const v : TStMaxiCodeMode);
procedure SetHorPixelsPerMM (const v : Extended);
procedure SetVerPixelsPerMM (const v : Extended);
procedure TextToCodewords;
public
constructor Create (AOwner : TComponent); override;
procedure RenderToResolution (var OutBitmap : TBitmap;
ResX : Integer;
ResY : Integer;
var SizeX : Integer;
var SizeY : Integer); override;
published
property AutoScale : Boolean
read FAutoScale write SetAutoScale default True;
property CarrierCountryCode : Integer
read FCarrierCountryCode write SetCarrierCountryCode default 0;
property CarrierPostalCode : string
read FCarrierPostalCode write SetCarrierPostalCode;
property CarrierServiceClass : Integer
read FCarrierServiceClass write SetCarrierServiceClass
default 0;
property HorPixelsPerMM : Extended
read FHorPixelsPerMM write SetHorPixelsPerMM;
property Mode : TStMaxiCodeMode
read FMode write SetMode default cmMode4;
property VerPixelsPerMM : Extended
read FVerPixelsPerMM write SetVerPixelsPerMM;
property Alignment;
property BackgroundColor;
property BarCodeHeight;
property BarCodeWidth;
property BarHeight default 0;
property BarWidth default 0;
property Bitmap;
property CaptionLayout;
property Code;
property ExtendedSyntax;
property Height default 129;
property QuietZone;
property Width default 121;
property Caption;
property Color;
property Font;
end;
implementation
{ PDF417 types and constants }
type
TStPDF417CodewordArray = array [0..2] of array [0..928] of Longint;
const
StPDF417CellWidth = 17;
StPDF417Codewords : TstPDF417CodewordArray =
(($1d5c0, $1eaf0, $1f57c, $1d4e0, $1ea78, $1f53e, $1a8c0, $1d470, $1a860,
$15040, $1a830, $15020, $1adc0, $1d6f0, $1eb7c, $1ace0, $1d678, $1eb3e,
$158c0, $1ac70, $15860, $15dc0, $1aef0, $1d77c, $15ce0, $1ae78, $1d73e,
$15c70, $1ae3c, $15ef0, $1af7c, $15e78, $1af3e, $15f7c, $1f5fa, $1d2e0,
$1e978, $1f4be, $1a4c0, $1d270, $1e93c, $1a460, $1d238, $14840, $1a430,
$1d21c, $14820, $1a418, $14810, $1a6e0, $1d378, $1e9be, $14cc0, $1a670,
$1d33c, $14c60, $1a638, $1d31e, $14c30, $1a61c, $14ee0, $1a778, $1d3be,
$14e70, $1a73c, $14e38, $1a71e, $14f78, $1a7be, $14f3c, $14f1e, $1a2c0,
$1d170, $1e8bc, $1a260, $1d138, $1e89e, $14440, $1a230, $1d11c, $14420,
$1a218, $14410, $14408, $146c0, $1a370, $1d1bc, $14660, $1a338, $1d19e,
$14630, $1a31c, $14618, $1460c, $14770, $1a3bc, $14738, $1a39e, $1471c,
$147bc, $1a160, $1d0b8, $1e85e, $14240, $1a130, $1d09c, $14220, $1a118,
$1d08e, $14210, $1a10c, $14208, $1a106, $14360, $1a1b8, $1d0de, $14330,
$1a19c, $14318, $1a18e, $1430c, $14306, $1a1de, $1438e, $14140, $1a0b0,
$1d05c, $14120, $1a098, $1d04e, $14110, $1a08c, $14108, $1a086, $14104,
$141b0, $14198, $1418c, $140a0, $1d02e, $1a04c, $1a046, $14082, $1cae0,
$1e578, $1f2be, $194c0, $1ca70, $1e53c, $19460, $1ca38, $1e51e, $12840,
$19430, $12820, $196e0, $1cb78, $1e5be, $12cc0, $19670, $1cb3c, $12c60,
$19638, $12c30, $12c18, $12ee0, $19778, $1cbbe, $12e70, $1973c, $12e38,
$12e1c, $12f78, $197be, $12f3c, $12fbe, $1dac0, $1ed70, $1f6bc, $1da60,
$1ed38, $1f69e, $1b440, $1da30, $1ed1c, $1b420, $1da18, $1ed0e, $1b410,
$1da0c, $192c0, $1c970, $1e4bc, $1b6c0, $19260, $1c938, $1e49e, $1b660,
$1db38, $1ed9e, $16c40, $12420, $19218, $1c90e, $16c20, $1b618, $16c10,
$126c0, $19370, $1c9bc, $16ec0, $12660, $19338, $1c99e, $16e60, $1b738,
$1db9e, $16e30, $12618, $16e18, $12770, $193bc, $16f70, $12738, $1939e,
$16f38, $1b79e, $16f1c, $127bc, $16fbc, $1279e, $16f9e, $1d960, $1ecb8,
$1f65e, $1b240, $1d930, $1ec9c, $1b220, $1d918, $1ec8e, $1b210, $1d90c,
$1b208, $1b204, $19160, $1c8b8, $1e45e, $1b360, $19130, $1c89c, $16640,
$12220, $1d99c, $1c88e, $16620, $12210, $1910c, $16610, $1b30c, $19106,
$12204, $12360, $191b8, $1c8de, $16760, $12330, $1919c, $16730, $1b39c,
$1918e, $16718, $1230c, $12306, $123b8, $191de, $167b8, $1239c, $1679c,
$1238e, $1678e, $167de, $1b140, $1d8b0, $1ec5c, $1b120, $1d898, $1ec4e,
$1b110, $1d88c, $1b108, $1d886, $1b104, $1b102, $12140, $190b0, $1c85c,
$16340, $12120, $19098, $1c84e, $16320, $1b198, $1d8ce, $16310, $12108,
$19086, $16308, $1b186, $16304, $121b0, $190dc, $163b0, $12198, $190ce,
$16398, $1b1ce, $1638c, $12186, $16386, $163dc, $163ce, $1b0a0, $1d858,
$1ec2e, $1b090, $1d84c, $1b088, $1d846, $1b084, $1b082, $120a0, $19058,
$1c82e, $161a0, $12090, $1904c, $16190, $1b0cc, $19046, $16188, $12084,
$16184, $12082, $120d8, $161d8, $161cc, $161c6, $1d82c, $1d826, $1b042,
$1902c, $12048, $160c8, $160c4, $160c2, $18ac0, $1c570, $1e2bc, $18a60,
$1c538, $11440, $18a30, $1c51c, $11420, $18a18, $11410, $11408, $116c0,
$18b70, $1c5bc, $11660, $18b38, $1c59e, $11630, $18b1c, $11618, $1160c,
$11770, $18bbc, $11738, $18b9e, $1171c, $117bc, $1179e, $1cd60, $1e6b8,
$1f35e, $19a40, $1cd30, $1e69c, $19a20, $1cd18, $1e68e, $19a10, $1cd0c,
$19a08, $1cd06, $18960, $1c4b8, $1e25e, $19b60, $18930, $1c49c, $13640,
$11220, $1cd9c, $1c48e, $13620, $19b18, $1890c, $13610, $11208, $13608,
$11360, $189b8, $1c4de, $13760, $11330, $1cdde, $13730, $19b9c, $1898e,
$13718, $1130c, $1370c, $113b8, $189de, $137b8, $1139c, $1379c, $1138e,
$113de, $137de, $1dd40, $1eeb0, $1f75c, $1dd20, $1ee98, $1f74e, $1dd10,
$1ee8c, $1dd08, $1ee86, $1dd04, $19940, $1ccb0, $1e65c, $1bb40, $19920,
$1eedc, $1e64e, $1bb20, $1dd98, $1eece, $1bb10, $19908, $1cc86, $1bb08,
$1dd86, $19902, $11140, $188b0, $1c45c, $13340, $11120, $18898, $1c44e,
$17740, $13320, $19998, $1ccce, $17720, $1bb98, $1ddce, $18886, $17710,
$13308, $19986, $17708, $11102, $111b0, $188dc, $133b0, $11198, $188ce,
$177b0, $13398, $199ce, $17798, $1bbce, $11186, $13386, $111dc, $133dc,
$111ce, $177dc, $133ce, $1dca0, $1ee58, $1f72e, $1dc90, $1ee4c, $1dc88,
$1ee46, $1dc84, $1dc82, $198a0, $1cc58, $1e62e, $1b9a0, $19890, $1ee6e,
$1b990, $1dccc, $1cc46, $1b988, $19884, $1b984, $19882, $1b982, $110a0,
$18858, $1c42e, $131a0, $11090, $1884c, $173a0, $13190, $198cc, $18846,
$17390, $1b9cc, $11084, $17388, $13184, $11082, $13182, $110d8, $1886e,
$131d8, $110cc, $173d8, $131cc, $110c6, $173cc, $131c6, $110ee, $173ee,
$1dc50, $1ee2c, $1dc48, $1ee26, $1dc44, $1dc42, $19850, $1cc2c, $1b8d0,
$19848, $1cc26, $1b8c8, $1dc66, $1b8c4, $19842, $1b8c2, $11050, $1882c,
$130d0, $11048, $18826, $171d0, $130c8, $19866, $171c8, $1b8e6, $11042,
$171c4, $130c2, $171c2, $130ec, $171ec, $171e6, $1ee16, $1dc22, $1cc16,
$19824, $19822, $11028, $13068, $170e8, $11022, $13062, $18560, $10a40,
$18530, $10a20, $18518, $1c28e, $10a10, $1850c, $10a08, $18506, $10b60,
$185b8, $1c2de, $10b30, $1859c, $10b18, $1858e, $10b0c, $10b06, $10bb8,
$185de, $10b9c, $10b8e, $10bde, $18d40, $1c6b0, $1e35c, $18d20, $1c698,
$18d10, $1c68c, $18d08, $1c686, $18d04, $10940, $184b0, $1c25c, $11b40,
$10920, $1c6dc, $1c24e, $11b20, $18d98, $1c6ce, $11b10, $10908, $18486,
$11b08, $18d86, $10902, $109b0, $184dc, $11bb0, $10998, $184ce, $11b98,
$18dce, $11b8c, $10986, $109dc, $11bdc, $109ce, $11bce, $1cea0, $1e758,
$1f3ae, $1ce90, $1e74c, $1ce88, $1e746, $1ce84, $1ce82, $18ca0, $1c658,
$19da0, $18c90, $1c64c, $19d90, $1cecc, $1c646, $19d88, $18c84, $19d84,
$18c82, $19d82, $108a0, $18458, $119a0, $10890, $1c66e, $13ba0, $11990,
$18ccc, $18446, $13b90, $19dcc, $10884, $13b88, $11984, $10882, $11982,
$108d8, $1846e, $119d8, $108cc, $13bd8, $119cc, $108c6, $13bcc, $119c6,
$108ee, $119ee, $13bee, $1ef50, $1f7ac, $1ef48, $1f7a6, $1ef44, $1ef42,
$1ce50, $1e72c, $1ded0, $1ef6c, $1e726, $1dec8, $1ef66, $1dec4, $1ce42,
$1dec2, $18c50, $1c62c, $19cd0, $18c48, $1c626, $1bdd0, $19cc8, $1ce66,
$1bdc8, $1dee6, $18c42, $1bdc4, $19cc2, $1bdc2, $10850, $1842c, $118d0,
$10848, $18426, $139d0, $118c8, $18c66, $17bd0, $139c8, $19ce6, $10842,
$17bc8, $1bde6, $118c2, $17bc4, $1086c, $118ec, $10866, $139ec, $118e6,
$17bec, $139e6, $17be6, $1ef28, $1f796, $1ef24, $1ef22, $1ce28, $1e716,
$1de68, $1ef36, $1de64, $1ce22, $1de62, $18c28, $1c616, $19c68, $18c24,
$1bce8, $19c64, $18c22, $1bce4, $19c62, $1bce2, $10828, $18416, $11868,
$18c36, $138e8, $11864, $10822, $179e8, $138e4, $11862, $179e4, $138e2,
$179e2, $11876, $179f6, $1ef12, $1de34, $1de32, $19c34, $1bc74, $1bc72,
$11834, $13874, $178f4, $178f2, $10540, $10520, $18298, $10510, $10508,
$10504, $105b0, $10598, $1058c, $10586, $105dc, $105ce, $186a0, $18690,
$1c34c, $18688, $1c346, $18684, $18682, $104a0, $18258, $10da0, $186d8,
$1824c, $10d90, $186cc, $10d88, $186c6, $10d84, $10482, $10d82, $104d8,
$1826e, $10dd8, $186ee, $10dcc, $104c6, $10dc6, $104ee, $10dee, $1c750,
$1c748, $1c744, $1c742, $18650, $18ed0, $1c76c, $1c326, $18ec8, $1c766,
$18ec4, $18642, $18ec2, $10450, $10cd0, $10448, $18226, $11dd0, $10cc8,
$10444, $11dc8, $10cc4, $10442, $11dc4, $10cc2, $1046c, $10cec, $10466,
$11dec, $10ce6, $11de6, $1e7a8, $1e7a4, $1e7a2, $1c728, $1cf68, $1e7b6,
$1cf64, $1c722, $1cf62, $18628, $1c316, $18e68, $1c736, $19ee8, $18e64,
$18622, $19ee4, $18e62, $19ee2, $10428, $18216, $10c68, $18636, $11ce8,
$10c64, $10422, $13de8, $11ce4, $10c62, $13de4, $11ce2, $10436, $10c76,
$11cf6, $13df6, $1f7d4, $1f7d2, $1e794, $1efb4, $1e792, $1efb2, $1c714,
$1cf34, $1c712, $1df74, $1cf32, $1df72, $18614, $18e34, $18612, $19e74,
$18e32, $1bef4),
($1f560, $1fab8, $1ea40, $1f530, $1fa9c, $1ea20, $1f518, $1fa8e, $1ea10,
$1f50c, $1ea08, $1f506, $1ea04, $1eb60, $1f5b8, $1fade, $1d640, $1eb30,
$1f59c, $1d620, $1eb18, $1f58e, $1d610, $1eb0c, $1d608, $1eb06, $1d604,
$1d760, $1ebb8, $1f5de, $1ae40, $1d730, $1eb9c, $1ae20, $1d718, $1eb8e,
$1ae10, $1d70c, $1ae08, $1d706, $1ae04, $1af60, $1d7b8, $1ebde, $15e40,
$1af30, $1d79c, $15e20, $1af18, $1d78e, $15e10, $1af0c, $15e08, $1af06,
$15f60, $1afb8, $1d7de, $15f30, $1af9c, $15f18, $1af8e, $15f0c, $15fb8,
$1afde, $15f9c, $15f8e, $1e940, $1f4b0, $1fa5c, $1e920, $1f498, $1fa4e,
$1e910, $1f48c, $1e908, $1f486, $1e904, $1e902, $1d340, $1e9b0, $1f4dc,
$1d320, $1e998, $1f4ce, $1d310, $1e98c, $1d308, $1e986, $1d304, $1d302,
$1a740, $1d3b0, $1e9dc, $1a720, $1d398, $1e9ce, $1a710, $1d38c, $1a708,
$1d386, $1a704, $1a702, $14f40, $1a7b0, $1d3dc, $14f20, $1a798, $1d3ce,
$14f10, $1a78c, $14f08, $1a786, $14f04, $14fb0, $1a7dc, $14f98, $1a7ce,
$14f8c, $14f86, $14fdc, $14fce, $1e8a0, $1f458, $1fa2e, $1e890, $1f44c,
$1e888, $1f446, $1e884, $1e882, $1d1a0, $1e8d8, $1f46e, $1d190, $1e8cc,
$1d188, $1e8c6, $1d184, $1d182, $1a3a0, $1d1d8, $1e8ee, $1a390, $1d1cc,
$1a388, $1d1c6, $1a384, $1a382, $147a0, $1a3d8, $1d1ee, $14790, $1a3cc,
$14788, $1a3c6, $14784, $14782, $147d8, $1a3ee, $147cc, $147c6, $147ee,
$1e850, $1f42c, $1e848, $1f426, $1e844, $1e842, $1d0d0, $1e86c, $1d0c8,
$1e866, $1d0c4, $1d0c2, $1a1d0, $1d0ec, $1a1c8, $1d0e6, $1a1c4, $1a1c2,
$143d0, $1a1ec, $143c8, $1a1e6, $143c4, $143c2, $143ec, $143e6, $1e828,
$1f416, $1e824, $1e822, $1d068, $1e836, $1d064, $1d062, $1a0e8, $1d076,
$1a0e4, $1a0e2, $141e8, $1a0f6, $141e4, $141e2, $1e814, $1e812, $1d034,
$1d032, $1a074, $1a072, $1e540, $1f2b0, $1f95c, $1e520, $1f298, $1f94e,
$1e510, $1f28c, $1e508, $1f286, $1e504, $1e502, $1cb40, $1e5b0, $1f2dc,
$1cb20, $1e598, $1f2ce, $1cb10, $1e58c, $1cb08, $1e586, $1cb04, $1cb02,
$19740, $1cbb0, $1e5dc, $19720, $1cb98, $1e5ce, $19710, $1cb8c, $19708,
$1cb86, $19704, $19702, $12f40, $197b0, $1cbdc, $12f20, $19798, $1cbce,
$12f10, $1978c, $12f08, $19786, $12f04, $12fb0, $197dc, $12f98, $197ce,
$12f8c, $12f86, $12fdc, $12fce, $1f6a0, $1fb58, $16bf0, $1f690, $1fb4c,
$169f8, $1f688, $1fb46, $168fc, $1f684, $1f682, $1e4a0, $1f258, $1f92e,
$1eda0, $1e490, $1fb6e, $1ed90, $1f6cc, $1f246, $1ed88, $1e484, $1ed84,
$1e482, $1ed82, $1c9a0, $1e4d8, $1f26e, $1dba0, $1c990, $1e4cc, $1db90,
$1edcc, $1e4c6, $1db88, $1c984, $1db84, $1c982, $1db82, $193a0, $1c9d8,
$1e4ee, $1b7a0, $19390, $1c9cc, $1b790, $1dbcc, $1c9c6, $1b788, $19384,
$1b784, $19382, $1b782, $127a0, $193d8, $1c9ee, $16fa0, $12790, $193cc,
$16f90, $1b7cc, $193c6, $16f88, $12784, $16f84, $12782, $127d8, $193ee,
$16fd8, $127cc, $16fcc, $127c6, $16fc6, $127ee, $1f650, $1fb2c, $165f8,
$1f648, $1fb26, $164fc, $1f644, $1647e, $1f642, $1e450, $1f22c, $1ecd0,
$1e448, $1f226, $1ecc8, $1f666, $1ecc4, $1e442, $1ecc2, $1c8d0, $1e46c,
$1d9d0, $1c8c8, $1e466, $1d9c8, $1ece6, $1d9c4, $1c8c2, $1d9c2, $191d0,
$1c8ec, $1b3d0, $191c8, $1c8e6, $1b3c8, $1d9e6, $1b3c4, $191c2, $1b3c2,
$123d0, $191ec, $167d0, $123c8, $191e6, $167c8, $1b3e6, $167c4, $123c2,
$167c2, $123ec, $167ec, $123e6, $167e6, $1f628, $1fb16, $162fc, $1f624,
$1627e, $1f622, $1e428, $1f216, $1ec68, $1f636, $1ec64, $1e422, $1ec62,
$1c868, $1e436, $1d8e8, $1c864, $1d8e4, $1c862, $1d8e2, $190e8, $1c876,
$1b1e8, $1d8f6, $1b1e4, $190e2, $1b1e2, $121e8, $190f6, $163e8, $121e4,
$163e4, $121e2, $163e2, $121f6, $163f6, $1f614, $1617e, $1f612, $1e414,
$1ec34, $1e412, $1ec32, $1c834, $1d874, $1c832, $1d872, $19074, $1b0f4,
$19072, $1b0f2, $120f4, $161f4, $120f2, $161f2, $1f60a, $1e40a, $1ec1a,
$1c81a, $1d83a, $1903a, $1b07a, $1e2a0, $1f158, $1f8ae, $1e290, $1f14c,
$1e288, $1f146, $1e284, $1e282, $1c5a0, $1e2d8, $1f16e, $1c590, $1e2cc,
$1c588, $1e2c6, $1c584, $1c582, $18ba0, $1c5d8, $1e2ee, $18b90, $1c5cc,
$18b88, $1c5c6, $18b84, $18b82, $117a0, $18bd8, $1c5ee, $11790, $18bcc,
$11788, $18bc6, $11784, $11782, $117d8, $18bee, $117cc, $117c6, $117ee,
$1f350, $1f9ac, $135f8, $1f348, $1f9a6, $134fc, $1f344, $1347e, $1f342,
$1e250, $1f12c, $1e6d0, $1e248, $1f126, $1e6c8, $1f366, $1e6c4, $1e242,
$1e6c2, $1c4d0, $1e26c, $1cdd0, $1c4c8, $1e266, $1cdc8, $1e6e6, $1cdc4,
$1c4c2, $1cdc2, $189d0, $1c4ec, $19bd0, $189c8, $1c4e6, $19bc8, $1cde6,
$19bc4, $189c2, $19bc2, $113d0, $189ec, $137d0, $113c8, $189e6, $137c8,
$19be6, $137c4, $113c2, $137c2, $113ec, $137ec, $113e6, $137e6, $1fba8,
$175f0, $1bafc, $1fba4, $174f8, $1ba7e, $1fba2, $1747c, $1743e, $1f328,
$1f996, $132fc, $1f768, $1fbb6, $176fc, $1327e, $1f764, $1f322, $1767e,
$1f762, $1e228, $1f116, $1e668, $1e224, $1eee8, $1f776, $1e222, $1eee4,
$1e662, $1eee2, $1c468, $1e236, $1cce8, $1c464, $1dde8, $1cce4, $1c462,
$1dde4, $1cce2, $1dde2, $188e8, $1c476, $199e8, $188e4, $1bbe8, $199e4,
$188e2, $1bbe4, $199e2, $1bbe2, $111e8, $188f6, $133e8, $111e4, $177e8,
$133e4, $111e2, $177e4, $133e2, $177e2, $111f6, $133f6, $1fb94, $172f8,
$1b97e, $1fb92, $1727c, $1723e, $1f314, $1317e, $1f734, $1f312, $1737e,
$1f732, $1e214, $1e634, $1e212, $1ee74, $1e632, $1ee72, $1c434, $1cc74,
$1c432, $1dcf4, $1cc72, $1dcf2, $18874, $198f4, $18872, $1b9f4, $198f2,
$1b9f2, $110f4, $131f4, $110f2, $173f4, $131f2, $173f2, $1fb8a, $1717c,
$1713e, $1f30a, $1f71a, $1e20a, $1e61a, $1ee3a, $1c41a, $1cc3a, $1dc7a,
$1883a, $1987a, $1b8fa, $1107a, $130fa, $171fa, $170be, $1e150, $1f0ac,
$1e148, $1f0a6, $1e144, $1e142, $1c2d0, $1e16c, $1c2c8, $1e166, $1c2c4,
$1c2c2, $185d0, $1c2ec, $185c8, $1c2e6, $185c4, $185c2, $10bd0, $185ec,
$10bc8, $185e6, $10bc4, $10bc2, $10bec, $10be6, $1f1a8, $1f8d6, $11afc,
$1f1a4, $11a7e, $1f1a2, $1e128, $1f096, $1e368, $1e124, $1e364, $1e122,
$1e362, $1c268, $1e136, $1c6e8, $1c264, $1c6e4, $1c262, $1c6e2, $184e8,
$1c276, $18de8, $184e4, $18de4, $184e2, $18de2, $109e8, $184f6, $11be8,
$109e4, $11be4, $109e2, $11be2, $109f6, $11bf6, $1f9d4, $13af8, $19d7e,
$1f9d2, $13a7c, $13a3e, $1f194, $1197e, $1f3b4, $1f192, $13b7e, $1f3b2,
$1e114, $1e334, $1e112, $1e774, $1e332, $1e772, $1c234, $1c674, $1c232,
$1cef4, $1c672, $1cef2, $18474, $18cf4, $18472, $19df4, $18cf2, $19df2,
$108f4, $119f4, $108f2, $13bf4, $119f2, $13bf2, $17af0, $1bd7c, $17a78,
$1bd3e, $17a3c, $17a1e, $1f9ca, $1397c, $1fbda, $17b7c, $1393e, $17b3e,
$1f18a, $1f39a, $1f7ba, $1e10a, $1e31a, $1e73a, $1ef7a, $1c21a, $1c63a,
$1ce7a, $1defa, $1843a, $18c7a, $19cfa, $1bdfa, $1087a, $118fa, $139fa,
$17978, $1bcbe, $1793c, $1791e, $138be, $179be, $178bc, $1789e, $1785e,
$1e0a8, $1e0a4, $1e0a2, $1c168, $1e0b6, $1c164, $1c162, $182e8, $1c176,
$182e4, $182e2, $105e8, $182f6, $105e4, $105e2, $105f6, $1f0d4, $10d7e,
$1f0d2, $1e094, $1e1b4, $1e092, $1e1b2, $1c134, $1c374, $1c132, $1c372,
$18274, $186f4, $18272, $186f2, $104f4, $10df4, $104f2, $10df2, $1f8ea,
$11d7c, $11d3e, $1f0ca, $1f1da, $1e08a, $1e19a, $1e3ba, $1c11a, $1c33a,
$1c77a, $1823a, $1867a, $18efa, $1047a, $10cfa, $11dfa, $13d78, $19ebe,
$13d3c, $13d1e, $11cbe, $13dbe, $17d70, $1bebc, $17d38, $1be9e, $17d1c,
$17d0e, $13cbc, $17dbc, $13c9e, $17d9e, $17cb8, $1be5e, $17c9c, $17c8e,
$13c5e, $17cde, $17c5c, $17c4e, $17c2e, $1c0b4, $1c0b2, $18174, $18172,
$102f4, $102f2, $1e0da, $1c09a, $1c1ba, $1813a, $1837a, $1027a, $106fa,
$10ebe, $11ebc, $11e9e, $13eb8, $19f5e, $13e9c, $13e8e, $11e5e, $13ede,
$17eb0, $1bf5c, $17e98, $1bf4e, $17e8c, $17e86, $13e5c, $17edc, $13e4e,
$17ece, $17e58, $1bf2e, $17e4c, $17e46, $13e2e, $17e6e, $17e2c, $17e26,
$10f5e, $11f5c, $11f4e, $13f58, $19fae, $13f4c, $13f46, $11f2e, $13f6e,
$13f2c, $13f26),
($1abe0, $1d5f8, $153c0, $1a9f0, $1d4fc, $151e0, $1a8f8, $1d47e, $150f0,
$1a87c, $15078, $1fad0, $15be0, $1adf8, $1fac8, $159f0, $1acfc, $1fac4,
$158f8, $1ac7e, $1fac2, $1587c, $1f5d0, $1faec, $15df8, $1f5c8, $1fae6,
$15cfc, $1f5c4, $15c7e, $1f5c2, $1ebd0, $1f5ec, $1ebc8, $1f5e6, $1ebc4,
$1ebc2, $1d7d0, $1ebec, $1d7c8, $1ebe6, $1d7c4, $1d7c2, $1afd0, $1d7ec,
$1afc8, $1d7e6, $1afc4, $14bc0, $1a5f0, $1d2fc, $149e0, $1a4f8, $1d27e,
$148f0, $1a47c, $14878, $1a43e, $1483c, $1fa68, $14df0, $1a6fc, $1fa64,
$14cf8, $1a67e, $1fa62, $14c7c, $14c3e, $1f4e8, $1fa76, $14efc, $1f4e4,
$14e7e, $1f4e2, $1e9e8, $1f4f6, $1e9e4, $1e9e2, $1d3e8, $1e9f6, $1d3e4,
$1d3e2, $1a7e8, $1d3f6, $1a7e4, $1a7e2, $145e0, $1a2f8, $1d17e, $144f0,
$1a27c, $14478, $1a23e, $1443c, $1441e, $1fa34, $146f8, $1a37e, $1fa32,
$1467c, $1463e, $1f474, $1477e, $1f472, $1e8f4, $1e8f2, $1d1f4, $1d1f2,
$1a3f4, $1a3f2, $142f0, $1a17c, $14278, $1a13e, $1423c, $1421e, $1fa1a,
$1437c, $1433e, $1f43a, $1e87a, $1d0fa, $14178, $1a0be, $1413c, $1411e,
$141be, $140bc, $1409e, $12bc0, $195f0, $1cafc, $129e0, $194f8, $1ca7e,
$128f0, $1947c, $12878, $1943e, $1283c, $1f968, $12df0, $196fc, $1f964,
$12cf8, $1967e, $1f962, $12c7c, $12c3e, $1f2e8, $1f976, $12efc, $1f2e4,
$12e7e, $1f2e2, $1e5e8, $1f2f6, $1e5e4, $1e5e2, $1cbe8, $1e5f6, $1cbe4,
$1cbe2, $197e8, $1cbf6, $197e4, $197e2, $1b5e0, $1daf8, $1ed7e, $169c0,
$1b4f0, $1da7c, $168e0, $1b478, $1da3e, $16870, $1b43c, $16838, $1b41e,
$1681c, $125e0, $192f8, $1c97e, $16de0, $124f0, $1927c, $16cf0, $1b67c,
$1923e, $16c78, $1243c, $16c3c, $1241e, $16c1e, $1f934, $126f8, $1937e,
$1fb74, $1f932, $16ef8, $1267c, $1fb72, $16e7c, $1263e, $16e3e, $1f274,
$1277e, $1f6f4, $1f272, $16f7e, $1f6f2, $1e4f4, $1edf4, $1e4f2, $1edf2,
$1c9f4, $1dbf4, $1c9f2, $1dbf2, $193f4, $193f2, $165c0, $1b2f0, $1d97c,
$164e0, $1b278, $1d93e, $16470, $1b23c, $16438, $1b21e, $1641c, $1640e,
$122f0, $1917c, $166f0, $12278, $1913e, $16678, $1b33e, $1663c, $1221e,
$1661e, $1f91a, $1237c, $1fb3a, $1677c, $1233e, $1673e, $1f23a, $1f67a,
$1e47a, $1ecfa, $1c8fa, $1d9fa, $191fa, $162e0, $1b178, $1d8be, $16270,
$1b13c, $16238, $1b11e, $1621c, $1620e, $12178, $190be, $16378, $1213c,
$1633c, $1211e, $1631e, $121be, $163be, $16170, $1b0bc, $16138, $1b09e,
$1611c, $1610e, $120bc, $161bc, $1209e, $1619e, $160b8, $1b05e, $1609c,
$1608e, $1205e, $160de, $1605c, $1604e, $115e0, $18af8, $1c57e, $114f0,
$18a7c, $11478, $18a3e, $1143c, $1141e, $1f8b4, $116f8, $18b7e, $1f8b2,
$1167c, $1163e, $1f174, $1177e, $1f172, $1e2f4, $1e2f2, $1c5f4, $1c5f2,
$18bf4, $18bf2, $135c0, $19af0, $1cd7c, $134e0, $19a78, $1cd3e, $13470,
$19a3c, $13438, $19a1e, $1341c, $1340e, $112f0, $1897c, $136f0, $11278,
$1893e, $13678, $19b3e, $1363c, $1121e, $1361e, $1f89a, $1137c, $1f9ba,
$1377c, $1133e, $1373e, $1f13a, $1f37a, $1e27a, $1e6fa, $1c4fa, $1cdfa,
$189fa, $1bae0, $1dd78, $1eebe, $174c0, $1ba70, $1dd3c, $17460, $1ba38,
$1dd1e, $17430, $1ba1c, $17418, $1ba0e, $1740c, $132e0, $19978, $1ccbe,
$176e0, $13270, $1993c, $17670, $1bb3c, $1991e, $17638, $1321c, $1761c,
$1320e, $1760e, $11178, $188be, $13378, $1113c, $17778, $1333c, $1111e,
$1773c, $1331e, $1771e, $111be, $133be, $177be, $172c0, $1b970, $1dcbc,
$17260, $1b938, $1dc9e, $17230, $1b91c, $17218, $1b90e, $1720c, $17206,
$13170, $198bc, $17370, $13138, $1989e, $17338, $1b99e, $1731c, $1310e,
$1730e, $110bc, $131bc, $1109e, $173bc, $1319e, $1739e, $17160, $1b8b8,
$1dc5e, $17130, $1b89c, $17118, $1b88e, $1710c, $17106, $130b8, $1985e,
$171b8, $1309c, $1719c, $1308e, $1718e, $1105e, $130de, $171de, $170b0,
$1b85c, $17098, $1b84e, $1708c, $17086, $1305c, $170dc, $1304e, $170ce,
$17058, $1b82e, $1704c, $17046, $1302e, $1706e, $1702c, $17026, $10af0,
$1857c, $10a78, $1853e, $10a3c, $10a1e, $10b7c, $10b3e, $1f0ba, $1e17a,
$1c2fa, $185fa, $11ae0, $18d78, $1c6be, $11a70, $18d3c, $11a38, $18d1e,
$11a1c, $11a0e, $10978, $184be, $11b78, $1093c, $11b3c, $1091e, $11b1e,
$109be, $11bbe, $13ac0, $19d70, $1cebc, $13a60, $19d38, $1ce9e, $13a30,
$19d1c, $13a18, $19d0e, $13a0c, $13a06, $11970, $18cbc, $13b70, $11938,
$18c9e, $13b38, $1191c, $13b1c, $1190e, $13b0e, $108bc, $119bc, $1089e,
$13bbc, $1199e, $13b9e, $1bd60, $1deb8, $1ef5e, $17a40, $1bd30, $1de9c,
$17a20, $1bd18, $1de8e, $17a10, $1bd0c, $17a08, $1bd06, $17a04, $13960,
$19cb8, $1ce5e, $17b60, $13930, $19c9c, $17b30, $1bd9c, $19c8e, $17b18,
$1390c, $17b0c, $13906, $17b06, $118b8, $18c5e, $139b8, $1189c, $17bb8,
$1399c, $1188e, $17b9c, $1398e, $17b8e, $1085e, $118de, $139de, $17bde,
$17940, $1bcb0, $1de5c, $17920, $1bc98, $1de4e, $17910, $1bc8c, $17908,
$1bc86, $17904, $17902, $138b0, $19c5c, $179b0, $13898, $19c4e, $17998,
$1bcce, $1798c, $13886, $17986, $1185c, $138dc, $1184e, $179dc, $138ce,
$179ce, $178a0, $1bc58, $1de2e, $17890, $1bc4c, $17888, $1bc46, $17884,
$17882, $13858, $19c2e, $178d8, $1384c, $178cc, $13846, $178c6, $1182e,
$1386e, $178ee, $17850, $1bc2c, $17848, $1bc26, $17844, $17842, $1382c,
$1786c, $13826, $17866, $17828, $1bc16, $17824, $17822, $13816, $17836,
$10578, $182be, $1053c, $1051e, $105be, $10d70, $186bc, $10d38, $1869e,
$10d1c, $10d0e, $104bc, $10dbc, $1049e, $10d9e, $11d60, $18eb8, $1c75e,
$11d30, $18e9c, $11d18, $18e8e, $11d0c, $11d06, $10cb8, $1865e, $11db8,
$10c9c, $11d9c, $10c8e, $11d8e, $1045e, $10cde, $11dde, $13d40, $19eb0,
$1cf5c, $13d20, $19e98, $1cf4e, $13d10, $19e8c, $13d08, $19e86, $13d04,
$13d02, $11cb0, $18e5c, $13db0, $11c98, $18e4e, $13d98, $19ece, $13d8c,
$11c86, $13d86, $10c5c, $11cdc, $10c4e, $13ddc, $11cce, $13dce, $1bea0,
$1df58, $1efae, $1be90, $1df4c, $1be88, $1df46, $1be84, $1be82, $13ca0,
$19e58, $1cf2e, $17da0, $13c90, $19e4c, $17d90, $1becc, $19e46, $17d88,
$13c84, $17d84, $13c82, $17d82, $11c58, $18e2e, $13cd8, $11c4c, $17dd8,
$13ccc, $11c46, $17dcc, $13cc6, $17dc6, $10c2e, $11c6e, $13cee, $17dee,
$1be50, $1df2c, $1be48, $1df26, $1be44, $1be42, $13c50, $19e2c, $17cd0,
$13c48, $19e26, $17cc8, $1be66, $17cc4, $13c42, $17cc2, $11c2c, $13c6c,
$11c26, $17cec, $13c66, $17ce6, $1be28, $1df16, $1be24, $1be22, $13c28,
$19e16, $17c68, $13c24, $17c64, $13c22, $17c62, $11c16, $13c36, $17c76,
$1be14, $1be12, $13c14, $17c34, $13c12, $17c32, $102bc, $1029e, $106b8,
$1835e, $1069c, $1068e, $1025e, $106de, $10eb0, $1875c, $10e98, $1874e,
$10e8c, $10e86, $1065c, $10edc, $1064e, $10ece, $11ea0, $18f58, $1c7ae,
$11e90, $18f4c, $11e88, $18f46, $11e84, $11e82, $10e58, $1872e, $11ed8,
$18f6e, $11ecc, $10e46, $11ec6, $1062e, $10e6e, $11eee, $19f50, $1cfac,
$19f48, $1cfa6, $19f44, $19f42, $11e50, $18f2c, $13ed0, $19f6c, $18f26,
$13ec8, $11e44, $13ec4, $11e42, $13ec2, $10e2c, $11e6c, $10e26, $13eec,
$11e66, $13ee6, $1dfa8, $1efd6, $1dfa4, $1dfa2, $19f28, $1cf96, $1bf68,
$19f24, $1bf64, $19f22, $1bf62, $11e28, $18f16, $13e68, $11e24, $17ee8,
$13e64, $11e22, $17ee4, $13e62, $17ee2, $10e16, $11e36, $13e76, $17ef6,
$1df94, $1df92, $19f14, $1bf34, $19f12, $1bf32, $11e14, $13e34, $11e12,
$17e74, $13e32, $17e72, $1df8a, $19f0a, $1bf1a, $11e0a, $13e1a, $17e3a,
$1035c, $1034e, $10758, $183ae, $1074c, $10746, $1032e, $1076e, $10f50,
$187ac, $10f48, $187a6, $10f44, $10f42, $1072c, $10f6c, $10726, $10f66,
$18fa8, $1c7d6, $18fa4, $18fa2, $10f28, $18796, $11f68, $18fb6, $11f64,
$10f22, $11f62, $10716, $10f36, $11f76, $1cfd4, $1cfd2, $18f94, $19fb4,
$18f92, $19fb2, $10f14, $11f34, $10f12, $13f74, $11f32, $13f72, $1cfca,
$18f8a, $19f9a, $10f0a, $11f1a, $13f3a, $103ac, $103a6, $107a8, $183d6,
$107a4, $107a2, $10396, $107b6, $187d4, $187d2, $10794, $10fb4, $10792,
$10fb2, $1c7ea));
type
TStPDF417TextCompactionMode = (cmAlpha, cmLower, cmMixed, cmPunctuation,
cmNone);
TStPDF417TextCompactionModes = set of TStPDF417TextCompactionMode;
TStPDF417TextCompactionData = record
Value : Integer;
Mode : TStPDF417TextCompactionModes;
end;
const
TStPDF417TextCompaction : array [0..127] of TStPDF417TextCompactionData =
((Value : -1; Mode : []), { 000 }
(Value : -1; Mode : []), { 001 }
(Value : -1; Mode : []), { 002 }
(Value : -1; Mode : []), { 003 }
(Value : -1; Mode : []), { 004 }
(Value : -1; Mode : []), { 005 }
(Value : -1; Mode : []), { 006 }
(Value : -1; Mode : []), { 007 }
(Value : -1; Mode : []), { 008 }
(Value : 12; Mode : [cmMixed, cmPunctuation]), { 009 }
(Value : 15; Mode : [cmPunctuation]), { 010 }
(Value : -1; Mode : []), { 011 }
(Value : -1; Mode : []), { 012 }
(Value : 11; Mode : [cmMixed, cmPunctuation]), { 013 }
(Value : -1; Mode : []), { 014 }
(Value : -1; Mode : []), { 015 }
(Value : -1; Mode : []), { 016 }
(Value : -1; Mode : []), { 017 }
(Value : -1; Mode : []), { 018 }
(Value : -1; Mode : []), { 019 }
(Value : -1; Mode : []), { 020 }
(Value : -1; Mode : []), { 021 }
(Value : -1; Mode : []), { 022 }
(Value : -1; Mode : []), { 023 }
(Value : -1; Mode : []), { 024 }
(Value : -1; Mode : []), { 025 }
(Value : -1; Mode : []), { 026 }
(Value : -1; Mode : []), { 027 }
(Value : -1; Mode : []), { 028 }
(Value : -1; Mode : []), { 029 }
(Value : -1; Mode : []), { 030 }
(Value : -1; Mode : []), { 031 }
(Value : 26; Mode : [cmAlpha, cmLower, cmMixed]), { 032 }
(Value : 10; Mode : [cmPunctuation]), { 033 }
(Value : 20; Mode : [cmPunctuation]), { 034 }
(Value : 15; Mode : [cmMixed]), { 035 }
(Value : 18; Mode : [cmMixed, cmPunctuation]), { 036 }
(Value : 21; Mode : [cmMixed]), { 037 }
(Value : 10; Mode : [cmMixed]), { 038 }
(Value : 28; Mode : [cmPunctuation]), { 039 }
(Value : 23; Mode : [cmPunctuation]), { 040 }
(Value : 24; Mode : [cmPunctuation]), { 041 }
(Value : 22; Mode : [cmMixed, cmPunctuation]), { 042 }
(Value : 20; Mode : [cmMixed]), { 043 }
(Value : 13; Mode : [cmMixed, cmPunctuation]), { 044 }
(Value : 16; Mode : [cmMixed, cmPunctuation]), { 045 }
(Value : 17; Mode : [cmMixed, cmPunctuation]), { 046 }
(Value : 19; Mode : [cmMixed, cmPunctuation]), { 047 }
(Value : 0; Mode : [cmMixed]), { 048 }
(Value : 1; Mode : [cmMixed]), { 049 }
(Value : 2; Mode : [cmMixed]), { 050 }
(Value : 3; Mode : [cmMixed]), { 051 }
(Value : 4; Mode : [cmMixed]), { 052 }
(Value : 5; Mode : [cmMixed]), { 053 }
(Value : 6; Mode : [cmMixed]), { 054 }
(Value : 7; Mode : [cmMixed]), { 055 }
(Value : 8; Mode : [cmMixed]), { 056 }
(Value : 9; Mode : [cmMixed]), { 057 }
(Value : 14; Mode : [cmMixed, cmPunctuation]), { 058 }
(Value : 0; Mode : [cmPunctuation]), { 059 }
(Value : 1; Mode : [cmPunctuation]), { 060 }
(Value : 23; Mode : [cmMixed]), { 061 }
(Value : 2; Mode : [cmPunctuation]), { 062 }
(Value : 25; Mode : [cmPunctuation]), { 063 }
(Value : 3; Mode : [cmPunctuation]), { 064 }
(Value : 0; Mode : [cmAlpha]), { 065 }
(Value : 1; Mode : [cmAlpha]), { 066 }
(Value : 2; Mode : [cmAlpha]), { 067 }
(Value : 3; Mode : [cmAlpha]), { 068 }
(Value : 4; Mode : [cmAlpha]), { 069 }
(Value : 5; Mode : [cmAlpha]), { 070 }
(Value : 6; Mode : [cmAlpha]), { 071 }
(Value : 7; Mode : [cmAlpha]), { 072 }
(Value : 8; Mode : [cmAlpha]), { 073 }
(Value : 9; Mode : [cmAlpha]), { 074 }
(Value : 10; Mode : [cmAlpha]), { 075 }
(Value : 11; Mode : [cmAlpha]), { 076 }
(Value : 12; Mode : [cmAlpha]), { 077 }
(Value : 13; Mode : [cmAlpha]), { 078 }
(Value : 14; Mode : [cmAlpha]), { 079 }
(Value : 15; Mode : [cmAlpha]), { 080 }
(Value : 16; Mode : [cmAlpha]), { 081 }
(Value : 17; Mode : [cmAlpha]), { 082 }
(Value : 18; Mode : [cmAlpha]), { 083 }
(Value : 19; Mode : [cmAlpha]), { 084 }
(Value : 20; Mode : [cmAlpha]), { 085 }
(Value : 21; Mode : [cmAlpha]), { 086 }
(Value : 22; Mode : [cmAlpha]), { 087 }
(Value : 23; Mode : [cmAlpha]), { 088 }
(Value : 24; Mode : [cmAlpha]), { 089 }
(Value : 25; Mode : [cmAlpha]), { 090 }
(Value : 4; Mode : [cmPunctuation]), { 091 }
(Value : 5; Mode : [cmPunctuation]), { 092 }
(Value : 6; Mode : [cmPunctuation]), { 093 }
(Value : 24; Mode : [cmMixed]), { 094 }
(Value : 7; Mode : [cmPunctuation]), { 095 }
(Value : 8; Mode : [cmPunctuation]), { 096 }
(Value : 0; Mode : [cmLower]), { 097 }
(Value : 1; Mode : [cmLower]), { 098 }
(Value : 2; Mode : [cmLower]), { 099 }
(Value : 3; Mode : [cmLower]), { 100 }
(Value : 4; Mode : [cmLower]), { 101 }
(Value : 5; Mode : [cmLower]), { 102 }
(Value : 6; Mode : [cmLower]), { 103 }
(Value : 7; Mode : [cmLower]), { 104 }
(Value : 8; Mode : [cmLower]), { 105 }
(Value : 9; Mode : [cmLower]), { 106 }
(Value : 10; Mode : [cmLower]), { 107 }
(Value : 11; Mode : [cmLower]), { 108 }
(Value : 12; Mode : [cmLower]), { 109 }
(Value : 13; Mode : [cmLower]), { 110 }
(Value : 14; Mode : [cmLower]), { 111 }
(Value : 15; Mode : [cmLower]), { 112 }
(Value : 16; Mode : [cmLower]), { 113 }
(Value : 17; Mode : [cmLower]), { 114 }
(Value : 18; Mode : [cmLower]), { 115 }
(Value : 19; Mode : [cmLower]), { 116 }
(Value : 20; Mode : [cmLower]), { 117 }
(Value : 21; Mode : [cmLower]), { 118 }
(Value : 22; Mode : [cmLower]), { 119 }
(Value : 23; Mode : [cmLower]), { 120 }
(Value : 24; Mode : [cmLower]), { 121 }
(Value : 25; Mode : [cmLower]), { 122 }
(Value : 26; Mode : [cmPunctuation]), { 123 }
(Value : 21; Mode : [cmPunctuation]), { 124 }
(Value : 27; Mode : [cmPunctuation]), { 125 }
(Value : 9; Mode : [cmPunctuation]), { 126 }
(Value : -1; Mode : [])); { 127 }
{ TStMaxiCode types and constants }
type
TStMaxiCodeCodeSet = (csCodeSetA, csCodeSetB, csCodeSetC, csCodeSetD,
csCodeSetE, csNone);
const
StMaxiCodeCodeSets : array [csCodeSetA..csCodeSetE] of
array [0..255] of ShortInt =
{ csCodeSetA }
{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}
((-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {000}
-1, -1, -1, 0, -1, -1, -1, -1, -1, -1, {010}
-1, -1, -1, -1, -1, -1, -1, -1, 28, 29, {020}
30, -1, 32, 33, 34, 35, 36, 37, 38, 39, {030}
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, {040}
50, 51, 52, 53, 54, 55, 56, 57, 58, -1, {050}
-1, -1, -1, -1, -1, 1, 2, 3, 4, 5, {060}
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, {070}
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, {080}
26, -1, -1, -1, -1, -1, -1, -1, -1, -1, {090}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {100}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {110}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {120}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {130}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {140}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {150}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {160}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {170}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {180}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {190}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {200}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {210}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {220}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {230}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {240}
-1, -1, -1, -1, -1, -1), {250}
{ csCodeSetB }
{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}
(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {000}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {010}
-1, -1, -1, -1, -1, -1, -1, -1, 28, 29, {020}
30, -1, 47, 53, -1, -1, -1, -1, -1, -1, {030}
-1, -1, -1, -1, 48, 49, 50, -1, -1, -1, {040}
-1, -1, -1, -1, -1, -1, -1, -1, 51, 37, {050}
38, 39, 40, 41, 52, -1, -1, -1, -1, -1, {060}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {070}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {080}
-1, 42, 43, 44, 45, 46, 0, 1, 2, 3, {090}
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, {100}
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, {110}
24, 25, 26, 32, 54, 34, 35, 36, -1, -1, {120}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {130}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {140}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {150}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {160}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {170}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {180}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {190}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {200}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {210}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {220}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {230}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {240}
-1, -1, -1, -1, -1, -1), {250}
{ csCodeSetC }
{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}
(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {000}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {010}
-1, -1, -1, -1, -1, -1, -1, -1, 28, 29, {020}
30, -1, 59, -1, -1, -1, -1, -1, -1, -1, {030}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {040}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {050}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {060}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {070}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {080}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {090}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {100}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {110}
-1, -1, -1, -1, -1, -1, -1, -1, 48, 49, {120}
50, 51, 52, 53, 54, 55, 56, 57, -1, -1, {130}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {140}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {150}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {160}
37, -1, 38, -1, -1, -1, -1, 39, 40, 41, {170}
-1, 42, -1, -1, -1, 43, 44, -1, 45, 46, {180}
47, -1, 0, 1, 2, 3, 4, 5, 6, 7, {190}
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, {200}
18, 19, 20, 21, 22, 23, 24, 25, 26, 32, {210}
33, 34, 35, 36, -1, -1, -1, -1, -1, -1, {220}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {230}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {240}
-1, -1, -1, -1, -1, -1), {250}
{ csCodeSetD }
{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}
(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {000}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {010}
-1, -1, -1, -1, -1, -1, -1, -1, 28, 29, {020}
30, -1, 59, -1, -1, -1, -1, -1, -1, -1, {030}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {040}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {050}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {060}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {070}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {080}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {090}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {100}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {110}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {120}
-1, -1, -1, -1, -1, -1, -1, -1, 47, 48, {130}
49, 50, 51, 52, 53, 54, 55, 56, 57, -1, {140}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {150}
-1, 37, -1, -1, -1, -1, -1, -1, 38, -1, {160}
-1, 39, -1, -1, -1, 40, 41, -1, -1, -1, {170}
42, -1, -1, 43, 44, -1, -1, 45, -1, -1, {180}
-1, 46, -1, -1, -1, -1, -1, -1, -1, -1, {190}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {200}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {210}
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5, {220}
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, {230}
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, {240}
26, 32, 33, 34, 35, 36), {250}
{ csCodeSetE }
{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}
( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, {000}
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, {010}
20, 21, 22, 23, 24, 25, 26, 30, 32, 33, {020}
34, 35, 59, -1, -1, -1, -1, -1, -1, -1, {030}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {040}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {050}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {060}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {070}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {080}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {090}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {100}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {110}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {120}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {130}
-1, -1, -1, -1, -1, -1, -1, -1, -1, 48, {140}
49, 50, 51, 52, 53, 54, 55, 56, 57, 36, {150}
37, -1, 38, 39, 40, 41, 42, 43, -1, 44, {160}
-1, -1, -1, 45, 46, -1, -1, -1, -1, -1, {170}
-1, -1, 47, -1, -1, -1, -1, -1, -1, -1, {180}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {190}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {200}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {210}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {220}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {230}
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, {240}
-1, -1, -1, -1, -1, -1)); {250}
{ TStCustom2DBarcode }
constructor TStCustom2DBarcode.Create (AOwner : TComponent);
begin
inherited Create (AOwner);
FBitmap := TBitmap.Create;
FBarWidth := 2;
FBarHeight := 0;
FBackgroundColor := clWhite;
FExtendedSyntax := True;
FQuietZone := 8;
FAlignment := taCenter;
FCaptionLayout := tlBottom;
Width := 329;
Height := 50;
Color := clBlack;
FECCLevel := 2;
FRelativeBarHeight := False;
FBarHeightToWidth := 4;
FBarHeight := 2;
FCaption := '';
FCode := '';
FECCLevel := 0;
end;
destructor TStCustom2DBarcode.Destroy;
begin
FBitmap.Free;
inherited Destroy;
end;
procedure TStCustom2DBarcode.CopyToClipboard;
begin
CopyToClipboardRes (0, 0);
end;
procedure TStCustom2DBarcode.CopyToClipboardRes (ResX : Integer;
ResY : Integer);
var
{$IFNDEF FPC}
MetaFile : TMetaFile;
MetaFileCanvas : TMetaFileCanvas;
{$ENDIF}
RenderBMP : TBitmap;
SizeX : Integer;
SizeY : Integer;
begin
Clipboard.Clear;
Clipboard.Open;
try
RenderBmp := TBitmap.Create;
try
RenderToResolution (RenderBmp, ResX, ResY, SizeX, SizeY);
Clipboard.Assign (RenderBmp);
{$IFNDEF FPC}
{metafile}
MetaFile := TMetaFile.Create;
try
MetaFileCanvas := TMetaFileCanvas.Create (MetaFile, 0);
try
MetaFile.Enhanced := True;
MetaFile.Width := ClientWidth;
MetaFile.Height := ClientHeight;
MetaFileCanvas.Draw (0, 0, RenderBmp);
finally
MetaFileCanvas.Free;
end;
Clipboard.Assign (MetaFile);
finally
MetaFile.Free;
end;
{$ENDIF}
finally
RenderBmp.Free;
end;
finally
Clipboard.Close;
end;
end;
procedure TStCustom2DBarcode.GenerateBarcodeBitmap (BCWidth : Integer;
BCHeight : Integer);
var
TextHeight : Integer;
TextWidth : Integer;
XPos : Integer;
YPos : Integer;
TopOffset : Integer;
BottomOffset : Integer;
BarCodeHeight : Integer;
BarCodeWidth : Integer;
RWidthOffset : Integer;
LWidthOffset : Integer;
PaintHeight : Integer;
begin
{ Initialize the canvas }
FBitmap.Width := BCWidth;
FBitmap.Height := BCHeight;
FBitmap.Canvas.Pen.Color := Color;
FBitmap.Canvas.Brush.Color := BackgroundColor;
FBitmap.Canvas.FillRect (Rect (0, 0, BCWidth, BCHeight));
FBitmap.Canvas.Brush.Color := Color;
{ Calculate the size of the caption }
FBitmap.Canvas.Font.Assign (Font);
TextHeight := FBitmap.Canvas.TextHeight ('Yg0');
TextWidth := FBitmap.Canvas.TextWidth (Caption);
{ determine x position of the caption }
XPos := 0;
case FAlignment of
taLeftJustify :
XPos := 0;
taRightJustify :
if BCWidth - TextWidth > 0 then
XPos := BCWidth - TextWidth
else
XPos := 0;
taCenter :
if BCWidth - TextWidth > 0 then
XPos := BCWidth div 2 - TextWidth div 2
else
XPos := 0;
end;
{ determine the y position of the caption. In addition, determine offsets
for the barcode painting. }
TopOffset := 0;
BottomOffset := 0;
YPos := 0;
case FCaptionLayout of
tlBottom :
begin
if BCHeight - 2 - TextHeight > 0 then
YPos := BCHeight - 2 - TextHeight
else
YPos := 0;
if Caption <> '' then
BottomOffset := TextHeight + 4;
end;
tlTop :
begin
YPos := 0;
if Caption <> '' then
TopOffset := TextHeight + 4;
end;
tlCenter :
if BCHeight - TextHeight > 0 then
YPos := BCHeight div 2 - TextHeight div 2
else
YPos := 0;
end;
{ determine the size of the barcode and calculate the rectangle the
barcode should be painted in. Take into account the size of the
caption (and it's existance), and the quiet zone.}
PaintHeight := BCHeight - QuietZone * 2 - BottomOffset - TopOffset;
BarCodeHeight := CalculateBarCodeHeight (PaintHeight);
BarCodeWidth := CalculateBarCodeWidth (BCWidth);
if BarCodeHeight < PaintHeight then begin
Inc (BottomOffset, (PaintHeight - BarCodeHeight) div 2);
Inc (TopOffset, (PaintHeight - BarCodeHeight) div 2);
end;
{ Position the barcode horizontally }
LWidthOffset := QuietZone;
RWidthOffset := QuietZone;
if BarCodeWidth < BCWidth - QuietZone * 2 then
case Alignment of
taLeftJustify :
begin
LWidthOffset := QuietZone;
RWidthOffset := BCWidth - BarCodeWidth - QuietZone;
end;
taRightJustify :
begin
RWidthOffset := QuietZone;
LWidthOffset := BCWidth - BarCodeWidth - QuietZone;
end;
taCenter :
begin
LWidthOffset := (BCWidth - BarCodeWidth) div 2;
RWidthOffset := (BCWidth - BarCodeWidth) div 2;
end;
end;
{ Save the barcode rectangle }
FBarCodeRect := Rect (LWidthOffset,
QuietZone + TopOffset,
BCWidth - RWidthOffset,
BCHeight - QuietZone - BottomOffset);
{ Draw the barcode }
DrawBarcode;
FBitmap.Canvas.Brush.Color := BackgroundColor;
{ Draw the caption }
FBitmap.Canvas.TextOut (XPos, YPos, Caption);
end;
function TStCustom2DBarcode.GetBarCodeHeight : Integer;
begin
Result := CalculateBarCodeHeight (Height);
end;
function TStCustom2DBarcode.GetBarCodeWidth : Integer;
begin
Result := CalculateBarCodeWidth (Width);
end;
procedure TStCustom2DBarcode.GetCurrentResolution (var ResX : Integer;
var ResY : Integer);
begin
ResX := GetDeviceCaps (FBitmap.Canvas.Handle, LOGPIXELSX);
ResY := GetDeviceCaps (FBitmap.Canvas.Handle, LOGPIXELSY);
end;
function TStCustom2DBarcode.GetVersion : string;
begin
Result := StVersionStr;
end;
procedure TStCustom2DBarcode.Paint;
begin
GenerateBarcodeBitmap (Width, Height);
Canvas.CopyRect (Rect (0, 0, Width, Height),
FBitmap.Canvas,
Rect (0, 0, Width, Height));
end;
procedure TStCustom2DBarcode.PaintToCanvas (ACanvas : TCanvas;
Position : TPoint);
begin
PaintToDC (ACanvas.Handle, Position);
end;
procedure TStCustom2DBarcode.PaintToCanvasRes (ACanvas : TCanvas;
Position : TPoint;
ResX : Integer;
ResY : Integer);
begin
PaintToDCRes (ACanvas.Handle, Position, ResX, ResY);
end;
procedure TStCustom2DBarcode.PaintToCanvasSize (ACanvas : TCanvas;
X, Y, H : Double);
var
PixelsPerInchX : Integer;
PixelsPerInchY : Integer;
begin
{get some information about this device context}
PixelsPerInchX := GetDeviceCaps (ACanvas.Handle, LOGPIXELSX);
PixelsPerInchY := GetDeviceCaps (ACanvas.Handle, LOGPIXELSY);
PaintToCanvasRes (ACanvas,
Point (Round (PixelsPerInchX * X),
Round (PixelsPerInchY * Y)),
Round (PixelsPerInchX * H),
Round (PixelsPerInchY * H));
end;
procedure TStCustom2DBarcode.PaintToDC (DC : hDC; Position : TPoint);
var
NewResX : Integer;
NewResY : Integer;
begin
NewResX := GetDeviceCaps (DC, LOGPIXELSX);
NewResY := GetDeviceCaps (DC, LOGPIXELSY);
PaintToDCRes (DC, Position, NewResX, NewResY);
end;
procedure TStCustom2DBarcode.PaintToDCRes (DC : hDC; Position : TPoint;
ResX : Integer; ResY : Integer);
var
ACanvas : TCanvas;
R1 : TRect;
R2 : TRect;
RenderBmp : TBitmap;
SizeX : Integer;
SizeY : Integer;
begin
ACanvas := TCanvas.Create;
ACanvas.Handle := DC;
try
RenderBmp := TBitmap.Create;
try
{this is necessary because of a Delphi buglet}
RenderBmp.Canvas.Font.PixelsPerInch := ResY;
{use our font}
RenderBmp.Canvas.Font := Font;
RenderToResolution (RenderBmp, ResX, ResY, SizeX, SizeY);
R1 := Rect (0, 0, RenderBmp.Width, RenderBmp.Height);
R2 := Rect (Position.X, Position.Y,
RenderBmp.Width + Position.X,
RenderBmp.Height + Position.Y);
ACanvas.CopyRect (R2, RenderBmp.Canvas, R1);
finally
RenderBmp.Free;
end;
finally
ACanvas.Free;
end;
end;
procedure TStCustom2DBarcode.PaintToPrinterCanvas (ACanvas : TCanvas;
Position : TPoint);
begin
PaintToPrinterDC (ACanvas.Handle, Position);
end;
procedure TStCustom2DBarcode.PaintToPrinterCanvasRes (ACanvas : TCanvas;
Position : TPoint;
ResX : Integer;
ResY : Integer);
begin
PaintToPrinterDCRes (ACanvas.Handle, Position, ResX, ResY);
end;
procedure TStCustom2DBarcode.PaintToPrinterCanvasSize (ACanvas : TCanvas;
X, Y, H : Double);
var
PixelsPerInchX : Integer;
PixelsPerInchY : Integer;
begin
{get some information about this device context}
PixelsPerInchX := GetDeviceCaps (ACanvas.Handle, LOGPIXELSX);
PixelsPerInchY := GetDeviceCaps (ACanvas.Handle, LOGPIXELSY);
PaintToPrinterCanvasRes (ACanvas,
Point (Round (PixelsPerInchX * X),
Round (PixelsPerInchY * Y)),
Round (PixelsPerInchX * H),
Round (PixelsPerInchY * H));
end;
procedure TStCustom2DBarcode.PaintToPrinterDC (DC : hDC; Position : TPoint);
var
NewResX : Integer;
NewResY : Integer;
begin
NewResX := GetDeviceCaps (DC, LOGPIXELSX);
NewResY := GetDeviceCaps (DC, LOGPIXELSY);
PaintToPrinterDCRes (DC, Position, NewResX, NewResY);
end;
procedure TStCustom2DBarcode.PaintToPrinterDCRes (DC : hDC;
Position : TPoint;
ResX : Integer;
ResY : Integer);
var
ACanvas : TCanvas;
R2 : TRect;
Info : PBitMapInfo;
InfoSize : DWORD;
ImageSize : DWORD;
Image : Pointer;
RenderBmp : TBitmap;
SizeX : Integer;
SizeY : Integer;
begin
(* ---------- to do: fix me for Lazarus ---------
ACanvas := TCanvas.Create;
ACanvas.Handle := DC;
try
RenderBmp := TBitmap.Create;
try
{this is necessary because of a Delphi buglet}
RenderBmp.Canvas.Font.PixelsPerInch := ResY;
{use our font}
RenderBmp.Canvas.Font.Assign (Font);
RenderToResolution (RenderBmp, ResX, ResY, SizeX, SizeY);
R2 := Rect (Position.X, Position.Y,
SizeX + Position.X,
SizeY + Position.Y);
{Delphi does not allow a simple Canvas.CopyRect to the printer Canvas}
with RenderBmp do begin
GetDIBSizes (Handle, InfoSize, ImageSize);
GetMem (Info, InfoSize);
try
GetMem (Image, ImageSize);
try
GetDIB (Handle, Palette, Info^, Image^);
with Info^.bmiHeader do begin
StretchDIBits (ACanvas.Handle,
R2.Left, R2.Top, SizeX, SizeY,
0, 0, biWidth, biHeight,
Image, Info^, DIB_RGB_COLORS, SRCCOPY);
end;
finally
FreeMem (Image, ImageSize)
end;
finally
FreeMem (Info, InfoSize);
end;
end;
finally
RenderBmp.Free;
end;
finally
ACanvas.Free;
end;
*)
end;
procedure TStCustom2DBarcode.SaveToFile (const FileName : string);
begin
GenerateBarcodeBitmap (Width, Height);
FBitmap.SaveToFile (FileName);
end;
procedure TStCustom2DBarcode.SaveToFileRes (const FileName : string;
ResX : Integer; ResY : Integer);
var
RenderBmp : TBitmap;
SizeX : Integer;
SizeY : Integer;
begin
RenderBmp := TBitmap.Create;
try
RenderToResolution (RenderBmp, ResX, ResY, SizeX, SizeY);
RenderBmp.SaveToFile (FileName);
finally
RenderBmp.Free;
end;
end;
procedure TStCustom2DBarcode.SetAlignment (const v : TAlignment);
var
OldAlignment : TAlignment;
begin
if v <> FAlignment then begin
OldAlignment := FAlignment;
try
FAlignment := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FAlignment := OldAlignment;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetBackgroundColor (const v : TColor);
var
OldBackgroundColor : TColor;
begin
if v <> FBackgroundColor then begin
OldBackgroundColor := FBackgroundColor;
try
FBackgroundColor := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FBackgroundColor := OldBackgroundColor;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetBarHeight (const v : Integer);
var
OldBarHeight : Integer;
begin
if v <> FBarHeight then begin
OldBarHeight := FBarHeight;
try
FBarHeight := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FBarHeight := OldBarHeight;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetBarHeightToWidth (const v : Integer);
var
OldBarHeightToWidth : Integer;
begin
if v <> FBarHeightToWidth then begin
if v < 0 then
raise E2DBarcodeError.Create (StEBadBarHeightToWidth);
OldBarHeightToWidth := FBarHeightToWidth;
try
FBarHeightToWidth := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FBarHeightToWidth := OldBarHeightToWidth;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetBarWidth (const v : Integer);
var
OldBarWidth : Integer;
begin
if v <> FBarWidth then begin
OldBarWidth := FBarWidth;
try
FBarWidth := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FBarWidth := OldBarWidth;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetBitmap (const v : TBitmap);
begin
FBitmap.Assign (v);
Invalidate;
end;
procedure TStCustom2DBarcode.SetCaption (const v : string);
var
OldCaption : string;
begin
if v <> FCaption then begin
OldCaption := FCaption;
try
FCaption := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FCaption := OldCaption;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetCaptionLayout (const v : TTextLayout);
var
OldCaptionLayout : TTextLayout;
begin
if v <> FCaptionLayout then begin
OldCaptionLayout := FCaptionLayout;
try
FCaptionLayout := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FCaptionLayout := OldCaptionLayout;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetCode (const v : string);
var
OldCode : string;
begin
if v <> FCode then begin
OldCode := FCode;
try
FCode := v;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FCode := OldCode;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetECCLevel (const v : Integer);
var
OldECCLevel : Integer;
begin
if v <> FECCLevel then begin
OldECCLevel := FECCLevel;
try
FECCLevel := v;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FECCLevel := OldECCLevel;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetExtendedSyntax (const v : Boolean);
var
OldExtendedSyntax : Boolean;
begin
if v <> FExtendedSyntax then begin
OldExtendedSyntax := FExtendedSyntax;
try
FExtendedSyntax := v;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FExtendedSyntax := OldExtendedSyntax;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetQuietZone (const v : Integer);
var
OldQuietZone : Integer;
begin
if v <> FQuietZone then begin
if (v < 0) then
raise E2DBarcodeError.Create (StEBadQuietZone);
OldQuietZone := FQuietZone;
try
FQuietZone := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FQuietZone := OldQuietZone;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetRelativeBarHeight (const v : Boolean);
var
OldRelativeBarHeight : Boolean;
begin
if v <> FRelativeBarHeight then begin
OldRelativeBarHeight := FRelativeBarHeight;
try
FRelativeBarHeight := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FRelativeBarHeight := OldRelativeBarHeight;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStCustom2DBarcode.SetVersion(const Value : string);
begin
end;
{ TStPDF417Barcode }
constructor TStPDF417Barcode.Create (AOwner : TComponent);
begin
inherited Create (AOwner);
FNumCodewords := 1;
FTruncated := False;
FHighlight := False;
FECCLevel := -1;
FNumRows := 0;
FNumColumns := 0;
FTotalCodewords := FNumRows * FNumColumns;
FUsedCodewords := 0;
FUsedECCCodewords := 0;
FFreeCodewords := FTotalCodewords;
Width := 273;
Height := 81;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
end;
procedure TStPDF417Barcode.AddCodeword (Value : Word);
begin
FCodewords[FNumCodewords] := Value;
Inc (FNumCodewords);
end;
function TStPDF417Barcode.CalculateBarCodeWidth (
PaintableWidth : Integer) : Integer;
var
XSize : Integer;
YSize : Integer;
begin
CalculateSize (XSize, YSize);
if Truncated then
Result := (XSize + 2) * 17 * BarWidth + BarWidth
else
Result := (XSize + 4) * 17 * BarWidth + BarWidth;
end;
function TStPDF417Barcode.CalculateBarCodeHeight (
PaintableHeight : Integer) : Integer;
var
XSize : Integer;
YSize : Integer;
begin
CalculateSize (XSize, YSize);
if RelativeBarHeight then
Result := PaintableHeight
else if BarHeightToWidth <> 0 then
Result := (BarHeightToWidth * BarWidth) * YSize
else
Result := BarHeight * YSize;
end;
procedure TStPDF417Barcode.CalculateECC (NumCodewords : Integer;
ECCLen : Integer);
const
StMods : array [0..64] of array [0..64] of Integer =
(( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(917, 27, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(890, 351, 200, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(809, 723, 568, 522, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(566, 155, 460, 919, 427, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(766, 17, 803, 19, 285, 861, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(437, 691, 784, 597, 537, 925, 76, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(379, 428, 653, 646, 284, 436, 308, 237,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(205, 441, 501, 362, 289, 257, 622, 527,
567, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(612, 266, 691, 818, 841, 826, 244, 64,
457, 377, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(904, 602, 327, 68, 15, 213, 825, 708,
565, 45, 462, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(851, 69, 7, 388, 127, 347, 684, 646,
201, 757, 864, 597, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(692, 394, 184, 204, 678, 592, 322, 583,
606, 384, 342, 713, 764, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(215, 105, 833, 691, 915, 478, 354, 274,
286, 241, 187, 154, 677, 669, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(642, 868, 147, 575, 550, 74, 80, 5,
230, 664, 904, 109, 476, 829, 460, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 65, 176, 42, 295, 428, 442, 116, 295,
132, 801, 524, 599, 755, 232, 562, 274,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(192, 70, 98, 55, 733, 916, 510, 163,
437, 843, 61, 259, 650, 430, 298, 115,
425, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(573, 760, 756, 233, 321, 560, 202, 312,
297, 120, 739, 275, 855, 37, 624, 315,
577, 279, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(787, 754, 821, 371, 17, 508, 201, 806,
177, 506, 407, 491, 249, 923, 181, 75,
170, 200, 250, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(500, 632, 880, 710, 375, 274, 258, 717,
176, 802, 109, 736, 540, 64, 45, 152,
12, 647, 448, 712, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(568, 259, 193, 165, 347, 691, 310, 610,
624, 693, 763, 716, 422, 553, 681, 425,
129, 534, 781, 519, 108, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(772, 6, 76, 519, 563, 875, 66, 678,
578, 716, 927, 296, 633, 244, 155, 928,
432, 838, 95, 55, 78, 665, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(455, 538, 32, 581, 473, 772, 462, 194,
251, 503, 631, 1, 630, 247, 843, 101,
749, 457, 143, 597, 294, 93, 78, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(433, 747, 273, 806, 697, 585, 200, 249,
628, 555, 713, 54, 608, 322, 54, 135,
385, 701, 308, 238, 166, 128, 819, 142,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(367, 39, 208, 439, 454, 104, 608, 55,
916, 912, 314, 375, 760, 141, 169, 287,
765, 374, 492, 348, 251, 320, 732, 899,
847, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(169, 764, 847, 131, 858, 325, 454, 441,
245, 699, 893, 446, 830, 159, 121, 269,
608, 331, 760, 477, 93, 788, 544, 887,
284, 443, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(504, 710, 383, 531, 151, 694, 636, 175,
269, 93, 21, 463, 671, 438, 433, 857,
610, 560, 165, 531, 100, 357, 688, 114,
149, 825, 694, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(580, 925, 461, 840, 560, 93, 427, 203,
563, 99, 586, 201, 557, 339, 277, 321,
712, 470, 920, 65, 509, 525, 879, 378,
452, 72, 222, 720, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(808, 318, 478, 42, 706, 500, 264, 14,
397, 261, 862, 33, 864, 62, 462, 305,
509, 231, 316, 800, 465, 452, 738, 126,
239, 9, 845, 241, 656, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(563, 235, 604, 915, 635, 324, 392, 364,
683, 541, 89, 655, 211, 194, 136, 453,
104, 12, 390, 487, 484, 794, 549, 471,
26, 910, 498, 383, 138, 926, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(757, 764, 673, 108, 706, 886, 76, 234,
695, 196, 66, 270, 8, 252, 612, 825,
660, 679, 860, 898, 204, 861, 371, 142,
358, 380, 528, 379, 120, 757, 347, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(410, 63, 330, 685, 390, 231, 133, 803,
320, 571, 800, 593, 147, 263, 494, 273,
517, 193, 284, 687, 742, 677, 742, 536,
321, 640, 586, 176, 525, 922, 575, 361,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(575, 871, 311, 454, 504, 870, 199, 768,
634, 362, 548, 855, 529, 384, 830, 923,
222, 85, 841, 59, 518, 590, 358, 110,
695, 864, 699, 581, 642, 175, 836, 855,
709, 274, 686, 244, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 5, 10, 156, 729, 684, 324, 60, 264,
99, 261, 89, 460, 742, 208, 699, 670,
512, 404, 726, 389, 492, 287, 894, 571,
41, 203, 353, 256, 243, 784, 385, 555,
595, 734, 714, 565, 205, 706, 316, 115,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(285, 82, 730, 339, 436, 572, 271, 103,
758, 231, 560, 31, 213, 272, 267, 569,
773, 3, 21, 446, 706, 413, 97, 376,
60, 714, 436, 417, 405, 632, 25, 109,
876, 470, 915, 157, 840, 764, 64, 678,
848, 659, 36, 476, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(669, 912, 896, 252, 338, 162, 414, 632,
626, 252, 869, 185, 444, 82, 920, 783,
565, 875, 126, 877, 524, 603, 189, 136,
373, 540, 649, 271, 836, 540, 199, 323,
888, 486, 92, 849, 162, 701, 178, 926,
498, 575, 765, 422, 450, 302, 354, 710,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(187, 57, 15, 317, 835, 593, 8, 158,
95, 145, 37, 659, 576, 386, 884, 913,
495, 869, 908, 296, 437, 215, 33, 883,
877, 477, 712, 578, 349, 13, 174, 839,
914, 107, 260, 40, 532, 210, 395, 905,
163, 785, 693, 627, 393, 687, 112, 481,
717, 297, 37, 483, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(163, 726, 626, 653, 414, 537, 467, 579,
729, 396, 142, 598, 860, 774, 518, 461,
136, 687, 827, 614, 841, 468, 207, 481,
649, 910, 497, 686, 186, 235, 845, 863,
821, 711, 663, 534, 393, 756, 467, 224,
442, 520, 210, 732, 864, 729, 433, 735,
70, 184, 278, 97, 492, 17, 2, 338,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 77, 611, 467, 704, 555, 579, 802, 773,
303, 518, 560, 196, 314, 102, 5, 845,
248, 125, 836, 923, 88, 630, 886, 619,
37, 141, 409, 229, 77, 658, 450, 449,
93, 651, 276, 501, 166, 75, 630, 701,
388, 72, 830, 166, 187, 131, 711, 577,
834, 147, 361, 517, 76, 581, 45, 495,
366, 278, 781, 61, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
( 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0),
(543, 264, 623, 843, 381, 4, 629, 840,
771, 280, 97, 404, 83, 717, 733, 648,
502, 488, 201, 651, 158, 605, 352, 517,
535, 225, 594, 460, 31, 519, 35, 440,
184, 283, 762, 672, 400, 511, 376, 543,
822, 858, 609, 430, 172, 462, 476, 723,
612, 381, 877, 733, 505, 107, 287, 610,
106, 453, 771, 862, 93, 6, 422, 539, 0));
StMods128 : array [0..127] of Integer =
(521, 310, 864, 547, 858, 580, 296, 379,
53, 779, 897, 444, 400, 925, 749, 415,
822, 93, 217, 208, 928, 244, 583, 620,
246, 148, 447, 631, 292, 908, 490, 704,
516, 258, 457, 907, 594, 723, 674, 292,
272, 96, 684, 432, 686, 606, 860, 569,
193, 219, 129, 186, 236, 287, 192, 775,
278, 173, 40, 379, 712, 463, 646, 776,
171, 491, 297, 763, 156, 732, 95, 270,
447, 90, 507, 48, 228, 821, 808, 898,
784, 663, 627, 378, 382, 262, 380, 602,
754, 336, 89, 614, 87, 432, 670, 616,
157, 374, 242, 726, 600, 269, 375, 898,
845, 454, 354, 130, 814, 587, 804, 34,
211, 330, 539, 297, 827, 865, 37, 517,
834, 315, 550, 86, 801, 4, 108, 539);
StMods256 : array [0..255] of Integer =
(524, 894, 75, 766, 882, 857, 74, 204,
82, 586, 708, 250, 905, 786, 138, 720,
858, 194, 311, 913, 275, 190, 375, 850,
438, 733, 194, 280, 201, 280, 828, 757,
710, 814, 919, 89, 68, 569, 11, 204,
796, 605, 540, 913, 801, 700, 799, 137,
439, 418, 592, 668, 353, 859, 370, 694,
325, 240, 216, 257, 284, 549, 209, 884,
315, 70, 329, 793, 490, 274, 877, 162,
749, 812, 684, 461, 334, 376, 849, 521,
307, 291, 803, 712, 19, 358, 399, 908,
103, 511, 51, 8, 517, 225, 289, 470,
637, 731, 66, 255, 917, 269, 463, 830,
730, 433, 848, 585, 136, 538, 906, 90,
2, 290, 743, 199, 655, 903, 329, 49,
802, 580, 355, 588, 188, 462, 10, 134,
628, 320, 479, 130, 739, 71, 263, 318,
374, 601, 192, 605, 142, 673, 687, 234,
722, 384, 177, 752, 607, 640, 455, 193,
689, 707, 805, 641, 48, 60, 732, 621,
895, 544, 261, 852, 655, 309, 697, 755,
756, 60, 231, 773, 434, 421, 726, 528,
503, 118, 49, 795, 32, 144, 500, 238,
836, 394, 280, 566, 319, 9, 647, 550,
73, 914, 342, 126, 32, 681, 331, 792,
620, 60, 609, 441, 180, 791, 893, 754,
605, 383, 228, 749, 760, 213, 54, 297,
134, 54, 834, 299, 922, 191, 910, 532,
609, 829, 189, 20, 167, 29, 872, 449,
83, 402, 41, 656, 505, 579, 481, 173,
404, 251, 688, 95, 497, 555, 642, 543,
307, 159, 924, 558, 648, 55, 497, 10);
StMods512 : array [0..511] of Integer =
(352, 77, 373, 504, 35, 599, 428, 207,
409, 574, 118, 498, 285, 380, 350, 492,
197, 265, 920, 155, 914, 299, 229, 643,
294, 871, 306, 88, 87, 193, 352, 781,
846, 75, 327, 520, 435, 543, 203, 666,
249, 346, 781, 621, 640, 268, 794, 534,
539, 781, 408, 390, 644, 102, 476, 499,
290, 632, 545, 37, 858, 916, 552, 41,
542, 289, 122, 272, 383, 800, 485, 98,
752, 472, 761, 107, 784, 860, 658, 741,
290, 204, 681, 407, 855, 85, 99, 62,
482, 180, 20, 297, 451, 593, 913, 142,
808, 684, 287, 536, 561, 76, 653, 899,
729, 567, 744, 390, 513, 192, 516, 258,
240, 518, 794, 395, 768, 848, 51, 610,
384, 168, 190, 826, 328, 596, 786, 303,
570, 381, 415, 641, 156, 237, 151, 429,
531, 207, 676, 710, 89, 168, 304, 402,
40, 708, 575, 162, 864, 229, 65, 861,
841, 512, 164, 477, 221, 92, 358, 785,
288, 357, 850, 836, 827, 736, 707, 94,
8, 494, 114, 521, 2, 499, 851, 543,
152, 729, 771, 95, 248, 361, 578, 323,
856, 797, 289, 51, 684, 466, 533, 820,
669, 45, 902, 452, 167, 342, 244, 173,
35, 463, 651, 51, 699, 591, 452, 578,
37, 124, 298, 332, 552, 43, 427, 119,
662, 777, 475, 850, 764, 364, 578, 911,
283, 711, 472, 420, 245, 288, 594, 394,
511, 327, 589, 777, 699, 688, 43, 408,
842, 383, 721, 521, 560, 644, 714, 559,
62, 145, 873, 663, 713, 159, 672, 729,
624, 59, 193, 417, 158, 209, 563, 564,
343, 693, 109, 608, 563, 365, 181, 772,
677, 310, 248, 353, 708, 410, 579, 870,
617, 841, 632, 860, 289, 536, 35, 777,
618, 586, 424, 833, 77, 597, 346, 269,
757, 632, 695, 751, 331, 247, 184, 45,
787, 680, 18, 66, 407, 369, 54, 492,
228, 613, 830, 922, 437, 519, 644, 905,
789, 420, 305, 441, 207, 300, 892, 827,
141, 537, 381, 662, 513, 56, 252, 341,
242, 797, 838, 837, 720, 224, 307, 631,
61, 87, 560, 310, 756, 665, 397, 808,
851, 309, 473, 795, 378, 31, 647, 915,
459, 806, 590, 731, 425, 216, 548, 249,
321, 881, 699, 535, 673, 782, 210, 815,
905, 303, 843, 922, 281, 73, 469, 791,
660, 162, 498, 308, 155, 422, 907, 817,
187, 62, 16, 425, 535, 336, 286, 437,
375, 273, 610, 296, 183, 923, 116, 667,
751, 353, 62, 366, 691, 379, 687, 842,
37, 357, 720, 742, 330, 5, 39, 923,
311, 424, 242, 749, 321, 54, 669, 316,
342, 299, 534, 105, 667, 488, 640, 672,
576, 540, 316, 486, 721, 610, 46, 656,
447, 171, 616, 464, 190, 531, 297, 321,
762, 752, 533, 175, 134, 14, 381, 433,
717, 45, 111, 20, 596, 284, 736, 138,
646, 411, 877, 669, 141, 919, 45, 780,
407, 164, 332, 899, 165, 726, 600, 325,
498, 655, 357, 752, 768, 223, 849, 647,
63, 310, 863, 251, 366, 304, 282, 738,
675, 410, 389, 244, 31, 121, 303, 263);
var
BaseReg : array [0..800] of DWord;
CoeffReg : array [0..800] of DWord;
i : Integer;
j : Integer;
TInt : Integer;
Temp : DWord;
Wrap : DWord;
begin
if ECClen < 128 then
for i := 0 to ECCLen - 1 do
CoeffReg[i] := StMods[ECClen][i]
else begin
if ECClen = 128 then
for i := 0 to ECCLen - 1 do
CoeffReg[i] := StMods128[i]
else if ECClen = 256 then
for i := 0 to ECCLen - 1 do
CoeffReg[i] := StMods256[i]
else if ECClen = 512 then
for i := 0 to ECCLen - 1 do
CoeffReg[i] := StMods512[i];
end;
for i := 0 to ECCLen - 1 do
BaseReg[i] := 0;
for i := NumCodewords to NumCodewords + ECCLen - 1 do
FCodewords[i] := 0;
for i := 0 to NumCodewords - 1 do begin
wrap := (BaseReg[ECClen - 1] + FCodewords[i]) mod 929;
for j := ECCLen - 1 downto 1 do begin
temp := (CoeffReg[ECClen - 1 - j] * wrap) mod 929;
temp := (929 - temp) mod 929;
BaseReg[j] := (BaseReg[j - 1] + temp) mod 929;
end;
temp := (CoeffReg[ECClen - 1] * wrap) mod 929;
temp := (929 - temp) mod 929;
BaseReg[0]:= temp;
end;
for j := 0 to ECCLen - 1 do
BaseReg[j] := (929 - BaseReg[j]) mod 929;
for j := 0 to ECCLen - 1 do begin
tint := BaseReg[ECClen - 1 - j];
FCodewords [NumCodewords + j] := tint;
end;
end;
procedure TStPDF417Barcode.CalculateSize (var XSize : Integer;
var YSize : Integer);
var
i : Integer;
NumErrorCodewords : Integer;
ErrorLevel : Integer;
j : Integer;
begin
{ Set the error correction level automatically if needed }
ErrorLevel := GetRealErrorLevel;
NumErrorCodewords := Trunc (Power (2, ErrorLevel + 1));
XSize := NumColumns;
YSize := NumRows;
FTotalCodewords := XSize * YSize;
{ Adjust the size if necessary }
if (NumRows <= 0) or (NumColumns <= 0) then begin
if NumRows > 0 then begin
i := 1;
while i <= 30 do begin
if i * NumRows - NumErrorCodewords > FNumCodewords then
Break;
Inc (i);
end;
FTotalCodewords := YSize * 30;
XSize := i;
end else if NumColumns > 0 then begin
i := 3;
while i <= 90 do begin
if i * NumColumns - NumErrorCodewords > FNumCodewords then
Break;
Inc (i);
end;
YSize := i;
FTotalCodewords := XSize * 90;
end else begin
i := 1;
j := 3;
while (i * j - NumErrorCodewords < FNumCodewords) do begin
if j < 90 then
Inc (j);
if (i < 30) and (i * j - NumErrorCodewords < FNumCodewords) then
Inc (i);
if (j >= 90) and (i >= 30) then
Break;
end;
XSize := i;
YSize := J;
FTotalCodewords := 900;
end;
end;
end;
function TStPDF417Barcode.CodewordToBitmask (RowNumber : Integer;
Codeword : Integer) : DWord;
begin
if (Codeword < 0) or (CodeWord > 929) then
raise E2DBarcodeError.Create (StEInvalidCodeword);
Result := StPDF417Codewords[RowNumber mod 3][Codeword];
end;
procedure TStPDF417Barcode.ConvertBytesToBase900 (const S : array of Byte;
var A : array of Integer);
var
i : Integer;
D : array [0..5] of Byte;
Dividend : Integer;
Digits : array [0..4] of Integer;
SP : Integer;
begin
// Assert(length(S) = 6,
// 'ConvertBytesToBase900: there should be 6 bytes in the input byte array');
// Assert(length(A) = 5,
// 'ConvertBytesToBase900: there should be 5 elements in the output digit array');
{copy the array of bytes}
for i := 0 to 5 do
D[i] := S[i];
{loop until the entire base 256 value has been converted to an array
of base 900 digits (6 base 256 digits will convert to 5 base 900
digits)}
SP := 0;
while (SP < 5) do begin
Dividend := 0;
for i := 0 to 5 do begin
{notes: at the start of the loop, Dividend will always be in the
range 0..899--it starts out as zero and the final
statement in the loop forces it into that range
the first calculation sets Dividend to 0..230399
the second calc sets D[i] to 0..255 (with no possibility
of overflow)
the third calc sets Dividend to 0..899 again}
Dividend := (Dividend shl 8) + D[i];
D[i] := Dividend div 900;
Dividend := Dividend mod 900;
end;
Digits[SP] := Dividend;
inc(SP);
end;
{pop the base 900 digits and enter them into the array of integers}
i := 0;
while (SP > 0) do begin
dec(SP);
A[i] := Digits[SP];
inc(i);
end;
end;
procedure TStPDF417Barcode.ConvertToBase900 (const S : string;
var A : array of Integer;
var LenA : Integer);
var
D : string;
i : Integer;
LenD : Integer;
Dividend : Integer;
Rem : Integer;
Done : Boolean;
FirstDigit : Integer;
Digits : array [0..14] of Integer;
// 15 base 900 digits = 45 base 10 digits
SP : Integer;
begin
{Assert: S must be non-empty
it must contain just the ASCII characters '0' to '9' (so no
leading/trailing spaces either)
it must have a maximum length of 45}
Assert(IsNumericString(S), 'ConvertToBase900: S should be a numeric string');
{grab the string and calculate its length}
D := S;
LenD := length(D);
{convert the string from ASCII characters into binary digits and in
the process calculate the first non-zero digit}
FirstDigit := 0;
for i := LenD downto 1 do begin
D[i] := char(ord(D[i]) - ord('0'));
if (D[i] <> #0) then
FirstDigit := i;
end;
{if the input string comprises just zero digits, return}
if (FirstDigit = 0) then begin
LenA := 0;
Exit;
end;
{prepare the stack of base 900 digits}
SP := 0;
{loop until the entire base 10 string has been converted to an array
of base 900 digits}
Done := false;
while not Done do begin
{if we can switch to using standard integer arithmetic, do so}
if ((LenD - FirstDigit) <= 8) then begin
{convert the remaining digits to a binary integer}
Dividend := 0;
for i := FirstDigit to LenD do
Dividend := (Dividend * 10) + ord(D[i]);
{calculate the remaining base 900 digits using the standard
radix conversion algorithm; push onto the digit stack}
while (Dividend <> 0) do begin
Digits[SP] := Dividend mod 900;
inc(SP);
Dividend := Dividend div 900;
end;
{we've finished}
Done := true;
end
{otherwise operate directly on the base 10 string}
else begin
{calculate the remainder base 100}
Rem := ord(D[LenD]);
dec(LenD);
Rem := Rem + (ord(D[LenD]) * 10);
dec(LenD);
{calculate the quotient and remainder of the remaining digits,
dividing by 9}
Dividend := 0;
for i := FirstDigit to LenD do begin
Dividend := (Dividend * 10) + ord(D[i]);
D[i] := char(Dividend div 9);
Dividend := Dividend mod 9;
end;
{push the base 900 digit onto the stack: it's the remainder base
9 multiplied by 100, plus the remainder base 100}
Digits[SP] := (Dividend * 100) + Rem;
inc(SP);
{if the first digit is now zero, advance the index to the first
non-zero digit}
if (D[FirstDigit] = '0') then
inc(FirstDigit);
end;
end;
{pop the base 900 digits and enter them into the array of integers}
i := 0;
while (SP > 0) do begin
dec(SP);
A[i] := Digits[SP];
inc(i);
end;
LenA := i;
end;
procedure TStPDF417Barcode.DrawBarcode;
var
XSize : Integer;
YSize : Integer;
i : Integer;
j : Integer;
WorkBarHeight : Integer;
CodewordPos : Integer;
ErrorLevel : Integer;
NumErrorCodewords : Integer;
const
SymbolPadding = 900;
begin
{ Set the error correction level automatically if needed }
ErrorLevel := GetRealErrorLevel;
NumErrorCodewords := Trunc (Power (2, ErrorLevel + 1));
CalculateSize (XSize, YSize);
{ The first codewords is always the length }
if FNumCodewords +
(XSize * YSize - FNumCodewords - NumErrorCodewords) < 0 then
raise E2DBarcodeError.Create (StECodeTooLarge);
FCodewords[0] := FNumCodewords +
(XSize * YSize - FNumCodewords - NumErrorCodewords);
CodewordPos := 1; { The first codeword is always the length }
WorkBarHeight := (BarCodeRect.Bottom - BarCodeRect.Top) div YSize;
for i := 0 to YSize - 1 do begin
if FHighlight then
FBitmap.Canvas.Brush.Color := $ffbbff;
DrawStartPattern (i, WorkBarHeight);
if FHighlight then
FBitmap.Canvas.Brush.Color := $ffffbb;
DrawLeftRowIndicator (i, WorkBarHeight, YSize, XSize);
for j := 0 to XSize - 1 do begin
if (i = 0) and (j = 0) then begin
if FHighlight then
FBitmap.Canvas.Brush.Color := $bbffff;
{ Length }
DrawCodeWordBitmask (i, j + 2, WorkBarHeight,
CodeWordToBitmask (i, FNumCodewords +
(XSize * YSize - FNumCodewords - NumErrorCodewords)))
end else if CodewordPos < FNumCodewords then begin
if FHighlight then
FBitmap.Canvas.Brush.Color := $bbbbff;
{ Data }
DrawCodeWordBitmask (i, j + 2, WorkBarHeight,
CodewordToBitmask (i, FCodewords[CodewordPos]));
Inc (CodewordPos);
end else if CodewordPos >= XSize * YSize - NumErrorCodeWords then begin
if FHighlight then
FBitmap.Canvas.Brush.Color := $ffbbbb;
{ Error Correction Codes }
DrawCodeWordBitmask (i, j + 2, WorkBarHeight,
CodewordToBitmask (i, FCodewords[CodewordPos]));
Inc (CodewordPos);
end else begin
if FHighlight then
FBitmap.Canvas.Brush.Color := $bbffbb;
{ Padding }
DrawCodewordBitmask (i, j + 2, WorkBarHeight,
CodewordToBitmask (i, SymbolPadding));
Inc (CodewordPos);
end;
end;
if FHighlight then
FBitmap.Canvas.Brush.Color := $bbddff;
if Truncated then
DrawStopPattern (i, XSize + 2, WorkBarHeight)
else begin
DrawRightRowIndicator (i, XSize + 2, WorkBarHeight, YSize, XSize);
if FHighlight then
FBitmap.Canvas.Brush.Color := $ddaaff;
DrawStopPattern (i, XSize + 3, WorkBarHeight);
end;
end;
end;
procedure TStPDF417Barcode.DrawCodeword (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer;
Pattern : string);
function GetColumnPosition (ColNumber : Integer) : Integer;
begin
Result := ColNumber * StPDF417CellWidth * BarWidth;
end;
var
i : Integer;
CurPos : Integer;
NewPos : Integer;
DrawBlock : Boolean;
begin
if FHighlight then begin
FBitmap.Canvas.FillRect (
Rect (BarCodeRect.Left + (GetColumnPosition (ColNumber)),
BarCodeRect.Top + RowNumber * WorkBarHeight,
BarCodeRect.Left + 17 * BarWidth + GetColumnPosition (ColNumber),
BarCodeRect.Top + (RowNumber + 1) * WorkBarHeight));
FBitmap.Canvas.Brush.Color := Color;
end;
CurPos := 0;
DrawBlock := True;
for i := 1 to Length (Pattern) do begin
NewPos := StrToInt (Copy (Pattern, i, 1)) * BarWidth;
if DrawBlock then
FBitmap.Canvas.Rectangle (
BarCodeRect.Left + CurPos + GetColumnPosition (ColNumber),
BarCodeRect.Top + RowNumber * WorkBarHeight,
BarCodeRect.Left + CurPos + NewPos + GetColumnPosition (ColNumber),
BarCodeRect.Top + (RowNumber + 1) * WorkBarHeight);
CurPos := CurPos + NewPos;
DrawBlock := not DrawBlock;
end;
end;
procedure TStPDF417Barcode.DrawCodewordBitmask (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer;
Bitmask : DWord);
function GetColumnPosition (ColNumber : Integer) : Integer;
begin
Result := ColNumber * StPDF417CellWidth * BarWidth;
end;
var
i : Integer;
begin
if FHighlight then begin
FBitmap.Canvas.FillRect (
Rect (BarCodeRect.Left + (GetColumnPosition (ColNumber)),
BarCodeRect.Top + RowNumber * WorkBarHeight,
BarCodeRect.Left + 17 * BarWidth + GetColumnPosition (ColNumber),
BarCodeRect.Top + (RowNumber + 1) * WorkBarHeight));
FBitmap.Canvas.Brush.Color := Color;
end;
for i := 16 downto 0 do
if ((BitMask shr i) and $00001) <> 0 then
FBitmap.Canvas.Rectangle (
BarCodeRect.Left + (16 - i) * BarWidth +
GetColumnPosition (ColNumber),
BarCodeRect.Top + RowNumber * WorkBarHeight,
BarCodeRect.Left + (17 - i) * BarWidth +
GetColumnPosition (ColNumber),
BarCodeRect.Top + (RowNumber + 1) * WorkBarHeight);
end;
procedure TStPDF417Barcode.DrawLeftRowIndicator (RowNumber : Integer;
WorkBarHeight : Integer;
NumRows : Integer;
NumCols : Integer);
var
CodeWord : Integer;
ErrorLevel : Integer;
begin
ErrorLevel := GetRealErrorLevel;
CodeWord := 0;
if RowNumber mod 3 = 0 then
CodeWord := ((RowNumber div 3) * 30) + ((NumRows - 1) div 3)
else if RowNumber mod 3 = 1 then
CodeWord := ((RowNumber div 3) * 30) + ((NumRows - 1) mod 3) +
(3 * ErrorLevel)
else if RowNumber mod 3 = 2 then
CodeWord := (( RowNumber div 3) * 30) + (NumCols - 1);
DrawCodeWordBitmask (RowNumber, 1, WorkBarHeight,
CodewordToBitmask (RowNumber, Codeword));
end;
procedure TStPDF417Barcode.DrawRightRowIndicator (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer;
NumRows : Integer;
NumCols : Integer);
var
Codeword : Integer;
ErrorLevel : Integer;
begin
ErrorLevel := GetRealErrorLevel;
CodeWord := 0;
if RowNumber mod 3 = 0 then
Codeword := ((RowNumber div 3) * 30) + (NumCols - 1)
else if RowNumber mod 3 = 1 then
Codeword := ((RowNumber div 3) * 30) + ((NumRows - 1) div 3)
else if RowNumber mod 3 = 2 then
Codeword := ((RowNumber div 3) * 30) + ((NumRows - 1) mod 3) +
(3 * ErrorLevel);
DrawCodeWordBitmask (RowNumber, ColNumber, WorkBarHeight,
CodewordToBitmask (RowNumber, Codeword));
end;
procedure TStPDF417Barcode.DrawStartPattern (RowNumber : Integer;
WorkBarHeight : Integer);
begin
DrawCodeword (RowNumber, 0, WorkBarHeight, '81111113');
end;
procedure TStPDF417Barcode.DrawStopPattern (RowNumber : Integer;
ColNumber : Integer;
WorkBarHeight : Integer);
begin
if Truncated then
DrawCodeWord (RowNumber, ColNumber, WorkBarHeight, '1')
else
DrawCodeWord (RowNumber, ColNumber, WorkBarHeight, '711311121');
end;
procedure TStPDF417Barcode.EncodeBinary (var Position : Integer;
CodeLen : Integer);
function CountBytes (Position : Integer; CodeLen : Integer) : Integer;
var
Done : Boolean;
Dummy : Integer;
begin
Result := 0;
Done := False;
while not done do begin
if (Result < CodeLen) and
(not GoodForNumericCompaction (Position + Result, CodeLen, Dummy)) and
(not GoodForTextCompaction (Position + Result, CodeLen, Dummy)) then
Inc (Result)
else
Done := True;
end;
end;
var
MultipleOfSix : Boolean;
BinaryDataSize : Integer;
i : Integer;
j : Integer;
A : array [0..6] of Integer;
const
Even6Bytes = 924;
Odd6Bytes = 901;
begin
BinaryDataSize := CountBytes (Position, CodeLen);
if BinaryDataSize mod 6 = 0 then
MultipleOfSix := True
else
MultipleOfSix := False;
if MultipleOfSix then
AddCodeword (Even6Bytes)
else
AddCodeword (Odd6Bytes);
i := 0;
while i < BinaryDataSize do
if BinaryDataSize - i < 6 then begin
AddCodeword (Word (Code[Position + i]));
Inc (i);
end else begin
ConvertBytesToBase900 ([Byte (Code[Position + i]),
Byte (Code[Position + i + 1]),
Byte (Code[Position + i + 2]),
Byte (Code[Position + i + 3]),
Byte (Code[Position + i + 4]),
Byte (Code[Position + i + 5])], A);
for j := 1 to 5 do
AddCodeword (A[j - 1]); {!!.dg}
Inc (i, 6);
end;
Inc (Position, BinaryDataSize); {!!.dg}
end;
procedure TStPDF417Barcode.EncodeNumeric (var Position : Integer;
CodeLen : Integer);
function CollectDigits (var Position : Integer;
CodeLen : Integer) : string;
var
StartPos : Integer;
const
MaxDigitChunk = 44;
begin
Result := '';
StartPos := Position;
while (Position <= CodeLen) and (Position - StartPos < MaxDigitChunk) and
(Code[Position] >= '0') and (Code[Position] <= '9') do begin
Inc (Position);
end;
if Position - StartPos > 0 then
Result := '1' + Copy (Code, StartPos, Position - StartPos);
end;
var
NumericString : string;
A : array [0..44] of Integer;
LenA : Integer;
i : Integer;
const
NumericLatch = 902;
begin
AddCodeword (NumericLatch);
repeat
NumericString := CollectDigits (Position, CodeLen);
if NumericString <> '' then begin
ConvertToBase900 (NumericString, A, LenA);
for i := 0 to LenA do
AddCodeword (A[i]);
end;
until NumericString = '';
end;
procedure TStPDF417Barcode.EncodeText (var Position : Integer;
CodeLen : Integer);
function SelectBestTextMode (
CurChar : TStPDF417TextCompactionData) : TStPDF417TextCompactionMode;
begin
if cmAlpha in CurChar.Mode then
Result := cmAlpha
else if cmLower in CurChar.Mode then
Result := cmLower
else if cmMixed in CurChar.Mode then
Result := cmMixed
else if cmPunctuation in CurChar.Mode then
Result := cmPunctuation
else
Result := cmNone;
end;
procedure AddTextCharacter (Value : Word);
begin
if FNewTextCodeword then
FCodewords[FNumCodewords] := 30 * Value
else begin
FCodewords[FNumCodewords] := FCodewords[FNumCodewords] + Value;
Inc (FNumCodewords);
end;
FNewTextCodeword := not FNewTextCodeword;
end;
function ChangeTextSubmode (CurrentMode : TStPDF417TextCompactionMode;
NewMode : TStPDF417TextCompactionMode;
UseShift : Boolean) : TStPDF417TextCompactionMode;
const
LatchAlphaToLower = 27;
LatchAlphaToMixed = 28;
ShiftAlphaToPunctuation = 29;
ShiftLowerToAlpha = 27;
LatchLowerToMixed = 28;
ShiftLowertoPunctuation = 29;
LatchMixedToPunctuation = 25;
LatchMixedToLower = 27;
LatchMixedToAlpha = 28;
ShiftMixedToPunctuation = 29;
LatchPunctuationToAlpha = 29;
begin
if UseShift then
Result := CurrentMode
else
Result := NewMode;
case CurrentMode of
cmAlpha :
case NewMode of
cmLower :
begin
{ Alpha to Lower. No shift }
AddTextCharacter (LatchAlphaToLower);
if UseShift then
Result := NewMode;
end;
cmMixed :
begin
{ Alpha to Numeric. No shift }
AddTextCharacter (LatchAlphaToMixed);
if UseShift then
Result := NewMode;
end;
cmPunctuation :
{ Alpha to Punctuation }
if UseShift then
AddTextCharacter (ShiftAlphaToPunctuation)
else begin
AddTextCharacter (LatchAlphaToMixed);
AddTextCharacter (LatchMixedToPunctuation);
end;
end;
cmLower :
case NewMode of
cmAlpha :
{ Lower to Alpha }
if UseShift then
AddTextCharacter (ShiftLowerToAlpha)
else begin
AddTextCharacter (LatchLowerToMixed);
AddTextCharacter (LatchMixedToAlpha);
end;
cmMixed :
begin
{ Lower to Mixed. No shift }
AddTextCharacter (LatchLowerToMixed);
if UseShift then
Result := NewMode;
end;
cmPunctuation :
{ Lower to Punctuation }
if UseShift then
AddTextCharacter (ShiftLowerToPunctuation)
else begin
AddTextCharacter (LatchLowerToMixed);
AddTextCharacter (LatchMixedToPunctuation);
end;
end;
cmMixed :
case NewMode of
cmAlpha :
begin
{ Mixed to Alpha. No shift }
AddTextCharacter (LatchMixedToAlpha);
if UseShift then
Result := NewMode;
end;
cmLower :
begin
{ Mixed to Lower. No shift }
AddTextCharacter (LatchMixedToLower);
if UseShift then
Result := NewMode;
end;
cmPunctuation :
{ Mixed to Punctuation }
if UseShift then
AddTextCharacter (ShiftMixedToPunctuation)
else
AddTextCharacter (LatchMixedToPunctuation);
end;
cmPunctuation :
case NewMode of
cmAlpha :
begin
{ Punctuation to Alpha. No shift }
AddTextCharacter (LatchPunctuationToAlpha);
if UseShift then
Result := NewMode;
end;
cmLower :
begin
{ Punctuation to Lower. No shift }
AddTextCharacter (LatchPunctuationToAlpha);
AddTextCharacter (LatchAlphaToLower);
if UseShift then
Result := NewMode;
end;
cmMixed :
begin
{ Punctuation to Mixed. No shift }
AddTextCharacter (LatchPunctuationToAlpha);
AddTextCharacter (LatchAlphaToMixed);
if UseShift then
Result := NewMode;
end;
end;
end;
end;
var
CurrentTextSubmode : TStPDF417TextCompactionMode;
CurChar : TStPDF417TextCompactionData;
UseShift : Boolean;
Done : Boolean;
Dummy : Integer;
NewChar : Integer;
Codeword : Boolean;
const
EndingPadChar = 29;
begin
{ Initialize and get the first character }
FNewTextCodeword := True;
CurrentTextSubmode := cmAlpha;
Done := False;
{ get characters until it is necessary to step out of text mode }
while (Position <= CodeLen) and (CurChar.Value >= 0) and
(not Done) do begin
if (Position <= CodeLen) then begin
GetNextCharacter (NewChar, Codeword, Position, CodeLen);
CurChar := TStPDF417TextCompaction[NewChar];
end;
if Codeword then begin
{ If the text contains an odd number of letters, follow it with a
trailing 29 }
if not FNewTextCodeword then
AddTextCharacter (EndingPadChar);
FNewTextCodeword := True;
{ Add the codeword }
AddCodeword (NewChar)
end else begin
{ Check if the text submode for the current character is different than
the current text submode }
if not (CurrentTextSubmode in CurChar.Mode) then begin
{ if the text submode is different, see if it remains different. If
it does, use a latch, otherwise just shift }
if Position < CodeLen then begin
if not (CurrentTextSubmode in
TStPDF417TextCompaction[Integer (Code[Position + 1])].Mode) then
UseShift := False
else
UseShift := True;
end else
UseShift := True;
{ Add the shift or latch to the text codewords }
CurrentTextSubmode := ChangeTextSubmode (CurrentTextSubmode,
SelectBestTextMode (CurChar),
UseShift);
end;
{ Add the character to the codeword array }
AddTextCharacter (CurChar.Value);
end;
{ If this is a digit and it looks like a good time to switch to
numeric mode, do so }
if GoodForNumericCompaction (Position, CodeLen, Dummy) then
Done := True;
end;
{ If the text contains an odd number of letters, follow it with a
trailing 29 }
if not FNewTextCodeword then
AddTextCharacter (EndingPadChar);
end;
procedure TStPDF417Barcode.GenerateCodewords;
var
ErrorLevel : Integer;
NumErrorCodewords : Integer;
XSize : Integer;
YSize : Integer;
begin
TextToCodewords;
ErrorLevel := GetRealErrorLevel;
NumErrorCodewords := Trunc (Power (2, ErrorLevel + 1));
CalculateSize (XSize, YSize);
FUsedCodewords := FNumCodewords;
FUsedECCCodewords := NumErrorCodewords;
FFreeCodewords := FTotalCodewords - FUsedCodewords;
{ The first codewords is always the length }
if FNumCodewords +
(XSize * YSize - FNumCodewords - NumErrorCodewords) < 0 then
raise E2DBarcodeError.Create (StECodeTooLarge);
FCodewords[0] := FNumCodewords +
(XSize * YSize - FNumCodewords - NumErrorCodewords);
if NumErrorCodeWords + FNumCodeWords <= XSize * YSize then
CalculateECC (XSize * YSize - NumErrorCodeWords, NumErrorCodewords)
else
raise E2DBarcodeError.Create (StECodeTooLarge);
end;
procedure TStPDF417Barcode.GetNextCharacter (var NewChar : Integer;
var Codeword : Boolean;
var Position : Integer;
CodeLen : Integer);
var
WorkNum : Integer;
begin
NewChar := 0;
Codeword := False;
if Position <= CodeLen then begin
if (FCode[Position] = '\') and
(Position < CodeLen) then begin
case FCode[Position + 1] of
'0'..'9' : begin
try
NewChar := StrToInt (Copy (FCode, Position + 1, 3));
Inc (Position, 4);
except
NewChar := 0;
Inc (Position, 4);
end;
end;
'C', 'c' : begin
try
Codeword := True;
NewChar := StrToInt (Copy (FCode, Position + 2, 3));
Inc (Position, 5);
except
NewChar := 0;
Inc (Position, 5);
end;
end;
'G', 'g' : begin
WorkNum := StrToInt (Copy (FCode, Position + 1, 6));
Inc (Position, 8);
if (WorkNum >= 0) and (WorkNum <= 899) then begin
AddCodeword (927);
Codeword := True;
NewChar := WorkNum;
end else if (WorkNum >= 900) and (WorkNum < 810900) then begin
AddCodeword (926);
AddCodeword ((WorkNum div 900) - 1);
Codeword := True;
NewChar := WorkNum mod 900;
end else if (WorkNum >= 810900) and (WorkNum < 811800) then begin
AddCodeword (925);
Codeword := True;
NewChar := WorkNum;
end else
raise E2DBarcodeError.Create (StEGLIOutOfRange);
end;
'X', 'x' : begin
try
NewChar := StrToInt ('$' + Copy (FCode, Position + 2, 2));
Inc (Position, 4);
except
NewChar := 0;
Inc (Position, 4);
end;
end;
'\' : begin
NewChar := Byte (FCode[Position]);
Inc (Position, 2);
end;
else begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end;
end else begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end;
end;
function TStPDF417Barcode.GetPDF417ECCLevel : TStPDF417ECCLevels;
begin
case FECCLevel of
0 : Result := ecLevel0;
1 : Result := ecLevel1;
2 : Result := ecLevel2;
3 : Result := ecLevel3;
4 : Result := ecLevel4;
5 : Result := ecLevel5;
6 : Result := ecLevel6;
7 : Result := ecLevel7;
8 : Result := ecLevel8;
else
Result := ecAuto;
end;
end;
function TStPDF417Barcode.GetRealErrorLevel : Integer;
begin
if (FECCLevel < 0) then begin
if FNumCodeWords < 41 then
Result := 2
else if FNumCodeWords < 161 then
Result := 3
else if FNumCodeWords < 321 then
Result := 4
else
Result := 5;
end else
Result := FECCLevel
end;
function TStPDF417Barcode.GoodForNumericCompaction (
Position : Integer;
CodeLen : Integer;
var Count : Integer) : Boolean;
const
BytesNeeded = 13;
begin
Result := False;
Count := 0;
while (Position + Count < CodeLen) and
(Code[Position + Count] >= '0') and
(Code[Position + Count] <= '9') do
Inc (Count);
if Count > BytesNeeded then
Result := True;
end;
function TStPDF417Barcode.GoodForTextCompaction (
Position : Integer;
CodeLen : Integer;
var Count : Integer) : Boolean;
function IsGoodTextValue (const v : Char) : Boolean; {!!.01}
begin {!!.01}
if v > #127 then {!!.01}
Result := False {!!.01}
else if TStPDF417TextCompaction[Integer (v)].Value >= 0 then {!!.01}
Result := True {!!.01}
else {!!.01}
Result := False; {!!.01}
end; {!!.01}
const
BytesNeeded = 5;
begin
Result := False;
Count := 0;
while (Position + Count < CodeLen) and {!!.01}
(IsGoodTextValue (Code[Position + Count])) and {!!.01}
(Count <= BytesNeeded) do {!!.01}
Inc (Count);
if (Count > BytesNeeded) or
((Position + Count >= CodeLen) and (Count > 0)) then
Result := True;
end;
procedure TStPDF417Barcode.RenderToResolution (var OutBitmap : TBitmap;
ResX : Integer;
ResY : Integer;
var SizeX : Integer;
var SizeY : Integer);
var
OldBarWidth : Integer;
OldWidth : Integer;
OldHeight : Integer;
CurResX : Integer;
CurResY : Integer;
MultX : Extended;
MultY : Extended;
begin
OldBarWidth := BarWidth;
OldWidth := Width;
OldHeight := Height;
SizeX := Width;
SizeY := Height;
try
if (ResX <> 0) and (ResY <> 0) then begin
GetCurrentResolution (CurResX, CurResY);
MultX := ResX / CurResX;
MultY := ResY / CurResY;
FBarWidth := Trunc (FBarWidth * MultX);
FBitmap.Width := Trunc (FBitmap.Width * MultX);
FBitmap.Height := Trunc (FBitmap.Height * MultY);
SizeX := FBitmap.Width;
SizeY := FBitmap.Height;
end;
FBitmap.Canvas.Font.PixelsPerInch := OutBitmap.Canvas.Font.PixelsPerInch;
GenerateBarcodeBitmap (FBitmap.Width, FBitmap.Height);
OutBitmap.Width := SizeX;
OutBitmap.Height := SizeY;
OutBitmap.Canvas.CopyRect (Rect (0, 0, SizeX, SizeY), FBitmap.Canvas,
Rect (0, 0, SizeX, SizeY));
finally
FBarWidth := OldBarWidth;
FBitmap.Width := OldWidth;
FBitmap.Height := OldHeight;
GenerateBarcodeBitmap (Width, Height);
end;
end;
procedure TStPDF417Barcode.SetBarHeight (const v : Integer);
begin
if (v < 1) and (BarHeightToWidth = 0) and (not RelativeBarHeight) then
raise E2DBarcodeError.Create (StENeedBarHeight);
if v < 0 then
raise E2DBarcodeError.Create (StEBadBarWidth);
inherited SetBarHeight (v);
end;
procedure TStPDF417Barcode.SetBarHeightToWidth (const v : Integer);
begin
if (v = 0) and (BarHeight = 0) and (not RelativeBarHeight) then
raise E2DBarcodeError.Create (StENeedBarHeight);
inherited SetBarHeightToWidth (v);
end;
procedure TStPDF417Barcode.SetBarWidth (const v : Integer);
begin
if v < 1 then
raise E2DBarcodeError.Create (StEBadBarHeight);
inherited SetBarWidth (v);
end;
procedure TStPDF417Barcode.SetPDF417ECCLevel (const v : TStPDF417ECCLevels);
var
NewLevel : Integer;
OldLevel : Integer;
begin
NewLevel := -1;
case v of
ecAuto : NewLevel := -1;
ecLevel0 : NewLevel := 0;
ecLevel1 : NewLevel := 1;
ecLevel2 : NewLevel := 2;
ecLevel3 : NewLevel := 3;
ecLevel4 : NewLevel := 4;
ecLevel5 : NewLevel := 5;
ecLevel6 : NewLevel := 6;
ecLevel7 : NewLevel := 7;
ecLevel8 : NewLevel := 8;
end;
if NewLevel <> FECCLevel then begin
OldLevel := FECCLevel;
try
FECCLevel := NewLevel;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FECCLevel := OldLevel;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStPDF417Barcode.SetRelativeBarHeight (const v : Boolean);
begin
if (not v) and (BarHeightToWidth = 0) and (BarHeight = 0) then
raise E2DBarcodeError.Create (StENeedBarHeight);
inherited SetRelativeBarHeight (v);
end;
procedure TStPDF417Barcode.SetTruncated (const v : Boolean);
var
OldTruncated : Boolean;
begin
if v <> FTruncated then begin
OldTruncated := FTruncated;
try
FTruncated := v;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FTruncated := OldTruncated;
try
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
function TStPDF417Barcode.IsNumericString (const S : string) : boolean;
var
i : integer;
LenS : integer;
begin
{note: an assertion test for ConvertToBase900}
Result := false;
LenS := length(S);
if (LenS = 0) or (LenS > 45) then
Exit;
for i := 1 to LenS do
if not (('0' <= S[i]) and (S[i] <= '9')) then
Exit;
Result := true;
end;
procedure TStPDF417Barcode.SetNumColumns (const v : Integer);
var
OldNumColumns : Integer;
begin
if (v < 0) or (v > 30) then
raise E2DBarcodeError.Create (StEBadNumCols);
if v <> FNumColumns then begin
OldNumColumns := FNumColumns;
try
if v < 0 then
FNumColumns := 0
else
FNumColumns := v;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FNumColumns := OldNumColumns;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStPDF417Barcode.SetNumRows (const v : Integer);
var
OldNumRows : Integer;
begin
if (v < 0) or (v > 90) then
raise E2DBarcodeError.Create (StEBadNumRows);
if v <> FNumRows then begin
OldNumRows := FNumRows;
try
if v < 0 then
FNumRows := 0
else
FNumRows := v;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FNumRows := OldNumRows;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStPDF417Barcode.TextToCodewords;
var
i : Integer;
CodeLen : Integer;
CurrentMode : TStDataMode;
Count : Integer;
First : Boolean;
const
TextCompaction = 900;
PadCodeword = 900;
begin
First := True;
for i := 0 to 2700 do
FCodewords[i] := PadCodeword;
FNumCodewords := 1; { There will always be a length codeword }
i := 1;
CodeLen := Length (Code);
if CodeLen = 0 then
Exit;
if GoodForNumericCompaction (i, CodeLen, Count) then
CurrentMode := dmNumeric
else if GoodForTextCompaction (i, CodeLen, Count) then
CurrentMode := dmText
else
CurrentMode := dmBinary;
while i < CodeLen do begin
case CurrentMode of
dmBinary :
EncodeBinary (i, CodeLen);
dmText :
if First then
EncodeText (i, CodeLen);
dmNumeric :
EncodeNumeric (i, CodeLen);
end;
if GoodForNumericCompaction (i, CodeLen, Count) then
CurrentMode := dmNumeric
else if GoodForTextCompaction (i, CodeLen, Count) then begin
if not First then
AddCodeword (TextCompaction);
CurrentMode := dmText;
EncodeText (i, CodeLen); {!!.01}
end else
CurrentMode := dmBinary;
First := False;
end;
end;
{ TStMaxiCodeBarcode }
constructor TStMaxiCodeBarcode.Create (AOwner : TComponent);
begin
inherited Create (AOwner);
FMode := cmMode4;
FHighlight := False;
FShowCodewords := False;
FShowAll := False;
FAutoScale := True;
FBarWidth := 0;
FBarHeight := 0;
FHorPixelsPerMM := 4;
FVerPixelsPerMM := 4;
FMaxiHexWidth := 9;
FMaxiHexHeight := 9;
FMaxiHexVOffset := -2;
FMaxiHexHOffset := 4;
FCarrierCountryCode := 0;
FCarrierServiceClass := 0;
FCarrierPostalCode := '000000000';
GetSizes;
Width := 121;
Height := 129;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
end;
procedure TStMaxiCodeBarcode.AddCodeword (Value : Integer);
begin
if FNumCodewords <= 144 then
FMessage[FNumCodewords] := Value;
Inc (FNumCodewords);
end;
function TStMaxiCodeBarcode.CalculateBarCodeWidth (
PaintableWidth : Integer) : Integer;
begin
Result := Round (30 * FMaxiHexWidth + FMaxiHexHOffset);
end;
function TStMaxiCodeBarcode.CalculateBarCodeHeight (
PaintableHeight : Integer) : Integer;
begin
Result := Round (33 * FMaxiHexHeight + 33 * FMaxiHexVOffset);
end;
procedure TStMaxiCodeBarcode.DrawBarcode;
function IsBitOn (Value : Byte; Bit : Byte) : Boolean;
begin
Result := ((Value shr Bit) and $01) <> $00;
end;
const
{
The MaxBits array is arranged to match the hex layout of the MaxiCode
Barcode.
-2 identifies the (light) module at the center of the finder pattern,
-1 identifies modules which are always dark,
0 identifies modules which are always light, and
Positive numbers indicate the bitnumber of the cell.
}
MaxBits : array [0..32] of array [0..29] of Integer =
(( 122,121,128,127,134,133,140,139,146,145,152,151,158,157,164,163,170,169,176,175,182,181,188,187,194,193,200,199, -1, -1 ),
( 124,123,130,129,136,135,142,141,148,147,154,153,160,159,166,165,172,171,178,177,184,183,190,189,196,195,202,201,817, 0 ),
( 126,125,132,131,138,137,144,143,150,149,156,155,162,161,168,167,174,173,180,179,186,185,192,191,198,197,204,203,819,818 ),
( 284,283,278,277,272,271,266,265,260,259,254,253,248,247,242,241,236,235,230,229,224,223,218,217,212,211,206,205,820, 0 ),
( 286,285,280,279,274,273,268,267,262,261,256,255,250,249,244,243,238,237,232,231,226,225,220,219,214,213,208,207,822,821 ),
( 288,287,282,281,276,275,270,269,264,263,258,257,252,251,246,245,240,239,234,233,228,227,222,221,216,215,210,209,823, 0 ),
( 290,289,296,295,302,301,308,307,314,313,320,319,326,325,332,331,338,337,344,343,350,349,356,355,362,361,368,367,825,824 ),
( 292,291,298,297,304,303,310,309,316,315,322,321,328,327,334,333,340,339,346,345,352,351,358,357,364,363,370,369,826, 0 ),
( 294,293,300,299,306,305,312,311,318,317,324,323,330,329,336,335,342,341,348,347,354,353,360,359,366,365,372,371,828,827 ),
( 410,409,404,403,398,397,392,391, 80, 79, -1, -1, 14, 13, 38, 37, 3, 0, 45, 44,110,109,386,385,380,379,374,373,829, 0 ),
( 412,411,406,405,400,399,394,393, 82, 81, 41, -1, 16, 15, 40, 39, 4, 0, 0, 46,112,111,388,387,382,381,376,375,831,830 ),
( 414,413,408,407,402,401,396,395, 84, 83, 42, 0, 0, 0, 0, 0, 6, 5, 48, 47,114,113,390,389,384,383,378,377,832, 0 ),
( 416,415,422,421,428,427,104,103, 56, 55, 17, 0, 0, 0, 0, 0, 0, 0, 21, 20, 86, 85,434,433,440,439,446,445,834,833 ),
( 418,417,424,423,430,429,106,105, 58, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 22, 88, 87,436,435,442,441,448,447,835, 0 ),
( 420,419,426,425,432,431,108,107, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 90, 89,438,437,444,443,450,449,837,836 ),
( 482,481,476,475,470,469, 49, -1, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 54, 53,464,463,458,457,452,451,838, 0 ),
( 484,483,478,477,472,471, 50, 0, -1, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, -1, 0,466,465,460,459,454,453,840,839 ),
( 486,485,480,479,474,473, 52, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, 43,468,467,462,461,456,455,841, 0 ),
( 488,487,494,493,500,499, 98, 97, 62, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 92, 91,506,505,512,511,518,517,843,842 ),
( 490,489,496,495,502,501,100, 99, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 29, 28, 94, 93,508,507,514,513,520,519,844, 0 ),
( 492,491,498,497,504,503,102,101, 66, 65, 18, 0, 0, 0, 0, 0, 0, 0, 19, 30, 96, 95,510,509,516,515,522,521,846,845 ),
( 560,559,554,553,548,547,542,541, 74, 73, 33, 0, 0, 0, 0, 0, 0, 11, 68, 67,116,115,536,535,530,529,524,523,847, 0 ),
( 562,561,556,555,550,549,544,543, 76, 75, -1, 0, 8, 7, 36, 35, 12, -1, 70, 69,118,117,538,537,532,531,526,525,849,848 ),
( 564,563,558,557,552,551,546,545, 78, 77, -1, 34, 10, 9, 26, 25, 0, -1, 72, 71,120,119,540,539,534,533,528,527,850, 0 ),
( 566,565,572,571,578,577,584,583,590,589,596,595,602,601,608,607,614,613,620,619,626,625,632,631,638,637,644,643,852,851 ),
( 568,567,574,573,580,579,586,585,592,591,598,597,604,603,610,609,616,615,622,621,628,627,634,633,640,639,646,645,853, 0 ),
( 570,569,576,575,582,581,588,587,594,593,600,599,606,605,612,611,618,617,624,623,630,629,636,635,642,641,648,647,855,854 ),
( 728,727,722,721,716,715,710,709,704,703,698,697,692,691,686,685,680,679,674,673,668,667,662,661,656,655,650,649,856, 0 ),
( 730,729,724,723,718,717,712,711,706,705,700,699,694,693,688,687,682,681,676,675,670,669,664,663,658,657,652,651,858,857 ),
( 732,731,726,725,720,719,714,713,708,707,702,701,696,695,690,689,684,683,678,677,672,671,666,665,660,659,654,653,859, 0 ),
( 734,733,740,739,746,745,752,751,758,757,764,763,770,769,776,775,782,781,788,787,794,793,800,799,806,805,812,811,861,860 ),
( 736,735,742,741,748,747,754,753,760,759,766,765,772,771,778,777,784,783,790,789,796,795,802,801,808,807,814,813,862, 0 ),
( 738,737,744,743,750,749,756,755,762,761,768,767,774,773,780,779,786,785,792,791,798,797,804,803,810,809,816,815,864,863 ));
ColorTable : array [0..11] of TColor = ($bbffff, $ffbbff, $ffffbb, $bbbbff,
$bbffbb, $ffbbbb, $a0cbff, $a0ffcb,
$ffa0cb, $cba0ff, $ffcba0, $cbffa0);
var
i : Integer;
j : Integer;
XPos : Integer;
YPos : Integer;
RowOffset : Extended;
ByteNum : Integer;
BitOffset : Integer;
begin
FBitmap.Canvas.Brush.Color := Color;
FBitmap.Canvas.Pen.Width := 1;
YPos := 0;
RowOffset := 0;
for i := 0 to 32 do begin
for j := 0 to 29 do begin
XPos := Round (j * FMaxiHexWidth + RowOffset);
if FHighlight then begin
FBitmap.Canvas.Pen.Color := Color;
FBitmap.Canvas.Brush.Color := Color;
end;
ByteNum := MaxBits[i, j];
if ByteNum = -1 then begin
if FHighlight then
FBitmap.Canvas.Pen.Color := $505050;
DrawHex (XPos, YPos);
if FHighlight then
FBitmap.Canvas.Pen.Color := Color;
end else if ByteNum > 0 then begin
BitOffset := ((ByteNum - 1) mod 6);
ByteNum := (ByteNum - 1) div 6 {+ 1}; { Codeword 1 is the mode }
if FHighlight then begin
if not FShowCodewords then
case ByteNum of
0 : FBitmap.Canvas.Pen.Color := ColorTable[0];
1..9 : FBitmap.Canvas.Pen.Color := ColorTable[1];
10..19 : FBitmap.Canvas.Pen.Color := ColorTable[2];
20..87 : FBitmap.Canvas.Pen.Color := ColorTable[3];
89..103 : FBitmap.Canvas.Pen.Color := ColorTable[4];
104..144 : FBitmap.Canvas.Pen.Color := ColorTable[5];
end
else
FBitmap.Canvas.Pen.Color := ColorTable[ByteNum mod 12];
FBitmap.Canvas.Brush.Color := FBitmap.Canvas.Pen.Color;
DrawHex (XPos, YPos);
FBitmap.Canvas.Pen.Color := Color;
FBitmap.Canvas.Brush.Color := Color;
end;
if IsBitOn (FCodewords[ByteNum], 5 - BitOffset) then
DrawHex (XPos, YPos)
else if FShowAll then
DrawHex (XPos, YPos);
end;
end;
RowOffset := FMaxiHexHOffset - RowOffset;
YPos := Round (((i + 1) * FMaxiHexHeight) * 0.8660254);
end;
DrawFinder;
end;
procedure TStMaxiCodeBarcode.DrawFinder;
var
CenterX : Integer;
CenterY : Integer;
begin
CenterX := Round (BarCodeRect.Left + 14.5 * FMaxiHexWidth);
CenterY := BarCodeRect.Top + Round (16.5 * FMaxiHexHeight * 0.8660254);
FBitmap.Canvas.Brush.Color := BackgroundColor;
FBitmap.Canvas.Pen.Width := Round (FMaxiHexWidth + FMaxiHexVOffset);
FBitmap.Canvas.Ellipse (
CenterX - Round (FMaxiHexWidth) * 4,
CenterY - Round (FMaxiHexHeight) * 4,
CenterX + Round (FMaxiHexWidth) * 4,
CenterY + Round (FMaxiHexHeight) * 4);
FBitmap.Canvas.Ellipse (
CenterX - Round (FMaxiHexWidth * 2.5),
CenterY - Round (FMaxiHexHeight * 2.5),
CenterX + Round (FMaxiHexWidth * 2.5),
CenterY + Round (FMaxiHexHeight * 2.5));
FBitmap.Canvas.Ellipse (
CenterX - Round (FMaxiHexWidth),
CenterY - Round (FMaxiHexHeight),
CenterX + Round (FMaxiHexWidth),
CenterY + Round (FMaxiHexHeight));
if FHighlight then begin
FBitmap.Canvas.Pen.Width := 1;
FBitmap.Canvas.Pen.Color := clRed;
FBitmap.Canvas.MoveTo (CenterX, 0);
FBitmap.Canvas.LineTo (CenterX, Height);
FBitmap.Canvas.MoveTo (0, CenterY);
FBitmap.Canvas.LineTo (Width, CenterY);
end;
FBitmap.Canvas.Pen.Width := 1;
FBitmap.Canvas.Brush.Color := Color;
end;
procedure TStMaxiCodeBarcode.DrawHex (XPos, YPos : Integer);
var
XOffset : Integer;
YOffset : Integer;
HexWidth : Integer;
HexHeight : Integer;
Border : Extended;
begin
XOffset := BarCodeRect.Left + XPos;
YOffset := BarCodeRect.Top + YPos;
Border := ((FMaxiHexWidth + 1) / 8) + 1;
if FMaxiHexWidth >= 4 then begin
XOffset := Round (XOffset + Border);
YOffset := Round (YOffset + Border);
HexWidth := Round (FMaxiHexWidth - Border);
HexHeight := Round (FMaxiHexHeight - Border);
end else begin
HexWidth := Round (FMaxiHexWidth);
HexHeight := Round (FMaxiHexHeight);
end;
if (HexWidth < 4) or (HexHeight < 4) then
{ Ellipses look better at poorer resolutions }
FBitmap.Canvas.Ellipse (XOffset, YOffset,
XOffset + HexWidth, YOffset + HexHeight)
else begin
{ Better resolution, draw a hex }
FBitmap.Canvas.MoveTo (XOffset + HexWidth div 2,
YOffset);
FBitmap.Canvas.LineTo (XOffset + HexWidth,
YOffset + HexHeight div 4);
FBitmap.Canvas.LineTo (XOffset + HexWidth,
YOffset + HexHeight - (HexHeight div 4));
FBitmap.Canvas.LineTo (XOffset + HexWidth div 2,
YOffset + HexHeight);
FBitmap.Canvas.LineTo (XOffset,
YOffset + HexHeight - (HexHeight div 4));
FBitmap.Canvas.LineTo (XOffset,
YOffset + HexHeight div 4);
FBitmap.Canvas.LineTo (XOffset + HexWidth div 2,
YOffset);
FBitmap.Canvas.FloodFill (XOffset + HexWidth div 2,
YOffset + HexWidth div 2,
BackgroundColor,
fsSurface);
end;
end;
procedure TStMaxiCodeBarcode.GenerateCodewords;
begin
TextToCodewords;
end;
procedure TStMaxiCodeBarcode.GenerateECC;
{ Calculate the ECC codes for MaxiCode }
function GFSum (a : Integer; b : Integer) : Integer;
{ Sum of two numbers in Galois field arithmetic }
begin
Result := a xor b;
end;
function GfDifference (a : Integer; b : Integer) : Integer;
{ difference between two numbers in Galois field arithmetic (included for
completeness) }
begin
Result := a xor b;
end;
function GFProduct (a : Integer; b : Integer) : Integer;
{ Product of two numbers in Galois field arithmetic }
begin
if (a = 0) or (b = 0) then
Result := 0
else
Result := FAntiLog[(FLog[a] + FLog[b]) mod (StMaxiCodeGaloisField - 1)];
end;
function GFQuotient (a : Integer; b : Integer) : Integer;
{ Division of two numbers in Galois field arithmetic (included for
completeness ) }
begin
if b = 0 then
Result := 1 - StMaxiCodeGaloisField
else if a = 0 then
Result := 0
else
Result := FAntiLog[(FLog[a] - FLog[b] +
(StMaxiCodeGaloisField - 1)) mod (StMaxiCodeGaloisField - 1)];
end;
procedure FillLogArrays (StMaxiCodeGaloisField : Integer;
StMaxiCodeECCPoly : Integer);
{ Populate the log and antilog tables for Galois field arithmetic }
var
i : Integer;
begin
FLog[0] := 1 - StMaxiCodeGaloisField;
FAntiLog[0] := 1;
for i := 1 to StMaxiCodeGaloisField - 1 do begin
FAntiLog[i] := FAntiLog[i - 1] * 2;
if FAntiLog[i] >= StMaxiCodeGaloisField then
FAntiLog[i] := FAntiLog[i] xor StMaxiCodeECCPoly;
FLog[FAntiLog[i]] := i;
end;
end;
procedure CalculateECCCodes (var Data : TStMaxiCodeECCData;
Polynomial : TStMaxiCodeECCPoly;
IStart : TStMaxiCodeECCInterleave);
{ Calculate the Reed-Solomon error correcting codes (ECC) for MaxiCode.
Basically, this is the equivalent of taking the Data as a series of
coefficients to a polynomial (that has the lowest power the same as the
highest power of the generating polynomial) and dividing it by the
generating polynomial using Galois field arithmetic. Get the remainder of
this division and use that as the Reed Solomon error correcting codes }
const
{ Generating polynomials }
GPrimary : array [0..10] of Integer =
(46, 44, 49, 3, 2, 57, 42, 39, 28, 31, 1);
GEnhanced : array [0..28] of Integer =
(28, 11, 20, 7, 43, 9, 41, 34, 49, 46, 37, 40, 55, 34, 45, 61, 13, 23,
29, 22, 10, 35, 55, 41, 10, 53, 45, 22, 1);
GStandard : array [0..20] of Integer =
(59, 23, 19, 31, 33, 38, 17, 22, 48, 15, 36, 57, 37, 22, 8, 27, 33, 11,
44, 23, 1);
var
BRegisters : TStMaxiCodeECCData; { Works space for calculating RS ECC }
DataPos : Integer; { Position for data read/writes }
i : Integer;
j : Integer;
SumFromLast : Integer; { Result of input data + Last BReg }
GenPolyMult : Integer; { Input data (SumFromLast) * gen poly }
NumCodewords : Integer; { Number of ECC codewords to generate }
Interleaved : Boolean; { Read all data or alternate chars }
StartingPos : Integer; { Where to start reading from }
DataLength : Integer; { Amount of data to read }
OutDataPos : Integer; { Where to write ECC to }
begin
{ Intialize where to get data, write data, what poly to use, etc.. based
from the Polynomial used and whether or not the even characters or
odd characters are being encoded. }
case Polynomial of
epStandard :
{ Standard Error Correction }
begin
NumCodewords := 20;
Interleaved := True;
if IStart = imOdd then begin
StartingPos := 20;
OutDataPos := 104;
end else begin
StartingPos := 21;
OutDataPos := 105;
end;
DataLength := 42;
end;
epEnhanced :
begin
{ Enhanced Error Correction }
NumCodewords := 28;
Interleaved := True;
if IStart = imOdd then begin
StartingPos := 20;
OutDataPos := 88;
end else begin
StartingPos := 21;
OutDataPos := 89;
end;
DataLength := 34;
end
else begin
{ Primary Message }
NumCodewords := 10;
Interleaved := False;
StartingPos := 0;
OutDataPos := 10;
DataLength := 10;
end;
end;
{ Initialize all the BRegisters }
for i := 0 to StMaxMaxiCodeECCDataSize do
BRegisters[i] := 0;
{ Calculate the Log and AntiLog tables }
FillLogArrays (StMaxiCodeGaloisField, StMaxiCodeECCPoly);
DataPos := StartingPos;
{ Divide the polynomials and store the results in the BRegisters }
for i := 0 to DataLength - 1 do begin
SumFromLast := GFSum (BRegisters[NumCodewords - 1], Data[DataPos]);
for j := NumCodewords - 1 downto 0 do begin
case Polynomial of
epStandard :
GenPolyMult := GFProduct (SumFromLast, GStandard[j]);
epEnhanced :
GenPolyMult := GFProduct (SumFromLast, GEnhanced[j]);
else
GenPolyMult := GFProduct (SumFromLast, GPrimary[j]);
end;
if j > 0 then
BRegisters[j] := GFSum (BRegisters[j - 1], GenPolyMult)
else
BRegisters[j] := GenPolyMult;
end;
if Interleaved then
Inc (DataPos, 2)
else
Inc (DataPos);
end;
{ Write the ECC values back into the data }
DataPos := OutDataPos;
for i := NumCodewords - 1 downto 0 do begin
Data[DataPos] := BRegisters[i];
if Interleaved then
Inc (DataPos, 2)
else
Inc (DataPos);
end;
end;
begin
{ Calculate ECC codes for MaxiCode }
CalculateECCCodes (FCodewords, epPrimary, imNone);
if Mode = cmMode5 then begin
CalculateECCCodes (FCodewords, epEnhanced, imEven);
CalculateECCCodes (FCodewords, epEnhanced, imOdd);
end else begin
CalculateECCCodes (FCodewords, epStandard, imEven);
CalculateECCCodes (FCodewords, epStandard, imOdd);
end;
end;
procedure TStMaxiCodeBarcode.GetNextCharacter (var NewChar : Integer;
var Codeword : Boolean;
var Position : Integer;
CodeLen : Integer);
var
WorkNum : Integer;
begin
NewChar := 0;
Codeword := False;
if Position <= CodeLen then begin
if (FCode[Position] = '\') and
(Position < CodeLen) then begin
case FCode[Position + 1] of
'0'..'9' : begin
try
NewChar := StrToInt (Copy (FCode, Position + 1, 3));
Inc (Position, 4);
except
NewChar := 0;
Inc (Position, 4);
end;
end;
'C', 'c' : begin
try
Codeword := True;
NewChar := StrToInt (Copy (FCode, Position + 2, 2));
Inc (Position, 4);
except
NewChar := 0;
Inc (Position, 4);
end;
end;
'E', 'e' : begin
if UpperCase (Copy (FCode, Position + 1, 3)) = 'EOT' then begin
NewChar := 4;
Inc (Position, 4);
end else
try
WorkNum := StrToInt (Copy (FCode, Position + 1, 6));
AddCodeword (27);
Codeword := True;
Inc (Position, 8);
if (WorkNum >= 0) and (WorkNum <= 31) then begin
NewChar := WorkNum;
end else if (WorkNum >= 32) and (WorkNum <= 1023) then begin
AddCodeword ($20 or (WorkNum div 64));
NewChar := WorkNum mod 64;
end else if (WorkNum >= 1024) and (WorkNum <= 32767) then begin
AddCodeword ($30 or (WorkNum div 4096));
WorkNum := WorkNum mod 4096;
AddCodeword (WorkNum div 64);
NewChar := WorkNum mod 64;
end else if (WorkNum >= 32768) and (WorkNum <= 999999) then begin
AddCodeword ($38 or (WorkNum div 262144));
WorkNum := WorkNum mod 262144;
AddCodeword (WorkNum div 64);
WorkNum := WorkNum mod 4096;
AddCodeword (WorkNum div 64);
NewChar := WorkNum mod 64;
end else
raise E2DBarcodeError.Create (StEGLIOutOfRange);
except
on EConvertError do begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end;
end;
'F', 'f', 'G', 'g', 'N', 'n', 'R', 'r' : begin
if Position < CodeLen - 1 then begin
if (FCode[Position + 2] = 'S') or
(FCode[Position + 2] = 's') then begin
case FCode[Position + 1] of
'F', 'f' : NewChar := 28;
'G', 'g' : NewChar := 29;
'N', 'n' : begin
NewChar := 31;
Codeword := True;
end;
'R', 'r' : NewChar := 30;
end;
Inc (Position, 3);
end else begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end else begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end;
'X', 'x' : begin
try
NewChar := StrToInt ('$' + Copy (FCode, Position + 2, 2));
Inc (Position, 4);
except
NewChar := 0;
Inc (Position, 4);
end;
end;
'\' : begin
NewChar := Byte (FCode[Position]);
Inc (Position, 2);
end;
else begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end;
end else begin
NewChar := Byte (FCode[Position]);
Inc (Position);
end;
end;
end;
procedure TStMaxiCodeBarcode.GetSizes;
var
ResX : Integer;
ResY : Integer;
begin
ResX := GetDeviceCaps (FBitmap.Canvas.Handle, LOGPIXELSX);
ResY := GetDeviceCaps (FBitmap.Canvas.Handle, LOGPIXELSY);
GetSizesEx (ResX, ResY);
end;
procedure TStMaxiCodeBarcode.GetSizesEx (ResX : Integer; ResY : Integer);
begin
if FAutoScale then begin
FMaxiHexWidth := (ResX * 1.003937) / 29; { Width is 1.00" }
FMaxiHexHeight := (ResY * 0.959449) /29; { Height is 0.96" }
FMaxiHexVOffset := -1 * (FMaxiHexHeight / 6);
FMaxiHexHOffset := FMaxiHexWidth / 2;
end else begin
if BarWidth <> 0 then
FMaxiHexWidth := BarWidth
else
FMaxiHexWidth := (FHorPixelsPerMM * 27) / 29;
if BarHeight <> 0 then
FMaxiHexHeight := BarHeight
else
FMaxiHexHeight := Round (FVerPixelsPerMM * 25) / 29;
FMaxiHexVOffset := -1 * (FMaxiHexHeight / 6);
FMaxiHexHOffset := FMaxiHexWidth / 2;
end;
end;
procedure TStMaxiCodeBarcode.PlotCell (Row : Integer; Col : Integer);
var
XPos : Integer;
YPos : Integer;
begin
YPos := Round (Row * FMaxiHexHeight + Row * FMaxiHexVOffset);
if (Row mod 2) <> 0 then
XPos := Round (FMaxiHexHOffset + FMaxiHexWidth * Col)
else
XPos := Round (FMaxiHexWidth * Col);
DrawHex (XPos, YPos);
end;
procedure TStMaxiCodeBarcode.RenderToResolution (var OutBitmap : TBitmap;
ResX : Integer;
ResY : Integer;
var SizeX : Integer;
var SizeY : Integer);
var
OldBarWidth : Integer;
OldBarHeight : Integer;
OldHorPixelsPerMM : Extended;
OldVerPixelsPerMM : Extended;
OldWidth : Integer;
OldHeight : Integer;
CurResX : Integer;
CurResY : Integer;
MultX : Extended;
MultY : Extended;
OldPPI : Integer;
begin
OldBarWidth := BarWidth;
OldBarHeight := BarHeight;
OldHorPixelsPerMM := FHorPixelsPerMM;
OldVerPixelsPerMM := FVerPixelsPerMM;
OldWidth := Width;
OldHeight := Height;
SizeX := Width;
SizeY := Height;
try
if (ResX <> 0) and (ResY <> 0) then begin
GetCurrentResolution (CurResX, CurResY);
MultX := ResX / CurResX;
MultY := ResY / CurResY;
FBarWidth := Trunc (FBarWidth * MultX);
FBarHeight := Trunc (FBarHeight * MultX);
FHorPixelsPerMM := FHorPixelsPerMM * MultX;
FVerPixelsPerMM := FVerPixelsPerMM * MultX;
GetSizesEx (ResX, ResY);
FBitmap.Width := Trunc (FBitmap.Width * MultX);
FBitmap.Height := Trunc (FBitmap.Height * MultY);
SizeX := FBitmap.Width;
SizeY := FBitmap.Height;
end;
OldPPI := FBitmap.Canvas.Font.PixelsPerInch;
try
FBitmap.Canvas.Font.PixelsPerInch := OutBitmap.Canvas.Font.PixelsPerInch;
GenerateBarcodeBitmap (FBitmap.Width, FBitmap.Height);
finally
FBitmap.Canvas.Font.PixelsPerInch := OldPPI;
end;
OutBitmap.Width := SizeX;
OutBitmap.Height := SizeY;
OutBitmap.Canvas.CopyRect (Rect (0, 0, SizeX, SizeY), FBitmap.Canvas,
Rect (0, 0, SizeX, SizeY));
finally
FBarWidth := OldBarWidth;
FBarHeight := OldBarHeight;
FHorPixelsPerMM := OldHorPixelsPerMM;
FVerPixelsPerMM := OldVerPixelsPerMM;
FBitmap.Width := OldWidth;
FBitmap.Height := OldHeight;
GetSizes;
GenerateBarcodeBitmap (Width, Height);
end;
end;
procedure TStMaxiCodeBarcode.SetAutoScale (const v : Boolean);
var
OldAutoScale : Boolean;
begin
if v <> FAutoScale then begin
OldAutoScale := FAutoScale;
try
if (BarHeight = 0) and (HorPixelsPerMM = 0) and (not v) then
raise E2DBarcodeError.Create (StENeedHorz);
if (BarWidth = 0) and (VerPixelsPerMM = 0) and (not v) then
raise E2DBarcodeError.Create (StENeedVert);
FAutoScale := v;
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FAutoScale := OldAutoScale;
try
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.SetBarHeight (const v : Integer);
begin
if (v = 0) and (VerPixelsPerMM = 0) and (not AutoScale) then
raise E2DBarcodeError.Create (StENeedVert);
inherited SetBarHeight (v);
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
end;
procedure TStMaxiCodeBarcode.SetBarWidth (const v : Integer);
begin
if (v = 0) and (HorPixelsPerMM = 0) and (not AutoScale) then
raise E2DBarcodeError.Create (StENeedHorz);
inherited SetBarWidth (v);
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
end;
procedure TStMaxiCodeBarcode.SetCarrierCountryCode (const v : Integer);
var
OldCarrierCountryCode : Integer;
begin
if v <> FCarrierCountryCode then begin
OldCarrierCountryCode := FCarrierCountryCode;
try
FCarrierCountryCode := v;
if (FMode = cmMode2) or (FMode = cmMode3) then begin
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
end;
except
on E2DBarcodeError do begin
FCarrierCountryCode := OldCarrierCountryCode;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.SetCarrierPostalCode (const v : string);
var
OldCarrierPostalCode : string;
begin
if v <> FCarrierPostalCode then begin
OldCarrierPostalCode := FCarrierPostalCode;
try
FCarrierPostalCode := v;
if (FMode = cmMode2) or (FMode = cmMode3) then begin
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
end;
except
on E2DBarcodeError do begin
FCarrierPostalCode := OldCarrierPostalCode;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.SetCarrierServiceClass (const v : Integer);
var
OldCarrierServiceClass : Integer;
begin
if v <> FCarrierServiceClass then begin
OldCarrierServiceClass := FCarrierServiceClass;
try
FCarrierServiceClass := v;
if (FMode = cmMode2) or (FMode = cmMode3) then begin
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
end;
except
on E2DBarcodeError do begin
FCarrierServiceClass := OldCarrierServiceClass;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.SetHorPixelsPerMM (const v : Extended);
var
OldHorPixelsPerMM : Extended;
begin
if v <> FHorPixelsPerMM then begin
if (v = 0) and (BarWidth = 0) and (not AutoScale) then
raise E2DBarcodeError.Create (StENeedHorz);
OldHorPixelsPerMM := FHorPixelsPerMM;
try
FHorPixelsPerMM := v;
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FHorPixelsPerMM := OldHorPixelsPerMM;
try
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.SetMode (const v : TStMaxiCodeMode);
var
OldMode : TStMaxiCodeMode;
begin
if v <> FMode then begin
OldMode := Mode;
try
FMode := v;
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FMode := OldMode;
try
GenerateCodewords;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.SetVerPixelsPerMM (const v : Extended);
var
OldVerPixelsPerMM : Extended;
begin
if v <> FVerPixelsPerMM then begin
if (v = 0) and (BarHeight = 0) and (not AutoScale) then
raise E2DBarcodeError.Create (StENeedVert);
OldVerPixelsPerMM := FVerPixelsPerMM;
try
FVerPixelsPerMM := v;
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
FVerPixelsPerMM := OldVerPixelsPerMM;
try
GetSizes;
GenerateBarcodeBitmap (Width, Height);
Invalidate;
except
on E2DBarcodeError do begin
end;
end;
raise
end;
end;
end;
end;
procedure TStMaxiCodeBarcode.TextToCodewords;
function FindCodeSet (Value : Char) : TStMaxiCodeCodeSet;
begin
Result := csCodeSetA;
while Result < csNone do begin
if StMaxiCodeCodeSets[Result][Integer (Value)] <> -1 then
Exit;
Inc (Result);
end;
Result := csNone;
end;
function ChangeCodeSet (CurrentMode : TStMaxiCodeCodeSet;
NewMode : TStMaxiCodeCodeSet;
Value : Char;
UseShift : Boolean;
UseTwoShift : Boolean;
UseThreeShift : Boolean) : TStMaxiCodeCodeSet;
const
ShiftAB = 59;
ShiftAC = 60;
ShiftAD = 61;
ShiftAE = 62;
LatchAB = 63;
Shift2BA = 56;
Shift3BA = 57;
ShiftBA = 59;
ShiftBC = 60;
ShiftBD = 61;
ShiftBE = 62;
LatchBA = 63;
LatchCA = 58;
LockC = 60;
ShiftCD = 61;
ShiftCE = 62;
LatchCB = 63;
LatchDA = 58;
ShiftDC = 60;
LockD = 61;
ShiftDE = 62;
LatchDB = 63;
LatchEA = 58;
ShiftEC = 60;
ShiftED = 61;
LockE = 62;
LatchEB = 63;
begin
if UseShift then
Result := CurrentMode
else
Result := NewMode;
case CurrentMode of
csCodeSetA :
case NewMode of
csCodeSetB :
{ A -> B }
if UseShift then
AddCodeword (ShiftAB)
else
AddCodeword (LatchAB);
csCodeSetC :
{ A -> C }
begin
AddCodeword (ShiftAC);
if not UseShift then
AddCodeword (LockC);
end;
csCodeSetD :
{ A -> D }
begin
AddCodeword (ShiftAD);
if not UseShift then
AddCodeword (LockD);
end;
csCodeSetE :
{ A -> E }
begin
AddCodeword (ShiftAE);
if not UseShift then
AddCodeword (LockE);
end;
end;
csCodeSetB :
case NewMode of
csCodeSetA :
{ B -> A }
if UseThreeShift then
AddCodeword (Shift3BA)
else if UseTwoShift then
AddCodeword (Shift2BA)
else if UseShift then
AddCodeword (ShiftBA)
else
AddCodeword (LatchBA);
csCodeSetC :
{ B -> C }
begin
AddCodeword (ShiftBC);
if not UseShift then
AddCodeword (LockC);
end;
csCodeSetD :
{ B -> D }
begin
AddCodeword (ShiftBD);
if not UseShift then
AddCodeword (LockD);
end;
csCodeSetE :
{ B -> E }
begin
AddCodeword (ShiftBE);
if not UseShift then
AddCodeword (LockE);
end;
end;
csCodeSetC :
case NewMode of
csCodeSetA :
{ C -> A }
begin
AddCodeword (LatchCA);
Result := NewMode;
end;
csCodeSetB :
{ C -> B }
begin
AddCodeword (LatchCB);
Result := NewMode;
end;
csCodeSetD :
{ C -> D }
begin
AddCodeword (ShiftCD);
if not UseShift then
AddCodeword (LockD);
end;
csCodeSetE :
{ C -> E }
begin
AddCodeword (ShiftCE);
if not UseShift then
AddCodeword (LockE);
end;
end;
csCodeSetD :
case NewMode of
csCodeSetA :
{ D -> A }
begin
AddCodeword (LatchDA);
Result := NewMode;
end;
csCodeSetB :
{ D -> B }
begin
AddCodeword (LatchDB);
Result := NewMode;
end;
csCodeSetC :
{ D -> C }
begin
AddCodeword (ShiftDC);
if not UseShift then
AddCodeword (LockC);
end;
csCodeSetE :
{ D -> E }
begin
AddCodeword (ShiftDE);
if not UseShift then
AddCodeword (LockE);
end;
end;
csCodeSetE :
case NewMode of
csCodeSetA :
{ E -> A }
begin
AddCodeword (LatchEA);
Result := NewMode;
end;
csCodeSetB :
{ E -> B }
begin
AddCodeword (LatchEB);
Result := NewMode;
end;
csCodeSetC :
{ E -> C }
begin
AddCodeword (ShiftEC);
if not UseShift then
AddCodeword (LockC);
end;
csCodeSetD :
{ E -> D }
begin
AddCodeword (ShiftED);
if not UseShift then
AddCodeword (LockD);
end;
end;
end;
end;
procedure GetMessageCodewords;
var
CodeLen : Integer;
CurrentMode : TStMaxiCodeCodeSet;
UseShift : Boolean;
UseShift2 : Boolean;
UseShift3 : Boolean;
WorkMode : TStMaxiCodeCodeSet;
i : Integer;
Codeword : Boolean;
NewChar : Integer;
begin
CodeLen := Length (Code);
if CodeLen = 0 then begin
for i := 0 to 144 do
AddCodeword (33);
Exit;
end;
CurrentMode := csCodeSetA;
i := 1;
while i <= CodeLen do begin
GetNextCharacter (NewChar, CodeWord, i, CodeLen);
if CodeWord then
AddCodeword (NewChar)
else if StMaxiCodeCodeSets[CurrentMode][NewChar] = -1 then begin
WorkMode := FindCodeSet (Char (NewChar));
UseShift := False;
UseShift2 := False;
UseShift3 := False;
if i < CodeLen then begin
if StMaxiCodeCodeSets[CurrentMode][Integer (Code[i + 1])] <> -1 then
UseShift := True;
end;
CurrentMode := ChangeCodeSet (CurrentMode, WorkMode, Char (NewChar),
UseShift, UseShift2, UseShift3);
AddCodeword (StMaxiCodeCodeSets[WorkMode][NewChar]);
end else
AddCodeword (StMaxiCodeCodeSets[CurrentMode][NewChar]);
end;
if (FNumCodewords > 68) and (FMode = cmMode5) then
raise E2DBarcodeError.Create (StECodeTooLarge)
else if FNumCodewords > 84 then
raise E2DBarcodeError.Create (StECodeTooLarge);
if CodeLen < 144 then begin
if CurrentMode = csCodeSetC then begin
AddCodeword (58);
CurrentMode := csCodeSetA;
end else if CurrentMode = csCodeSetD then begin
AddCodeword (58);
CurrentMode := csCodeSetA;
end;
for i := FNumCodewords to 144 do begin
case CurrentMode of
csCodeSetA :
AddCodeword (33);
csCodeSetB :
AddCodeword (33);
csCodeSetE :
AddCodeword (28);
end;
end;
end;
end;
procedure MergeCodewords;
begin
case FMode of
cmMode2 :
System.Move (FMessage, FCodewords[20], 84);
cmMode3 :
System.Move (FMessage, FCodewords[20], 84);
cmMode4 :
begin
System.Move (FMessage, FCodeWords[1], 9);
System.Move (FMessage[9], FCodewords[20], 84);
end;
cmMode5 :
begin
System.Move (FMessage, FCodeWords[1], 9);
System.Move (FMessage[9], FCodewords[20], 68);
end;
cmMode6 :
System.Move (FMessage, FCodewords[20], 84);
end;
end;
function IsNumericPostalCode : Boolean;
var
PostalLen : Integer;
i : Integer;
begin
Result := True;
i := 1;
PostalLen := Length (FCarrierPostalCode);
while (i <= PostalLen) do
if (FCarrierPostalCode[i] < '0') or
(FCarrierPostalCode[i] > '9') then begin
Result := False;
i := PostalLen + 1;
end else
Inc (i);
end;
procedure EncodeCarrierInfo;
{ Encodation of the carrier information requires some fairly bizarre
bit manipulation
Codewords:--------> 111111
111111222222333333444444555555666666777777888888999999000000 C
012345012345012345012345012345012345012345012345012345012345012345 W
num: ppMMMMppppppppppppppppppppppppllppppccllllccccccssssccssssssEEE...
an: ppMMMMppppppppppppppppppppppppppppppccppppccccccssssccssssssEEE...
123456789012345678901234567890123456789012345678901234567890123456 B
Bits: -----> 111111111122222222223333333333444444444455555555556666666 i
t
MMMM = Mode
pppp = Postal Code
ll = Postal Code Length
cccc = Country Code
ssss = Service Class
EEEE = ECC Codes
For pppp, ll, cccc and ssss, the MSB is on the right.
}
var
WorkNum : Integer;
WorkStr : string;
i : Integer;
begin
for WorkNum := 2 to 10 do
FCodewords[WorkNum] := 0;
FCodewords[0] := FCodewords[0] and $0f;
if FCodewords[0] = $02 then begin
{ Format numeric postal code }
{ Format the postal code length }
WorkNum := Length (FCarrierPostalCode);
FCodewords[6] := (WorkNum and $3c) shr 2;
FCodewords[5] := (WorkNum and $03) shl 4;
{ Format the postal code }
try
WorkNum := StrToInt (FCarrierPostalCode);
except
on EConvertError do
raise E2DBarcodeError.Create (StEBadPostalCode);
end;
FCodewords[5] := FCodewords[5] or ((WorkNum shr 26) and $0f);
FCodewords[4] := (WorkNum shr 20) and $3f;
FCodewords[3] := (WorkNum shr 14) and $3f;
FCodewords[2] := (WorkNum shr 8) and $3f;
FCodewords[1] := (WorkNum shr 2) and $3f;
FCodewords[0] := FCodewords[0] or ((WorkNum and $03) shl 4);
end else begin
{ Format alphanumeric postal code }
WorkStr := UpperCase (FCarrierPostalCode) + ' ';
for i := 0 to 5 do begin
WorkNum := StMaxiCodeCodeSets[csCodeSetA][Integer (WorkStr[6 - i])];
if WorkNum < 0 then
WorkNum := StMaxiCodeCodeSets[csCodeSetA][32]; { Use a space }
FCodewords[i] := FCodewords[i] or ((WorkNum and $03) shl 4);
FCodewords[i + 1] := FCodewords[i + 1] or ((WorkNum and $3c) shr 2);
end;
end;
{ Format country code }
WorkNum := FCarrierCountryCode;
FCodewords[8] := (WorkNum shr 8) and $03;
FCodewords[7] := (WorkNum shr 2) and $3f;
FCodewords[6] := FCodewords[6] or ((WorkNum and $03) shl 4);
{ Format service class }
WorkNum := FCarrierServiceClass;
FCodewords[9] := (WorkNum and $3f0) shr 4;
FCodewords[8] := FCodewords[8] or ((WorkNum and $0f) shl 2);
end;
var
i : Integer;
begin
for i := 0 to 144 do begin
FCodewords[i] := 0;
FMessage[i] := 0;
end;
FNumCodewords := 0;
{ Encode the primary message and set the FNumCodewords to the begining
of the secondary message }
case FMode of
cmMode2, cmMode3 :
if IsNumericPostalCode then
FCodewords[0] := $02
else
FCodewords[0] := $03;
cmMode4 :
FCodewords[0] := $04;
cmMode5 :
FCodewords[0] := $05;
cmMode6 :
FCodewords[0] := $06;
end;
if (FMode = cmMode2) or (FMode = cmMode3) then
EncodeCarrierInfo;
GetMessageCodewords;
MergeCodewords;
GenerateECC;
FNumCodewords := 144;
FTotalCodewords := 144;
if FMode = cmMode5 then
FUsedECCCodewords := 66
else
FUsedECCCodewords := 50;
case FMode of
cmMode2 :
FUsedCodewords := FNumCodewords + 10;
cmMode3 :
FUsedCodewords := FNumCodewords + 10;
cmMode4 :
FUsedCodewords := FNumCodewords + 1;
cmMode5 :
FUsedCodewords := FNumCodewords + 1;
cmMode6 :
FUsedCodewords := FNumCodewords + 1;
end;
FFreeCodewords := FTotalCodewords - FUsedCodewords - FUsedECCCodewords;
end;
end.