1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453 |
- {
- This file is part of the Free Pascal FCL library.
- Copyright (c) 2017 by Michael Van Canneyt
- member of the Free Pascal development team
- Barcode encoding routines.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$IFNDEF FPC_DOTTEDUNITS}
- unit fpbarcode;
- {$ENDIF FPC_DOTTEDUNITS}
- {$mode objfpc}{$H+}
- interface
- {$IFDEF FPC_DOTTEDUNITS}
- uses
- System.SysUtils;
- {$ELSE FPC_DOTTEDUNITS}
- uses
- sysutils;
- {$ENDIF FPC_DOTTEDUNITS}
- Type
- // Various encodings. Sorted
- TBarcodeEncoding = (
- be128A, be128B, be128C,
- be2of5industrial, be2of5interleaved, be2of5matrix,
- be39, be39Extended,
- be93, be93Extended,
- beCodabar,
- beEAN13, beEAN8,
- beMSI,
- bePostNet
- );
- TBarcodeEncodings = Set of TBarcodeEncoding;
- {
- Various types of known bars in a barcode.
- Each type encapsulates 3 parameters.
- Color: black/white
- width: 100, (weighted) 150 or 200 % of unit width
- Height: full height or 2/5th (the latter is for postnet)
- }
- TBarColor = (bcWhite,bcBlack);
- TBarWidth = (bw100,bwWeighted,bw150,bw200);
- TBarheight = (bhFull,bhTwoFifth);
- TBarWidthArray = Array[TBarWidth] of Integer;
- TBarParams = record
- c : TBarColor;
- w : TBarWidth;
- h : TBarHeight;
- end;
- TBarType = 0..11;
- // auxiliary type for the constant
- TBarTypeParams = Array[TBarType] of TBarParams;
- // This
- TBarTypeArray = array of TBarType;
- TBarParamsArray = Array of TBarParams;
- EBarEncoding = class(exception);
- Const
- NumericalEncodings = [beEAN8,beEAN13,be2of5industrial,be2of5interleaved, be2of5matrix,bePostNet,beMSI,be128C];
- BarcodeEncodingNames: array[TBarcodeEncoding] of string =
- (
- '128 A', '128 B', '128 C',
- '2 of 5 industrial', '2 of 5 interleaved', '2 of 5 matrix',
- '39', '39 Extended',
- '93', '93 Extended',
- 'Codabar',
- 'EAN 13', 'EAN 8',
- 'MSI',
- 'PostNet'
- );
- Function StringAllowsBarEncoding(S : AnsiString; aEncoding : TBarcodeEncoding) : Boolean;
- Function StringToBarTypeArray(S : AnsiString; aEncoding : TBarcodeEncoding) : TBarTypeArray;
- Function StringToBarcodeParams(S : AnsiString; aEncoding : TBarcodeEncoding) : TBarParamsArray;
- Function IntToBarTypeArray(I: Int64; aEncoding : TBarcodeEncoding; aWidth : Integer = 0) : TBarTypeArray;
- Function IntToBarcodeParams(I : Int64; aEncoding : TBarcodeEncoding; aWidth : Integer = 0) : TBarParamsArray;
- Function BarTypeToBarParams(aType : TBarType) : TBarParams;
- Function BarTypeArrayToBarParamsArray(anArray : TBarTypeArray) : TBarParamsArray;
- Function CalcBarWidths(aEncoding : TBarcodeEncoding; aUnit : Integer; AWeight : Double) : TBarWidthArray;
- Function CalcStringWidthInBarCodeEncoding(S : AnsiString;aEncoding : TBarcodeEncoding; aUnit : Integer; AWeight : Double) : Cardinal;
- // Check with barcode unit
- implementation
- Const
- NumChars = ['0'..'9'];
- Procedure IllegalChar(C : AnsiChar;E : TBarcodeEncoding);
- Var
- S : AnsiString;
- begin
- Str(E,S);
- Raise EBarEncoding.CreateFmt('%s is an illegal character for encoding %s',[C,S]);
- end;
- Const
- BarTypes : TBarTypeParams = (
- { 0} (c: bcWhite; w: bw100; h: bhFull),
- { 1} (c: bcWhite; w: bwWeighted; h: bhFull),
- { 2} (c: bcWhite; w: bw150; h: bhFull),
- { 3} (c: bcWhite; w: bw200; h: bhFull),
- { 4} (c: bcBlack; w: bw100; h: bhFull),
- { 5} (c: bcBlack; w: bwWeighted; h: bhFull),
- { 6} (c: bcBlack; w: bw150; h: bhFull),
- { 7} (c: bcBlack; w: bw200; h: bhFull),
- { 8} (c: bcBlack; w: bw100; h: bhTwoFifth),
- { 9} (c: bcBlack; w: bwWeighted; h: bhTwoFifth),
- {10} (c: bcBlack; w: bw150; h: bhTwoFifth),
- {11} (c: bcBlack; w: bw200; h: bhTwoFifth)
- );
- { ---------------------------------------------------------------------
- EAN 8
- ---------------------------------------------------------------------}
- Type
- TEANChar = array[1..4] of TBarType;
- TEanParity = array[1..6] of TBarType;
- Const
- EANStartStop : array[1..3] of TBarType = (4,0,4);
- EANSep : array[1..5] of TBarType = (0,4,0,4,0);
- EANEncodingA : array['0'..'9'] of TEANChar = (
- ( 2, 5, 0, 4), // 0
- ( 1, 5, 1, 4), // 1
- ( 1, 4, 1, 5), // 2
- ( 0, 7, 0, 4), // 3
- ( 0, 4, 2, 5), // 4
- ( 0, 5, 2, 4), // 5
- ( 0, 4, 0, 7), // 6
- ( 0, 6, 0, 5), // 7
- ( 0, 5, 0, 6), // 8
- ( 2, 4, 0, 5) // 9
- );
- EANEncodingC : array['0'..'9'] of TEANChar = (
- ( 6, 1, 4, 0), // 0
- ( 5, 1, 5, 0), // 1
- ( 5, 0, 5, 1), // 2
- ( 4, 3, 4, 0), // 3
- ( 4, 0, 6, 1), // 4
- ( 4, 1, 6, 0), // 5
- ( 4, 0, 4, 3), // 6
- ( 4, 2, 4, 1), // 7
- ( 4, 1, 4, 2), // 8
- ( 6, 0, 4, 1) // 9
- );
- EANEncodingB : array['0'..'9'] of TEANChar = (
- ( 0, 4, 1, 6), // 0
- ( 0, 5, 1, 5), // 1
- ( 1, 5, 0, 5), // 2
- ( 0, 4, 3, 4), // 3
- ( 1, 6, 0, 4), // 4
- ( 0, 6, 1, 4), // 5
- ( 3, 4, 0, 4), // 6
- ( 1, 4, 2, 4), // 7
- ( 2, 4, 1, 4), // 8
- ( 1, 4, 0, 6) // 9
- );
- EANEncodingParity : array[0..9] of TEanParity = (
- ( 8, 8, 8, 8, 8, 8), // 0
- ( 8, 8, 9, 8, 9, 9), // 1
- ( 8, 8, 9, 9, 8, 9), // 2
- ( 8, 8, 9, 9, 9, 8), // 3
- ( 8, 9, 8, 8, 9, 9), // 4
- ( 8, 9, 9, 8, 8, 9), // 5
- ( 8, 9, 9, 9, 8, 8), // 6
- ( 8, 9, 8, 9, 8, 9), // 7
- ( 8, 9, 8, 9, 9, 8), // 8
- ( 8, 9, 9, 8, 9, 8) // 9
- );
- Procedure AddToArray(A : TBarTypeArray; var aPos : integer; Elements : Array of TBarType);
- Var
- I,L : Integer;
- begin
- L:=Length(Elements);
- // Safety check
- if ((aPos+L)>Length(A)) then
- Raise EBarEncoding.CreateFmt('Cannot add %d elements to array of length %d at pos %d,',[L,Length(A),aPos]);
- For I:=0 to L-1 do
- begin
- A[aPos]:=Elements[i];
- inc(aPos);
- end;
- end;
- function CheckEANValue(const AValue:AnsiString; const ASize: Byte): AnsiString;
- var
- L,I : Integer;
- begin
- Result:=AValue;
- UniqueString(Result);
- L:=Length(Result);
- for i:=1 to L do
- if not (Result[i] in NumChars) then
- Result[i]:='0';
- if L<ASize then
- Result:=StringOfChar('0', ASize-L-1)+Result+'0';
- end;
- function EncodeEAN8(S : AnsiString) : TBarTypeArray;
- var
- i, p: integer;
- begin
- S:=CheckEANValue(S,8);
- SetLength(Result,2*Length(EANStartStop)+Length(EANSep)+8*4);
- P:=0;
- AddToArray(Result,P,EANStartStop); // start
- for I:=1 to 4 do
- AddToArray(Result,P,EANEncodingA[S[i]]);
- AddToArray(Result,P,EANSep); // Separator
- for i := 5 to 8 do
- AddToArray(Result,P,EANEncodingC[S[i]]);
- AddToArray(Result,P,EANStartStop); // Stop
- end;
- function EnCodeEAN13(S : AnsiString) : TBarTypeArray;
- var
- i, p, cc : integer;
- begin
- S:=CheckEanValue(S, 13);
- SetLength(Result,2*Length(EANStartStop)+Length(EANSep)+12*4);
- cc:=Ord(S[1])-Ord('0');
- Delete(S,1,1);
- P:=0;
- AddToArray(Result,P,EANStartStop); // start
- for i := 1 to 6 do
- case EANEncodingParity[cc,i] of
- 8: AddToArray(Result,P,EANEncodingA[s[i]]);
- 9: AddToArray(Result,P,EANEncodingB[s[i]]);
- 10: AddToArray(Result,P,EANEncodingC[s[i]]);// will normally not happen...
- end;
- AddToArray(Result,P,EANSep); // Separator
- for i := 7 to 12 do
- AddToArray(Result,P,EANEncodingC[s[i]]);
- AddToArray(Result,P,EANStartStop); // stop
- end;
- { ---------------------------------------------------------------------
- Encoding 39 (+ extended)
- ---------------------------------------------------------------------}
- Type
- TCode39Char = array[0..9] of TBarType;
- TCode39Data = record
- c: AnsiChar;
- ck: byte;
- Data: TCode39Char;
- end;
- Const
- Encoding39 : array[0..43] of TCode39Data = (
- (c: '0'; ck: 0; data: ( 4, 0, 4, 1, 5, 0, 5, 0, 4, 0)),
- (c: '1'; ck: 1; data: ( 5, 0, 4, 1, 4, 0, 4, 0, 5, 0)),
- (c: '2'; ck: 2; data: ( 4, 0, 5, 1, 4, 0, 4, 0, 5, 0)),
- (c: '3'; ck: 3; data: ( 5, 0, 5, 1, 4, 0, 4, 0, 4, 0)),
- (c: '4'; ck: 4; data: ( 4, 0, 4, 1, 5, 0, 4, 0, 5, 0)),
- (c: '5'; ck: 5; data: ( 5, 0, 4, 1, 5, 0, 4, 0, 4, 0)),
- (c: '6'; ck: 6; data: ( 4, 0, 5, 1, 5, 0, 4, 0, 4, 0)),
- (c: '7'; ck: 7; data: ( 4, 0, 4, 1, 4, 0, 5, 0, 5, 0)),
- (c: '8'; ck: 8; data: ( 5, 0, 4, 1, 4, 0, 5, 0, 4, 0)),
- (c: '9'; ck: 9; data: ( 4, 0, 5, 1, 4, 0, 5, 0, 4, 0)),
- (c: 'A'; ck: 10; data: ( 5, 0, 4, 0, 4, 1, 4, 0, 5, 0)),
- (c: 'B'; ck: 11; data: ( 4, 0, 5, 0, 4, 1, 4, 0, 5, 0)),
- (c: 'C'; ck: 12; data: ( 5, 0, 5, 0, 4, 1, 4, 0, 4, 0)),
- (c: 'D'; ck: 13; data: ( 4, 0, 4, 0, 5, 1, 4, 0, 5, 0)),
- (c: 'E'; ck: 14; data: ( 5, 0, 4, 0, 5, 1, 4, 0, 4, 0)),
- (c: 'F'; ck: 15; data: ( 4, 0, 5, 0, 5, 1, 4, 0, 4, 0)),
- (c: 'G'; ck: 16; data: ( 4, 0, 4, 0, 4, 1, 5, 0, 5, 0)),
- (c: 'H'; ck: 17; data: ( 5, 0, 4, 0, 4, 1, 5, 0, 4, 0)),
- (c: 'I'; ck: 18; data: ( 4, 0, 5, 0, 4, 1, 5, 0, 0, 0)),
- (c: 'J'; ck: 19; data: ( 4, 0, 4, 0, 5, 1, 5, 0, 4, 0)),
- (c: 'K'; ck: 20; data: ( 5, 0, 4, 0, 4, 0, 4, 1, 5, 0)),
- (c: 'L'; ck: 21; data: ( 4, 0, 5, 0, 4, 0, 4, 1, 5, 0)),
- (c: 'M'; ck: 22; data: ( 5, 0, 5, 0, 4, 0, 4, 1, 4, 0)),
- (c: 'N'; ck: 23; data: ( 4, 0, 4, 0, 5, 0, 4, 1, 5, 0)),
- (c: 'O'; ck: 24; data: ( 5, 0, 4, 0, 5, 0, 4, 1, 4, 0)),
- (c: 'P'; ck: 25; data: ( 4, 0, 5, 0, 5, 0, 4, 1, 4, 0)),
- (c: 'Q'; ck: 26; data: ( 4, 0, 4, 0, 4, 0, 5, 1, 5, 0)),
- (c: 'R'; ck: 27; data: ( 5, 0, 4, 0, 4, 0, 5, 1, 4, 0)),
- (c: 'S'; ck: 28; data: ( 4, 0, 5, 0, 4, 0, 5, 1, 4, 0)),
- (c: 'T'; ck: 29; data: ( 4, 0, 4, 0, 5, 0, 5, 1, 4, 0)),
- (c: 'U'; ck: 30; data: ( 5, 1, 4, 0, 4, 0, 4, 0, 5, 0)),
- (c: 'V'; ck: 31; data: ( 4, 1, 5, 0, 4, 0, 4, 0, 5, 0)),
- (c: 'W'; ck: 32; data: ( 5, 1, 5, 0, 4, 0, 4, 0, 4, 0)),
- (c: 'X'; ck: 33; data: ( 4, 1, 4, 0, 5, 0, 4, 0, 5, 0)),
- (c: 'Y'; ck: 34; data: ( 5, 1, 4, 0, 5, 0, 4, 0, 4, 0)),
- (c: 'Z'; ck: 35; data: ( 4, 1, 5, 0, 5, 0, 4, 0, 4, 0)),
- (c: '-'; ck: 36; data: ( 4, 1, 4, 0, 4, 0, 5, 0, 5, 0)),
- (c: '.'; ck: 37; data: ( 5, 1, 4, 0, 4, 0, 5, 0, 4, 0)),
- (c: ' '; ck: 38; data: ( 4, 1, 5, 0, 4, 0, 5, 0, 4, 0)),
- (c: '*'; ck: 0; data: ( 4, 1, 4, 0, 5, 0, 5, 0, 4, 0)),
- (c: '$'; ck: 39; data: ( 4, 1, 4, 1, 4, 1, 4, 0, 4, 0)),
- (c: '/'; ck: 40; data: ( 4, 1, 4, 1, 4, 0, 4, 1, 4, 0)),
- (c: '+'; ck: 41; data: ( 4, 1, 4, 0, 4, 1, 4, 1, 4, 0)),
- (c: '%'; ck: 42; data: ( 4, 0, 4, 1, 4, 1, 4, 1, 4, 0))
- );
- function IndexOfCode39Char(c: AnsiChar): integer;
- begin
- Result:=High(Encoding39);
- While (Result>=0) and (c<>Encoding39[Result].c) do
- Dec(Result);
- end;
- Function AllowEncode39 (S : AnsiString) : boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=IndexOfCode39Char(S[i])>=0;
- Inc(I);
- end;
- end;
- Function Encode39(S : AnsiString; aCheckSum : Boolean) : TBarTypeArray;
- Const
- StartStopIndex = 39;
- function IndexOfCC(cs: byte): integer;
- Var
- H : integer;
- begin
- Result:=0;
- H:=High(Encoding39);
- While (Result<=H) and (cs<>Encoding39[Result].ck) do
- Inc(Result);
- if Result>=H then
- Result:=StartStopIndex;
- end;
- var
- cs, p, Idx: integer;
- c : AnsiChar;
- begin
- cs:=0;
- // Length = (length text + startstop * 2) * (length of data)
- SetLength(Result,(Length(S)+2)*10);
- P:=0;
- // Startcode
- AddToArray(Result,P,Encoding39[StartStopIndex].Data);
- for C in S do
- begin
- Idx:=IndexOfCode39Char(C);
- if Idx<0 then
- IllegalChar(C,be39);
- AddToArray(Result,P,Encoding39[Idx].Data);
- Inc(cs, Encoding39[Idx].ck);
- end;
- // Calculate Checksum if requested and add.
- if aCheckSum then
- begin
- AddToArray(Result,P,Encoding39[IndexOfCc(cs mod 43)].Data);
- SetLength(Result,P); // Correct result
- end
- else // No checksum: add startcode, minus last 0 !
- begin
- AddToArray(Result,P,Encoding39[StartStopIndex].Data);
- SetLength(Result,P-1); // Correct result
- end;
- end;
- function AllowEncode39Extended(S : AnsiString) : boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=Ord(S[i])<128;
- Inc(I);
- end;
- end;
- function Encode39Extended(S : AnsiString; aCheckSum : boolean): TBarTypeArray;
- // Extended uses an encoding for the first 127 characters...
- const
- CharEncoding : array[0..127] of String[2] = (
- '%U', '$A', '$B', '$C', '$D', '$E', '$F', '$G',
- '$H', '$I', '$J', '$K', '$L', '$M', '$N', '$O',
- '$P', '$Q', '$R', '$S', '$T', '$U', '$V', '$W',
- '$X', '$Y', '$Z', '%A', '%B', '%C', '%D', '%E',
- ' ', '/A', '/B', '/C', '/D', '/E', '/F', '/G',
- '/H', '/I', '/J', '/K', '/L', '/M', '/N', '/O',
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '/Z', '%F', '%G', '%H', '%I', '%J',
- '%V', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', '%K', '%L', '%M', '%N', '%O',
- '%W', '+A', '+B', '+C', '+D', '+E', '+F', '+G',
- '+H', '+I', '+J', '+K', '+L', '+M', '+N', '+O',
- '+P', '+Q', '+R', '+S', '+T', '+U', '+V', '+W',
- '+X', '+Y', '+Z', '%P', '%Q', '%R', '%S', '%T'
- );
- var
- T : AnsiString;
- O,i: integer;
- begin
- T:='';
- for I:=1 to Length(S) do
- begin
- O:=Ord(S[i]);
- if (O>127) then
- IllegalChar(S[i],be39Extended);
- T:=T+CharEncoding[O];
- end;
- Result:=Encode39(T,aChecksum);
- end;
- { ---------------------------------------------------------------------
- Code 93
- ---------------------------------------------------------------------}
- Type
- TCode93Char = array[0..5] of TBarType;
- TCode93Data = record
- c: AnsiChar;
- Data: TCode93Char;
- end;
- Const
- Encoding93 : array[0..46] of TCode93Data = (
- (c: '0'; data: ( 4, 2, 4, 0, 4, 1)),
- (c: '1'; data: ( 4, 0, 4, 1, 4, 2)),
- (c: '2'; data: ( 4, 0, 4, 2, 4, 1)),
- (c: '3'; data: ( 4, 0, 4, 3, 4, 0)),
- (c: '4'; data: ( 4, 1, 4, 0, 4, 2)),
- (c: '5'; data: ( 4, 1, 4, 1, 4, 1)),
- (c: '6'; data: ( 4, 1, 4, 2, 4, 0)),
- (c: '7'; data: ( 4, 0, 4, 0, 4, 3)),
- (c: '8'; data: ( 4, 2, 4, 1, 4, 0)),
- (c: '9'; data: ( 4, 3, 4, 0, 4, 0)),
- (c: 'A'; data: ( 5, 0, 4, 0, 4, 2)),
- (c: 'B'; data: ( 5, 0, 4, 1, 4, 1)),
- (c: 'C'; data: ( 5, 0, 4, 2, 4, 0)),
- (c: 'D'; data: ( 5, 1, 4, 0, 4, 1)),
- (c: 'E'; data: ( 5, 1, 4, 1, 4, 0)),
- (c: 'F'; data: ( 5, 2, 4, 0, 4, 0)),
- (c: 'G'; data: ( 4, 0, 5, 0, 4, 2)),
- (c: 'H'; data: ( 4, 0, 5, 1, 4, 1)),
- (c: 'I'; data: ( 4, 0, 5, 2, 4, 0)),
- (c: 'J'; data: ( 4, 1, 5, 0, 4, 1)),
- (c: 'K'; data: ( 4, 2, 5, 0, 4, 0)),
- (c: 'L'; data: ( 4, 0, 4, 0, 5, 2)),
- (c: 'M'; data: ( 4, 0, 4, 1, 5, 1)),
- (c: 'N'; data: ( 4, 0, 4, 2, 5, 0)),
- (c: 'O'; data: ( 4, 1, 4, 0, 5, 1)),
- (c: 'P'; data: ( 4, 2, 4, 0, 5, 0)),
- (c: 'Q'; data: ( 5, 0, 5, 0, 4, 1)),
- (c: 'R'; data: ( 5, 0, 5, 1, 4, 0)),
- (c: 'S'; data: ( 5, 0, 4, 0, 5, 1)),
- (c: 'T'; data: ( 5, 0, 4, 1, 5, 0)),
- (c: 'U'; data: ( 5, 1, 4, 0, 5, 0)),
- (c: 'V'; data: ( 5, 1, 5, 0, 4, 0)),
- (c: 'W'; data: ( 4, 0, 5, 0, 5, 1)),
- (c: 'X'; data: ( 4, 0, 5, 1, 5, 0)),
- (c: 'Y'; data: ( 4, 1, 5, 0, 5, 0)),
- (c: 'Z'; data: ( 4, 1, 6, 0, 4, 0)),
- (c: '-'; data: ( 4, 1, 4, 0, 6, 0)),
- (c: '.'; data: ( 6, 0, 4, 0, 4, 1)),
- (c: ' '; data: ( 6, 0, 4, 1, 4, 0)),
- (c: '$'; data: ( 6, 1, 4, 0, 4, 0)),
- (c: '/'; data: ( 4, 0, 5, 0, 6, 0)),
- (c: '+'; data: ( 4, 0, 6, 0, 5, 0)),
- (c: '%'; data: ( 5, 0, 4, 0, 6, 0)),
- (c: '['; data: ( 4, 1, 4, 1, 5, 0)),
- (c: ']'; data: ( 6, 0, 5, 0, 4, 0)),
- (c: '{'; data: ( 6, 0, 4, 0, 5, 0)),
- (c: '}'; data: ( 4, 1, 5, 1, 4, 0))
- );
- function IndexOfCode93Char(c: AnsiChar): integer;
- begin
- Result:=High(Encoding93);
- While (Result>=0) and (c<>Encoding93[Result].c) do
- Dec(Result);
- end;
- Function AllowEncode93 (S : AnsiString) : boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=IndexOfCode93Char(S[i])>=0;
- Inc(I);
- end;
- end;
- Function Encode93(S : AnsiString) : TBarTypeArray;
- Const
- Code93Start : Array[1..6] of TBarType = ( 4, 0, 4, 0, 7, 0);
- Code93Stop : Array[1..7] of TBarType = ( 4, 0, 4, 0, 7, 0, 4);
- var
- L,i, P, Idx, CC, CK, WC, WK : integer;
- C : AnsiChar;
- begin
- L:=Length(S);
- // Length String * 6 + Start + Stop + Checksum
- SetLength(Result,L*6+6+7+2*6);
- P:=0;
- AddToArray(Result,P,Code93Start);
- for C in S do
- begin
- Idx:=IndexOfCode93Char(C);
- if Idx<0 then
- IllegalChar(C,be93);
- AddToArray(Result,P,Encoding93[Idx].Data);
- end;
- CC:=0;
- CK:=0;
- WC:=1;
- WK:=2;
- for i:=L downto 1 do
- begin
- Idx:=IndexOfCode93Char(S[i]);
- Inc(CC,Idx*WC);
- Inc(CK,Idx*WK);
- Inc(WC);
- if (WC>20) then
- WC:=1;
- Inc(WK);
- if (WK>15) then
- WK:=1;
- end;
- Inc(CK,CC);
- CC:=CC mod 47;
- CK:=CK mod 47;
- AddToArray(Result,P,Encoding93[CC].Data);
- AddToArray(Result,P,Encoding93[CK].Data);
- AddToArray(Result,P,Code93Stop);
- end;
- function AllowEncode93Extended(S : AnsiString) : boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=Ord(S[i])<128;
- Inc(I);
- end;
- end;
- function Encode93Extended(S: AnsiString) : TBarTypeArray;
- const
- CharEncoding: array[0..127] of string[2] = (
- ']U', '[A', '[B', '[C', '[D', '[E', '[F', '[G',
- '[H', '[I', '[J', '[K', '[L', '[M', '[N', '[O',
- '[P', '[Q', '[R', '[S', '[T', '[U', '[V', '[W',
- '[X', '[Y', '[Z', ']A', ']B', ']C', ']D', ']E',
- ' ', '{A', '{B', '{C', '{D', '{E', '{F', '{G',
- '{H', '{I', '{J', '{K', '{L', '{M', '{N', '{O',
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '{Z', ']F', ']G', ']H', ']I', ']J',
- ']V', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', ']K', ']L', ']M', ']N', ']O',
- ']W', '}A', '}B', '}C', '}D', '}E', '}F', '}G',
- '}H', '}I', '}J', '}K', '}L', '}M', '}N', '}O',
- '}P', '}Q', '}R', '}S', '}T', '}U', '}V', '}W',
- '}X', '}Y', '}Z', ']P', ']Q', ']R', ']S', ']T'
- );
- var
- T : AnsiString;
- O,i: integer;
- begin
- T:='';
- for I:=1 to Length(S) do
- begin
- O:=Ord(S[i]);
- if (O>127) then
- IllegalChar(S[i],be93Extended);
- T:=T+CharEncoding[O];
- end;
- Result:=Encode93(T);
- end;
- { ---------------------------------------------------------------------
- MSI
- ---------------------------------------------------------------------}
- Type
- TMSIChar = Array[1..8] of TBarType;
- Const
- EncodingMSI : array['0'..'9'] of TMSIChar = (
- ( 4, 1, 4, 1, 4, 1, 4, 1), // 0
- ( 4, 1, 4, 1, 4, 1, 5, 0), // 1
- ( 4, 1, 4, 1, 5, 0, 4, 1), // 2
- ( 4, 1, 4, 1, 5, 0, 5, 0), // 3
- ( 4, 1, 5, 0, 4, 1, 4, 1), // 4
- ( 4, 1, 5, 0, 4, 1, 5, 0), // 5
- ( 4, 1, 5, 0, 5, 0, 4, 1), // 6
- ( 4, 1, 5, 0, 5, 0, 5, 0), // 7
- ( 5, 0, 4, 1, 4, 1, 4, 1), // 8
- ( 5, 0, 4, 1, 4, 1, 5, 0) // 9
- );
- function EncodeMSI(S : AnsiString) : TBarTypeArray;
- function SumDigits(D: integer): integer;
- begin
- Result:=0;
- while (D>0) do
- begin
- Result:=Result+(D mod 10);
- D:=D div 10;
- end;
- end;
- Const
- MSIPrefix : Array [1..2] of TBarType = (5,0);
- MSISuffix : Array [1..3] of TBarType = (4,1,4);
- var
- P,I,CSE,CSO,CS : integer;
- C : AnsiChar;
- begin
- // Length(Prefix)+Length(Suffix)+Length(S)+CheckSum
- SetLength(Result,(Length(S)+1)*8+2+3);
- P:=0;
- AddToArray(Result,P,MSIPrefix); // Prefix
- CSE:=0;
- CSO:=0;
- for i:=1 to Length(s) do
- begin
- C:=S[i];
- if Not (C in NumChars) then
- IllegalChar(S[i],beMSI);
- if odd(i-1) then
- CSO:=CSO*10+Ord(C)
- else
- CSE:=CSE+Ord(c);
- AddToArray(Result,P,EncodingMSI[C]);
- end;
- // Add checksum
- CS:=(SumDigits(CSO*2) + CSE) mod 10;
- if CS>0 then
- CS:=10-CS;
- AddToArray(Result,P,EncodingMSI[chr(Ord('0')+CS)]);
- AddToArray(Result,P,MSISuffix); // Suffix
- end;
- { ---------------------------------------------------------------------
- CodaBar
- ---------------------------------------------------------------------}
- Type
- TCodabarChar = array[0..6] of TBarType;
- TCodabarCharZero = array[0..7] of TBarType;
- TCodaBarData = record
- c: AnsiChar;
- Data: TCodabarChar;
- end;
- Var
- EncodingCodaBar : array[0..19] of TCodaBarData = (
- (c: '1'; data: ( 4, 0, 4, 0, 5, 1, 4)),
- (c: '2'; data: ( 4, 0, 4, 1, 4, 0, 5)),
- (c: '3'; data: ( 5, 1, 4, 0, 4, 0, 4)),
- (c: '4'; data: ( 4, 0, 5, 0, 4, 1, 4)),
- (c: '5'; data: ( 5, 0, 4, 0, 4, 1, 4)),
- (c: '6'; data: ( 4, 1, 4, 0, 4, 0, 5)),
- (c: '7'; data: ( 4, 1, 4, 0, 5, 0, 4)),
- (c: '8'; data: ( 4, 1, 5, 0, 4, 0, 4)),
- (c: '9'; data: ( 5, 0, 4, 1, 4, 0, 4)),
- (c: '0'; data: ( 4, 0, 4, 0, 4, 1, 5)),
- (c: '-'; data: ( 4, 0, 4, 1, 5, 0, 4)),
- (c: '$'; data: ( 4, 0, 5, 1, 4, 0, 4)),
- (c: ':'; data: ( 5, 0, 4, 0, 5, 0, 5)),
- (c: '/'; data: ( 5, 0, 5, 0, 4, 0, 5)),
- (c: '.'; data: ( 5, 0, 5, 0, 5, 0, 4)),
- (c: '+'; data: ( 4, 0, 5, 0, 5, 0, 5)),
- (c: 'A'; data: ( 4, 0, 5, 1, 4, 1, 4)),
- (c: 'B'; data: ( 4, 1, 4, 1, 4, 0, 5)),
- (c: 'C'; data: ( 4, 0, 4, 1, 4, 1, 5)),
- (c: 'D'; data: ( 4, 0, 4, 1, 5, 1, 4))
- );
- function IndexOfCodaChar(c: AnsiChar): integer;
- begin
- Result:=High(EncodingCodaBar);
- While (Result>=0) and (c<>EncodingCodaBar[Result].c) do
- Dec(Result);
- end;
- Function AllowEncodeCodaBar (S : AnsiString) : boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=IndexOfCodaChar(S[i])>=0;
- Inc(I);
- end;
- end;
- Function EncodeCodaBar(S : AnsiString) : TBarTypeArray;
- Function AddZero(C :TCodaBarChar) : TCodabarCharZero;
- begin
- Move(C,result,SizeOf(C));
- Result[7]:=0;
- end;
- var
- i, P, Idx: integer;
- begin
- // (Length(S)+1)*8+7
- Setlength(Result,(Length(S)+1)*8+7);
- P:=0;
- AddToArray(Result,P,AddZero(EncodingCodaBar[IndexOfCodaChar('A')].Data));
- for i:=1 to Length(S) do
- begin
- Idx:=IndexOfCodaChar(S[i]);
- if Idx<0 then
- IllegalChar(S[i],beCodabar);
- AddToArray(Result,P,AddZero(EncodingCodaBar[Idx].Data));
- end;
- AddToArray(Result,P,EncodingCodaBar[IndexOfCodaChar('B')].Data);
- end;
- { ---------------------------------------------------------------------
- Postnet
- ---------------------------------------------------------------------}
- Type
- TPostNetChar = Packed Array[1..10] of TBarType;
- Const
- EncodingPostNet : Packed array['0'..'9'] of TPostNetChar = (
- ( 4, 1, 4, 1, 8, 1, 8, 1, 8, 1), // 0
- ( 8, 1, 8, 1, 8, 1, 4, 1, 4, 1), // 1
- ( 8, 1, 8, 1, 4, 1, 8, 1, 4, 1), // 2
- ( 8, 1, 8, 1, 4, 1, 4, 1, 8, 1), // 3
- ( 8, 1, 4, 1, 8, 1, 8, 1, 4, 1), // 4
- ( 8, 1, 4, 1, 8, 1, 4, 1, 8, 1), // 5
- ( 8, 1, 4, 1, 4, 1, 8, 1, 8, 1), // 6
- ( 4, 1, 8, 1, 8, 1, 8, 1, 4, 1), // 7
- ( 4, 1, 8, 1, 8, 1, 4, 1, 8, 1), // 8
- ( 4, 1, 8, 1, 4, 1, 8, 1, 8, 1) // 9
- );
- Function EncodePostNet (S : AnsiString) : TBarTypeArray;
- var
- i,P : integer;
- begin
- SetLength(Result,Length(S)*10+2+1);
- P:=0;
- AddToArray(Result,P,[4,1]);
- for i := 1 to Length(S) do
- begin
- if Not (S[I] in NumChars) then
- IllegalChar(S[i],bePostNet);
- AddToArray(Result,P,EncodingPostNet[S[i]]);
- end;
- AddToArray(Result,P,[4]);
- end;
- { ---------------------------------------------------------------------
- Code 128
- ---------------------------------------------------------------------}
- Type
- TCode128Char = Packed Array[1..6] of TBarType;
- TCode128StopChar = Packed Array[1..7] of TBarType;
- Const
- // The order of these elements must be the same as for
- // the Encoding128A,Encoding128B,Encoding128C arrays below !
- Encoding128Data : Packed array[0..102] of TCode128Char = (
- ( 5, 0, 5, 1, 5, 1), // 0
- ( 5, 1, 5, 0, 5, 1), // 1
- ( 5, 1, 5, 1, 5, 0), // 2
- ( 4, 1, 4, 1, 5, 2), // 3
- ( 4, 1, 4, 2, 5, 1), // 4
- ( 4, 2, 4, 1, 5, 1), // 5
- ( 4, 1, 5, 1, 4, 2), // 6
- ( 4, 1, 5, 2, 4, 1), // 7
- ( 4, 2, 5, 1, 4, 1), // 8
- ( 5, 1, 4, 1, 4, 2), // 9
- ( 5, 1, 4, 2, 4, 1), // 10
- ( 5, 2, 4, 1, 4, 1), // 11
- ( 4, 0, 5, 1, 6, 1), // 12
- ( 4, 1, 5, 0, 6, 1), // 13
- ( 4, 1, 5, 1, 6, 0), // 14
- ( 4, 0, 6, 1, 5, 1), // 15
- ( 4, 1, 6, 0, 5, 1), // 16
- ( 4, 1, 6, 1, 5, 0), // 17
- ( 5, 1, 6, 1, 4, 0), // 18
- ( 5, 1, 4, 0, 6, 1), // 19
- ( 5, 1, 4, 1, 6, 0), // 20
- ( 5, 0, 6, 1, 4, 1), // 21
- ( 5, 1, 6, 0, 4, 1), // 22
- ( 6, 0, 5, 0, 6, 0), // 23
- ( 6, 0, 4, 1, 5, 1), // 24
- ( 6, 1, 4, 0, 5, 1), // 25
- ( 6, 1, 4, 1, 5, 0), // 26
- ( 6, 0, 5, 1, 4, 1), // 27
- ( 6, 1, 5, 0, 4, 1), // 28
- ( 6, 1, 5, 1, 4, 0), // 29
- ( 5, 0, 5, 0, 5, 2), // 30
- ( 5, 0, 5, 2, 5, 0), // 31
- ( 5, 2, 5, 0, 5, 0), // 32
- ( 4, 0, 4, 2, 5, 2), // 33
- ( 4, 2, 4, 0, 5, 2), // 34
- ( 4, 2, 4, 2, 5, 0), // 35
- ( 4, 0, 5, 2, 4, 2), // 36
- ( 4, 2, 5, 0, 4, 2), // 37
- ( 4, 2, 5, 2, 4, 0), // 38
- ( 5, 0, 4, 2, 4, 2), // 39
- ( 5, 2, 4, 0, 4, 2), // 40
- ( 5, 2, 4, 2, 4, 0), // 41
- ( 4, 0, 5, 0, 6, 2), // 42
- ( 4, 0, 5, 2, 6, 0), // 43
- ( 4, 2, 5, 0, 6, 0), // 44
- ( 4, 0, 6, 0, 5, 2), // 45
- ( 4, 0, 6, 2, 5, 0), // 46
- ( 4, 2, 6, 0, 5, 0), // 47
- ( 6, 0, 6, 0, 5, 0), // 48
- ( 5, 0, 4, 2, 6, 0), // 49
- ( 5, 2, 4, 0, 6, 0), // 50
- ( 5, 0, 6, 0, 4, 2), // 51
- ( 5, 0, 6, 2, 4, 0), // 52
- ( 5, 0, 6, 0, 6, 0), // 53
- ( 6, 0, 4, 0, 5, 2), // 54
- ( 6, 0, 4, 2, 5, 0), // 55
- ( 6, 2, 4, 0, 5, 0), // 56
- ( 6, 0, 5, 0, 4, 2), // 57
- ( 6, 0, 5, 2, 4, 0), // 58
- ( 6, 2, 5, 0, 4, 0), // 59
- ( 6, 0, 7, 0, 4, 0), // 60
- ( 5, 1, 4, 3, 4, 0), // 61
- ( 7, 2, 4, 0, 4, 0), // 62
- ( 4, 0, 4, 1, 5, 3), // 63
- ( 4, 0, 4, 3, 5, 1), // 64
- ( 4, 1, 4, 0, 5, 3), // 65
- ( 4, 1, 4, 3, 5, 0), // 66
- ( 4, 3, 4, 0, 5, 1), // 67
- ( 4, 3, 4, 1, 5, 0), // 68
- ( 4, 0, 5, 1, 4, 3), // 69
- ( 4, 0, 5, 3, 4, 1), // 70
- ( 4, 1, 5, 0, 4, 3), // 71
- ( 4, 1, 5, 3, 4, 0), // 72
- ( 4, 3, 5, 0, 4, 1), // 73
- ( 4, 3, 5, 1, 4, 0), // 74
- ( 5, 3, 4, 1, 4, 0), // 75
- ( 5, 1, 4, 0, 4, 3), // 76
- ( 7, 0, 6, 0, 4, 0), // 77
- ( 5, 3, 4, 0, 4, 1), // 78
- ( 4, 2, 7, 0, 4, 0), // 79
- ( 4, 0, 4, 1, 7, 1), // 80
- ( 4, 1, 4, 0, 7, 1), // 81
- ( 4, 1, 4, 1, 7, 0), // 82
- ( 4, 0, 7, 1, 4, 1), // 83
- ( 4, 1, 7, 0, 4, 1), // 84
- ( 4, 1, 7, 1, 4, 0), // 85
- ( 7, 0, 4, 1, 4, 1), // 86
- ( 7, 1, 4, 0, 4, 1), // 87
- ( 7, 1, 4, 1, 4, 0), // 88
- ( 5, 0, 5, 0, 7, 0), // 89
- ( 5, 0, 7, 0, 5, 0), // 90
- ( 7, 0, 5, 0, 5, 0), // 91
- ( 4, 0, 4, 0, 7, 2), // 92
- ( 4, 0, 4, 2, 7, 0), // 93
- ( 4, 2, 4, 0, 7, 0), // 94
- ( 4, 0, 7, 0, 4, 2), // 95
- ( 4, 0, 7, 2, 4, 0), // 96
- ( 7, 0, 4, 0, 4, 2), // 97
- ( 7, 0, 4, 2, 4, 0), // 98
- ( 4, 0, 6, 0, 7, 0), // 99
- ( 4, 0, 7, 0, 6, 0), // 100
- ( 6, 0, 4, 0, 7, 0), // 101
- ( 7, 0, 4, 0, 6, 0) // 102
- );
- Const
- Encoding128ACount = 64;
- Encoding128AChecksumInit = 103;
- Encoding128BCount = 95;
- Encoding128BChecksumInit = 104;
- Encoding128CChecksumInit = 105;
- Type
- /// 0 based, checksum relies on 0-based index
- TEncoding128AArray = Packed Array[0..Encoding128ACount-1] of Ansichar;
- TEncoding128BArray = Packed Array[0..Encoding128BCount-1] of Ansichar;
- Const
- StartEncoding128A : TCode128Char = ( 5, 0, 4, 3, 4, 1);
- StartEncoding128B : TCode128Char = ( 5, 0, 4, 1, 4, 3);
- StartEncoding128C : TCode128Char = ( 5, 0, 4, 1, 6, 1);
- StopEncoding128 : TCode128StopChar = ( 5, 2, 6, 0, 4, 0, 5);
- // The order of these elements must be the same as on Encoding128Data
- Encoding128A : TEncoding128AArray = (
- ' ','!','"','#','$','%','&','''','(',')',
- '*','+',',','-','.','/','0','1','2','3',
- '4','5','6','7','8','9',':',';','<','=',
- '>','?','@','A','B','C','D','E','F','G',
- 'H','I','J','K','L','M','N','O','P','Q',
- 'R','S','T','U','V','W','X','Y','Z','[',
- '\',']','^','_'
- );
- Encoding128B : TEncoding128BArray = (
- ' ','!','"','#','$','%','&','''','(',')',
- '*','+',',','-','.','/','0','1','2','3',
- '4','5','6','7','8','9',':',';','<','=',
- '>','?','@','A','B','C','D','E','F','G',
- 'H','I','J','K','L','M','N','O','P','Q',
- 'R','S','T','U','V','W','X','Y','Z','[',
- '\',']','^','_','`','a','b','c','d','e',
- 'f','g','h','i','j','k','l','m','n','o',
- 'p','q','r','s','t','u','v','w','x','y',
- 'z','{','|','}','~'
- );
- function IndexOf128AChar(c: AnsiChar): integer;
- begin
- Result:=0;
- While (Result<Encoding128ACount) and (c<>Encoding128A[Result]) do
- Inc(Result);
- if Result>=Encoding128ACount then
- Result:=-1;
- end;
- Function AllowEncode128A(S : AnsiString) : Boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=IndexOf128AChar(S[i])>=0;
- Inc(I);
- end;
- end;
- Function Encode128A(S : AnsiString) : TBarTypeArray;
- Var
- CS,I,P,Idx : integer;
- begin
- // Length(S)+StartCode+CheckSum+StopCode (stopcode has 7 bars)
- SetLength(Result,(Length(S)+2)*6+7);
- P:=0;
- AddToArray(Result,P,StartEncoding128A);
- CS:=Encoding128AChecksumInit;
- For I:=1 to Length(S) do
- begin
- Idx:=IndexOf128AChar(S[i]);
- if Idx<0 then
- IllegalChar(S[i],be128a);
- AddToArray(Result,P,Encoding128Data[Idx]);
- Inc(CS,Idx*I);
- end;
- // Cap CS
- CS:=CS mod 103;
- AddToArray(Result,P,Encoding128Data[CS]);
- AddToArray(Result,P,StopEncoding128);
- end;
- function IndexOf128BChar(c: AnsiChar): integer;
- begin
- Result:=1;
- While (Result<=Encoding128BCount) and (c<>Encoding128B[Result]) do
- Inc(Result);
- if Result>Encoding128BCount then
- Result:=-1;
- end;
- Function AllowEncode128B(S : AnsiString) : Boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=IndexOf128BChar(S[i])>=0;
- Inc(I);
- end;
- end;
- Function Encode128B(S : AnsiString) : TBarTypeArray;
- Var
- CS,I,P,Idx : integer;
- begin
- // Length(S)+StartCode+CheckSum+StopCode (stopcode has 7 bars)
- SetLength(Result,(Length(S)+2)*6+7);
- P:=0;
- AddToArray(Result,P,StartEncoding128B);
- CS:=Encoding128BChecksumInit;
- For I:=1 to Length(S) do
- begin
- Idx:=IndexOf128BChar(S[i]);
- if Idx<0 then
- IllegalChar(S[i],be128b);
- AddToArray(Result,P,Encoding128Data[Idx]);
- Inc(CS,Idx*I);
- end;
- // Cap CS
- CS:=CS mod 103;
- AddToArray(Result,P,Encoding128Data[CS]);
- AddToArray(Result,P,StopEncoding128);
- end;
- Function C(S : AnsiString) : TBarTypeArray;
- function IndexOfChar(c: AnsiChar): integer;
- begin
- Result:=1;
- While (Result<=Encoding128BCount) and (c<>Encoding128A[Result]) do
- Inc(Result);
- if Result>Encoding128BCount then
- Result:=-1;
- end;
- Var
- CS,I,P,Idx : integer;
- begin
- // Length(S)+StartCode+CheckSum+StopCode (stopcode has 7 bars)
- SetLength(Result,(Length(S)+2)*6+7);
- P:=0;
- AddToArray(Result,P,StartEncoding128B);
- CS:=Encoding128BChecksumInit;
- For I:=1 to Length(S) do
- begin
- Idx:=IndexOfChar(S[i]);
- if Idx<0 then
- IllegalChar(S[i],be128b);
- AddToArray(Result,P,Encoding128Data[Idx]);
- Inc(CS,Idx*I);
- end;
- // Cap CS
- CS:=CS mod 103;
- AddToArray(Result,P,Encoding128Data[CS]);
- AddToArray(Result,P,StopEncoding128);
- end;
- Function Encode128C(S : AnsiString) : TBarTypeArray;
- Var
- CS,I,CC,P,Idx : integer;
- T : AnsiString;
- begin
- // Length(S)+StartCode+CheckSum+StopCode (stopcode has 7 bars)
- if Odd(Length(S)) then
- S:='0'+S;
- I:=1;
- T:='';
- // construct a AnsiString with codes.
- while i<Length(S) do
- begin
- CC:=StrToIntDef(Copy(S,i,2),-1);
- if CC=-1 then
- IllegalChar(S[i],be128C);
- T:=T+Chr(CC);
- Inc(I,2);
- end;
- // With the new AnsiString, construct barcode
- SetLength(Result,(Length(T)+2)*6+7);
- P:=0;
- AddToArray(Result,P,StartEncoding128C);
- CS:=Encoding128CChecksumInit;
- For I:=1 to Length(T) do
- begin
- Idx:=Ord(T[i]);
- AddToArray(Result,P,Encoding128Data[Idx]);
- Inc(CS,Idx*I);
- end;
- // Cap CS
- CS:=CS mod 103;
- AddToArray(Result,P,Encoding128Data[CS]);
- AddToArray(Result,P,StopEncoding128);
- end;
- { ---------------------------------------------------------------------
- Barcode 2 of 5
- ---------------------------------------------------------------------}
- Type
- TCode2of5Char = Packed array [1..5] of boolean;
- Const
- Encoding2of5 : array['0'..'9'] of TCode2of5Char = (
- (false, false, True, True, false), // 0
- (True, false, false, false, True), // 1
- (false, True, false, false, True), // 2
- (True, True, false, false, false), // 3
- (false, false, True, false, True), // 4
- (True, false, True, false, false), // 5
- (false, True, True, false, false), // 6
- (false, false, false, True, True), // 7
- (True, false, false, True, false), // 8
- (false, True, false, True, false) // 9
- );
- Function Encode2of5Interleaved(S : AnsiString) : TBarTypeArray;
- Const
- Encode2of5Start : Array [1..4] of TBarType = (4,0,4,0);
- Encode2of5Stop : Array [1..3] of TBarType = (5,0,4);
- COdd : Array [Boolean] of TBarType = (4,5);
- CEven : Array [Boolean] of TBarType = (0,1);
- var
- P, i, j: integer;
- CC : Array[1..2] of TBarType;
- begin
- SetLength(Result,(Length(S)*5)+4+3);
- P:=0;
- AddToArray(Result,P,Encode2of5Start);
- for i := 1 to Length(S) div 2 do
- for j:=1 to 5 do
- begin
- if not (S[i*2-1] in NumChars) then
- IllegalChar(S[i*2-1],be2of5interleaved);
- if not (S[i*2] in NumChars) then
- IllegalChar(S[i*2],be2of5interleaved);
- CC[1]:=COdd[Encoding2of5[S[i*2-1],j]];
- CC[2]:=CEven[Encoding2of5[S[i*2],j]];
- AddToArray(Result,P,CC);
- end;
- AddToArray(Result,P,Encode2of5Stop);
- end;
- Function Encode2of5Industrial(S : AnsiString) : TBarTypeArray;
- Const
- Encode2of5Start : Array [1..6] of TBarType = (5,0,5,0,4,0);
- Encode2of5Stop : Array [1..6] of TBarType = (5,0,4,0,5,0);
- Codes : Array [Boolean] of Array[1..2] of TBarType = ((4,0),(5,0));
- var
- P,I,J : integer;
- C : AnsiChar;
- begin
- // Length of AnsiString * 2 + StartCode+StopCode
- SetLength(Result,Length(S)*10+6+6);
- P:=0;
- AddToArray(Result,P,Encode2of5Start);
- for i := 1 to Length(S) do
- for j := 1 to 5 do
- begin
- C:=S[i];
- if not (C in NumChars) then
- IllegalChar(C,be2of5industrial);
- AddToArray(Result,P,Codes[Encoding2of5[S[i],j]]);
- end;
- AddToArray(Result,P,Encode2of5Stop);
- end;
- Function Encode2of5Matrix(S : AnsiString) : TBarTypeArray;
- Const
- Encode2of5Start : Array [1..6] of TBarType = (6,0,4,0,4,0);
- Encode2of5Stop : Array [1..5] of TBarType = (6,0,4,0,4);
- var
- P,I,J : integer;
- C : AnsiChar;
- BT : TBarType;
- begin
- // Length of AnsiString + StartCode+StopCode
- SetLength(Result,Length(S)*6+6+5);
- P:=0;
- AddToArray(Result,P,Encode2of5Start);
- for i:=1 to Length(S) do
- begin
- for j:=1 to 5 do
- begin
- C:=S[i];
- if not (C in NumChars) then
- IllegalChar(C,be2of5industrial);
- BT:=Ord(Encoding2of5[S[i],j]); // 0 or 1
- if odd(J) then
- BT:=BT+4;
- AddToArray(Result,P,[BT]);
- end;
- AddToArray(Result,P,[0]);
- end;
- AddToArray(Result,P,Encode2of5Stop);
- end;
- { ---------------------------------------------------------------------
- Global routines
- ---------------------------------------------------------------------}
- Function AllNumerical (S : AnsiString) : boolean;
- Var
- I,L : integer;
- begin
- L:=Length(S);
- Result:=L>0;
- I:=1;
- While Result and (I<=L) do
- begin
- Result:=S[i] in Numchars;
- Inc(I);
- end;
- end;
- Function StringAllowsBarEncoding(S : AnsiString; aEncoding : TBarcodeEncoding) : Boolean;
- begin
- if (AEncoding in NumericalEncodings) then
- Result:=AllNumerical(S)
- else
- Case aEncoding of
- be128A : Result:=AllowEncode128A(S);
- be128B : Result:=AllowEncode128B(S);
- be39: Result:=AllowEncode39(S);
- be39Extended: Result:=AllowEncode39Extended(S);
- be93: Result:=AllowEncode93(S);
- be93Extended: Result:=AllowEncode93Extended(S);
- beCodabar: Result:=AllowEncodeCodaBar(S);
- else
- Raise EBarEncoding.CreateFmt('Unknown/Unhandled encoding, ordinal value : %d',[ord(aEncoding)]);
- end;
- end;
- Function StringToBarTypeArray(S : AnsiString; aEncoding : TBarcodeEncoding) : TBarTypeArray;
- begin
- SetLength(Result,0);
- Case aEncoding of
- beEAN8 : Result:=EncodeEan8(S);
- beEAN13 : Result:=EncodeEan13(S);
- be128A : Result:=Encode128A(S);
- be128B : Result:=Encode128B(S);
- be128C: Result:=Encode128C(S);
- be2of5industrial: Result:=Encode2of5Industrial(S);
- be2of5interleaved: Result:=Encode2of5Interleaved(S);
- be2of5matrix: Result:=Encode2of5Matrix(S);
- be39: Result:=Encode39(S,False);
- be39Extended: Result:=Encode39Extended(S,False);
- be93: Result:=Encode93(S);
- be93Extended: Result:=Encode93Extended(S);
- beCodabar: Result:=EncodeCodaBar(S);
- beMSI: Result:=EncodeMSI(S);
- bePostNet : Result:=EncodePostNet(S);
- else
- Raise EBarEncoding.CreateFmt('Unknown/Unhandled encoding, ordinal value : %d',[ord(aEncoding)]);
- end;
- end;
- Function StringToBarcodeParams(S : AnsiString; aEncoding : TBarcodeEncoding) : TBarParamsArray;
- begin
- Result:=BarTypeArrayToBarParamsArray(StringToBarTypeArray(S,aEncoding));
- end;
- Function IntToBarTypeArray(I: Int64; aEncoding : TBarcodeEncoding; aWidth : Integer = 0) : TBarTypeArray;
- Var
- S : AnsiString;
- L : integer;
- begin
- S:=IntToStr(i);
- L:=Length(S);
- if (AWidth>0) and (L<AWidth) then
- S:=StringOfChar('0',AWidth-L)+S;
- Result:=StringToBarTypeArray(S,aEncoding);
- end;
- Function IntToBarcodeParams(I : Int64; aEncoding : TBarcodeEncoding; aWidth : Integer = 0) : TBarParamsArray;
- begin
- Result:=BarTypeArrayToBarParamsArray(IntToBarTypeArray(I,aEncoding,aWidth));
- end;
- Function BarTypeToBarParams(aType : TBarType) : TBarParams;
- begin
- Result:=BarTypes[aType];
- end;
- Function BarTypeArrayToBarParamsArray(anArray : TBarTypeArray) : TBarParamsArray;
- Var
- I: Integer;
- begin
- Setlength(Result,Length(anArray));
- For I:=0 to length(AnArray)-1 do
- Result[i]:=BarTypeToBarParams(anArray[i]);
- end;
- function CalcBarWidths(aEncoding: TBarcodeEncoding; aUnit: Integer; AWeight: Double): TBarWidthArray;
- Const
- Weight2to3Encodings =
- [be2of5interleaved, be2of5industrial, be39, beEAN8, beEAN13, be39Extended, beCodabar];
- Weight225to3Encodings = [be2of5matrix];
- begin
- if aEncoding in Weight2to3Encodings then
- begin
- if aWeight < 2.0 then
- aWeight := 2.0;
- if aWeight > 3.0 then
- aWeight := 3.0;
- end
- else if aEncoding in Weight225to3Encodings then
- begin
- if aWeight < 2.25 then
- aWeight := 2.25;
- if aWeight > 3.0 then
- aWeight := 3.0;
- end;
- Result[bw100]:=aUnit;
- Result[bwWeighted]:=Round(aUnit*aWeight);
- Result[bw150]:=Result[bwWeighted]*3 div 2;
- Result[bw200]:=Result[bwWeighted]*2;
- end;
- function CalcStringWidthInBarCodeEncoding(S : AnsiString;aEncoding: TBarcodeEncoding; aUnit: Integer; AWeight: Double): Cardinal;
- Var
- BP : TBarParams;
- Data : TBarTypeArray;
- BWT : TBarWidthArray;
- I : integer;
- begin
- Result:=0;
- BWT:=CalcBarWidths(aEncoding,aUnit,aWeight);
- Data:=StringToBarTypeArray(S,aEncoding);
- for i:=0 to Length(Data)-1 do // examine the pattern string
- begin
- BP:=BarTypeToBarParams(Data[i]);
- Result:=Result+BWT[BP.w];
- end;
- end;
- end.
|