/components/lazreport/source/barcode.pas
http://github.com/graemeg/lazarus · Pascal · 1645 lines · 1219 code · 203 blank · 223 comment · 79 complexity · fcedb6deb92b4773f1f56c85f3cc1717 MD5 · raw file
- unit Barcode;
- {
- Barcode Component
- Version 1.5 (23 Apr 1999)
- Copyright 1998-99 Andreas Schmidt and friends
- Freeware
- for use with Delphi 2/3/4
- this component is for private use only !
- i'am not responsible for wrong barcodes
- bug-reports, enhancements:
- mailto:shmia@bizerba.de or a_j_schmidt@rocketmail.com
- get latest version from
- http://members.tripod.de/AJSchmidt/index.html
- thanx to Nikolay Simeonov, Wolfgang Koranda, Norbert Waas,
- Richard Hugues and Olivier Guilbaud.
- Diese Komponente darf nur in privaten Projekten verwendet werden.
- Die Weitergabe von veränderte Dateien ist nicht zulässig.
- Für die Korrektheit der erzeugten Barcodes kann keine Garantie
- übernommen werden.
- Anregungen, Bug-Reports, Danksagungen an:
- mailto:shmia@bizerba.de
- History:
- ----------------------------------------------------------------------
- Version 1.0:
- - initial release
- Version 1.1:
- - more comments
- - changed function Code_93Extended (now correct ?)
- Version 1.2:
- - Bugs (found by Nikolay Simeonov) removed
- Version 1.3:
- - EAN8/EAN13 added by Wolfgang Koranda (wkoranda@csi.com)
- Version 1.4:
- - Bug (found by Norbert Waas) removed
- Component must save the Canvas-properties Font,Pen and Brush
- Version 1.5:
- - Bug (found by Richard Hugues) removed
- Last line of barcode was 1 Pixel too wide
- Version 1.6:
- - new read-only property 'Width'
- Todo (missing features)
- -----------------------
- - Wrapper Class for Quick Reports
- }
- interface
- {$I lr_vers.inc}
- uses
- SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
- type
- TBarcodeType = (bcCode_2_5_interleaved,
- bcCode_2_5_industrial,
- bcCode_2_5_matrix,
- bcCode39,
- bcCode39Extended,
- bcCode128A,
- bcCode128B,
- bcCode128C,
- bcCode93,
- bcCode93Extended,
- bcCodeMSI,
- bcCodePostNet,
- bcCodeCodabar,
- bcCodeEAN8,
- bcCodeEAN13
- );
- TBarLineType = (white, black, black_half); // for internal use only
- // black_half means a black line with 2/5 height (used for PostNet)
- { TBarcode }
- TBarcode = class(TComponent)
- private
- { Private-Deklarationen }
- FHeight: integer;
- FText: string;
- FTop: integer;
- FLeft: integer;
- FModul: integer;
- FRatio: double;
- FTyp: TBarcodeType;
- FCheckSum: boolean;
- FShowText: boolean;
- FAngle: double;
- FCodetext: string;
- modules: array[0..3] of shortint;
- procedure OneBarProps(code: char; out aWidth: integer; out lt: TBarLineType);
- procedure DoLines(Data: string; Canvas: TCanvas);
- function Code_2_5_interleaved: string;
- function Code_2_5_industrial: string;
- function Code_2_5_matrix: string;
- function Code_39: string;
- function Code_39Extended: string;
- function Code_128: string;
- function Code_93: string;
- function Code_93Extended: string;
- function Code_MSI: string;
- function Code_PostNet: string;
- function Code_Codabar: string;
- function Code_EAN8: string;
- function Code_EAN13: string;
- function GetTypText: string;
- procedure MakeModules;
- procedure SetModul(v: integer);
- function GetWidth: integer;
- procedure SetText(AValue: string);
- function CleanEANValue(const AValue: string; const ASize:Byte): string;
- protected
- { Protected-Deklarationen }
- function MakeData: string;
- public
- { Public-Deklarationen }
- constructor Create(aOwner: TComponent); override;
- procedure DrawBarcode(Canvas: TCanvas);
- procedure DrawText(Canvas: TCanvas);
- function BarcodeTypeChecked(AType: TBarcodeType): boolean;
- property CodeText: string read FCodetext write FCodeText;
- published
- { Published-Deklarationen }
- // Height of Barcode (Pixel)
- property Height: integer read FHeight write FHeight;
- property Text: string read FText write SetText;
- property Top: integer read FTop write FTop;
- property Left: integer read FLeft write FLeft;
- // Width of the smallest line in a Barcode
- property Modul: integer read FModul write SetModul;
- property Ratio: double read FRatio write FRatio;
- property Typ: TBarcodeType read FTyp write FTyp default bcCode_2_5_interleaved;
- // build CheckSum ?
- property Checksum: boolean read FCheckSum write FCheckSum default False;
- // 0 - 360 degree
- property Angle: double read FAngle write FAngle;
- property ShowText: boolean read FShowText write FShowText default False;
- property Width: integer read GetWidth;
- end;
- // procedure Register; // Removed by TZ
- implementation
- {
- converts a string from '321' to the internal representation '715'
- i need this function because some pattern tables have a different
- format :
- '00111'
- converts to '05161'
- }
- function Convert(s: string): string;
- var
- i, v: integer;
- t: string;
- begin
- t := '';
- for i := 1 to Length(s) do
- begin
- v := Ord(s[i]) - 1;
- if odd(i) then
- Inc(v, 5);
- t := t + Chr(v);
- end;
- Convert := t;
- end;
- (*
- * Berechne die Quersumme aus einer Zahl x
- * z.B.: Quersumme von 1234 ist 10
- *)
- function quersumme(x: integer): integer;
- var
- sum: integer;
- begin
- sum := 0;
- while x > 0 do
- begin
- sum := sum + (x mod 10);
- x := x div 10;
- end;
- Result := sum;
- end;
- {
- Rotate a Point by Angle 'alpha'
- }
- function Rotate2D(p: TPoint; alpha: double): TPoint;
- var
- sinus, cosinus: extended;
- begin
- sinus := sin(alpha);
- cosinus := cos(alpha);
- Result.x := Round(p.x * cosinus + p.y * sinus);
- Result.y := Round(-p.x * sinus + p.y * cosinus);
- end;
- {
- Move Point a by Vector b
- }
- function Translate2D(a, b: TPoint): TPoint;
- begin
- Result.x := a.x + b.x;
- Result.y := a.y + b.y;
- end;
- constructor TBarcode.Create(aOwner: TComponent);
- begin
- inherited Create(aOwner);
- FAngle := 0.0;
- FRatio := 2.0;
- FModul := 1;
- FTyp := bcCodeEAN13;
- FCheckSum := False;
- FShowText := False;
- end;
- function TBarcode.GetTypText: string;
- const
- bcNames: array[bcCode_2_5_interleaved..bcCodeEAN13] of string =
- (
- ('2_5_interleaved'),
- ('2_5_industrial'),
- ('2_5_matrix'),
- ('Code39'),
- ('Code39 Extended'),
- ('Code128A'),
- ('Code128B'),
- ('Code128C'),
- ('Code93'),
- ('Code93 Extended'),
- ('MSI'),
- ('PostNet'),
- ('Codebar'),
- ('EAN8'),
- ('EAN13')
- );
- begin
- Result := bcNames[FTyp];
- end;
- // set Modul Width
- procedure TBarcode.SetModul(v: integer);
- begin
- if (v >= 1) and (v < 50) then
- FModul := v;
- end;
- {
- calculate the width and the linetype of a sigle bar
- Code Line-Color Width Height
- ------------------------------------------------------------------
- '0' white 100% full
- '1' white 100%*Ratio full
- '2' white 150%*Ratio full
- '3' white 200%*Ratio full
- '5' black 100% full
- '6' black 100%*Ratio full
- '7' black 150%*Ratio full
- '8' black 200%*Ratio full
- 'A' black 100% 2/5 (used for PostNet)
- 'B' black 100%*Ratio 2/5 (used for PostNet)
- 'C' black 150%*Ratio 2/5 (used for PostNet)
- 'D' black 200%*Ratio 2/5 (used for PostNet)
- }
- procedure TBarcode.OneBarProps(code: char; out aWidth: integer; out lt: TBarLineType);
- begin
- case code of
- '0':
- begin
- aWidth := modules[0];
- lt := white;
- end;
- '1':
- begin
- aWidth := modules[1];
- lt := white;
- end;
- '2':
- begin
- aWidth := modules[2];
- lt := white;
- end;
- '3':
- begin
- aWidth := modules[3];
- lt := white;
- end;
- '5':
- begin
- aWidth := modules[0];
- lt := black;
- end;
- '6':
- begin
- aWidth := modules[1];
- lt := black;
- end;
- '7':
- begin
- aWidth := modules[2];
- lt := black;
- end;
- '8':
- begin
- aWidth := modules[3];
- lt := black;
- end;
- 'A':
- begin
- aWidth := modules[0];
- lt := black_half;
- end;
- 'B':
- begin
- aWidth := modules[1];
- lt := black_half;
- end;
- 'C':
- begin
- aWidth := modules[2];
- lt := black_half;
- end;
- 'D':
- begin
- aWidth := modules[3];
- lt := black_half;
- end;
- else
- begin
- // something went wrong :-(
- // mistyped pattern table
- raise Exception.CreateFmt('%s: internal Error', [self.ClassName]);
- end;
- end;
- end;
- function TBarcode.MakeData: string;
- begin
- // calculate the with of the different lines (modules)
- MakeModules;
- // get the pattern of the barcode
- case Typ of
- bcCode_2_5_interleaved:
- Result := Code_2_5_interleaved;
- bcCode_2_5_industrial:
- Result := Code_2_5_industrial;
- bcCode_2_5_matrix:
- Result := Code_2_5_matrix;
- bcCode39:
- Result := Code_39;
- bcCode39Extended:
- Result := Code_39Extended;
- bcCode128A,
- bcCode128B,
- bcCode128C:
- Result := Code_128;
- bcCode93:
- Result := Code_93;
- bcCode93Extended:
- Result := Code_93Extended;
- bcCodeMSI:
- Result := Code_MSI;
- bcCodePostNet:
- Result := Code_PostNet;
- bcCodeCodabar:
- Result := Code_Codabar;
- bcCodeEAN8:
- Result := Code_EAN8;
- bcCodeEAN13:
- Result := Code_EAN13;
- else
- raise Exception.CreateFmt('%s: wrong BarcodeType', [self.ClassName]);
- end;
- //Showmessage(Format('Data <%s>', [Result]));
- end;
- function TBarcode.GetWidth: integer;
- var
- Data: string;
- i: integer;
- w: integer;
- lt: TBarLineType;
- begin
- Result := 0;
- // get barcode pattern
- Data := MakeData;
- for i := 1 to Length(Data) do // examine the pattern string
- begin
- OneBarProps(Data[i], w, lt);
- Inc(Result, w);
- end;
- end;
- procedure TBarcode.SetText(AValue: string);
- begin
- if FText=AValue then Exit;
- FText:=AValue;
- FCodeText:=AValue;
- end;
- ////////////////////////////// EAN /////////////////////////////////////////
- function getEAN(Nr: string): string;
- var
- i, fak, sum: integer;
- tmp: string;
- begin
- sum := 0;
- tmp := copy(nr, 1, Length(Nr) - 1);
- fak := Length(tmp);
- for i := 1 to length(tmp) do
- begin
- if (fak mod 2) = 0 then
- sum := sum + (StrToInt(tmp[i]) * 1)
- else
- sum := sum + (StrToInt(tmp[i]) * 3);
- Dec(fak);
- end;
- if (sum mod 10) = 0 then
- Result := tmp + '0'
- else
- Result := tmp + IntToStr(10 - (sum mod 10));
- end;
- ////////////////////////////// EAN8 /////////////////////////////////////////
- // Pattern for Barcode EAN Zeichensatz A
- // L1 S1 L2 S2
- const
- tabelle_EAN_A: array['0'..'9', 1..4] of char =
- (
- ('2', '6', '0', '5'), // 0
- ('1', '6', '1', '5'), // 1
- ('1', '5', '1', '6'), // 2
- ('0', '8', '0', '5'), // 3
- ('0', '5', '2', '6'), // 4
- ('0', '6', '2', '5'), // 5
- ('0', '5', '0', '8'), // 6
- ('0', '7', '0', '6'), // 7
- ('0', '6', '0', '7'), // 8
- ('2', '5', '0', '6') // 9
- );
- // Pattern for Barcode EAN Zeichensatz C
- // S1 L1 S2 L2
- const
- tabelle_EAN_C: array['0'..'9', 1..4] of char =
- (
- ('7', '1', '5', '0'), // 0
- ('6', '1', '6', '0'), // 1
- ('6', '0', '6', '1'), // 2
- ('5', '3', '5', '0'), // 3
- ('5', '0', '7', '1'), // 4
- ('5', '1', '7', '0'), // 5
- ('5', '0', '5', '3'), // 6
- ('5', '2', '5', '1'), // 7
- ('5', '1', '5', '2'), // 8
- ('7', '0', '5', '1') // 9
- );
- function TBarcode.Code_EAN8: string;
- var
- i, j: integer;
- begin
- FCodeText := CleanEANValue(FText, 8);
- Result := '505'; // Startcode
- for i := 1 to 4 do
- for j := 1 to 4 do
- begin
- Result := Result + tabelle_EAN_A[FCodeText[i], j];
- end;
- Result := Result + '05050'; // Trennzeichen
- for i := 5 to 8 do
- for j := 1 to 4 do
- begin
- Result := Result + tabelle_EAN_C[FCodeText[i], j];
- end;
- Result := Result + '505'; // Stopcode
- end;
- ////////////////////////////// EAN13 ///////////////////////////////////////
- // Pattern for Barcode EAN Zeichensatz B
- // L1 S1 L2 S2
- const
- tabelle_EAN_B: array['0'..'9', 1..4] of char =
- (
- ('0', '5', '1', '7'), // 0
- ('0', '6', '1', '6'), // 1
- ('1', '6', '0', '6'), // 2
- ('0', '5', '3', '5'), // 3
- ('1', '7', '0', '5'), // 4
- ('0', '7', '1', '5'), // 5
- ('3', '5', '0', '5'), // 6
- ('1', '5', '2', '5'), // 7
- ('2', '5', '1', '5'), // 8
- ('1', '5', '0', '7') // 9
- );
- // Zuordung der Paraitaetsfolgen für EAN13
- const
- tabelle_ParityEAN13: array[0..9, 1..6] of char =
- (
- ('A', 'A', 'A', 'A', 'A', 'A'), // 0
- ('A', 'A', 'B', 'A', 'B', 'B'), // 1
- ('A', 'A', 'B', 'B', 'A', 'B'), // 2
- ('A', 'A', 'B', 'B', 'B', 'A'), // 3
- ('A', 'B', 'A', 'A', 'B', 'B'), // 4
- ('A', 'B', 'B', 'A', 'A', 'B'), // 5
- ('A', 'B', 'B', 'B', 'A', 'A'), // 6
- ('A', 'B', 'A', 'B', 'A', 'B'), // 7
- ('A', 'B', 'A', 'B', 'B', 'A'), // 8
- ('A', 'B', 'B', 'A', 'B', 'A') // 9
- );
- function TBarcode.Code_EAN13: string;
- var
- i, j, LK: integer;
- tmp: string;
- begin
- FCodeText := CleanEanValue(FText, 13);
- LK := StrToInt(FCodeText[1]);
- tmp := copy(FCodeText, 2, 12);
- Result := '505'; // Startcode
- for i := 1 to 6 do
- begin
- case tabelle_ParityEAN13[LK, i] of
- 'A':
- for j := 1 to 4 do
- Result := Result + tabelle_EAN_A[tmp[i], j];
- 'B':
- for j := 1 to 4 do
- Result := Result + tabelle_EAN_B[tmp[i], j];
- 'C':
- for j := 1 to 4 do
- Result := Result + tabelle_EAN_C[tmp[i], j];
- end;
- end;
- Result := Result + '05050'; // Trennzeichen
- for i := 7 to 12 do
- for j := 1 to 4 do
- begin
- Result := Result + tabelle_EAN_C[tmp[i], j];
- end;
- Result := Result + '505'; // Stopcode
- end;
- // Pattern for Barcode 2 of 5
- const
- tabelle_2_5: array['0'..'9', 1..5] of char =
- (
- ('0', '0', '1', '1', '0'), // 0
- ('1', '0', '0', '0', '1'), // 1
- ('0', '1', '0', '0', '1'), // 2
- ('1', '1', '0', '0', '0'), // 3
- ('0', '0', '1', '0', '1'), // 4
- ('1', '0', '1', '0', '0'), // 5
- ('0', '1', '1', '0', '0'), // 6
- ('0', '0', '0', '1', '1'), // 7
- ('1', '0', '0', '1', '0'), // 8
- ('0', '1', '0', '1', '0') // 9
- );
- function TBarcode.Code_2_5_interleaved: string;
- var
- i, j: integer;
- c: char;
- begin
- Result := '5050'; // Startcode
- for i := 1 to Length(FText) div 2 do
- begin
- for j := 1 to 5 do
- begin
- if tabelle_2_5[FText[i * 2 - 1], j] = '1' then
- c := '6'
- else
- c := '5';
- Result := Result + c;
- if tabelle_2_5[FText[i * 2], j] = '1' then
- c := '1'
- else
- c := '0';
- Result := Result + c;
- end;
- end;
- Result := Result + '605'; // Stopcode
- end;
- function TBarcode.Code_2_5_industrial: string;
- var
- i, j: integer;
- begin
- Result := '606050'; // Startcode
- for i := 1 to Length(FText) do
- begin
- for j := 1 to 5 do
- begin
- if tabelle_2_5[FText[i], j] = '1' then
- Result := Result + '60'
- else
- Result := Result + '50';
- end;
- end;
- Result := Result + '605060'; // Stopcode
- end;
- function TBarcode.Code_2_5_matrix: string;
- var
- i, j: integer;
- c: char;
- begin
- Result := '705050'; // Startcode
- for i := 1 to Length(FText) do
- begin
- for j := 1 to 5 do
- begin
- if tabelle_2_5[FText[i], j] = '1' then
- c := '1'
- else
- c := '0';
- // Falls i ungerade ist dann mache Lücke zu Strich
- if odd(j) then
- c := chr(Ord(c) + 5);
- Result := Result + c;
- end;
- Result := Result + '0'; // Lücke zwischen den Zeichen
- end;
- Result := Result + '70505'; // Stopcode
- end;
- function TBarcode.Code_39: string;
- type
- TCode39 = record
- c: char;
- Data: array[0..9] of char;
- chk: shortint;
- end;
- const
- tabelle_39: array[0..43] of TCode39 = (
- (c: '0'; Data: '505160605'; chk: 0),
- (c: '1'; Data: '605150506'; chk: 1),
- (c: '2'; Data: '506150506'; chk: 2),
- (c: '3'; Data: '606150505'; chk: 3),
- (c: '4'; Data: '505160506'; chk: 4),
- (c: '5'; Data: '605160505'; chk: 5),
- (c: '6'; Data: '506160505'; chk: 6),
- (c: '7'; Data: '505150606'; chk: 7),
- (c: '8'; Data: '605150605'; chk: 8),
- (c: '9'; Data: '506150605'; chk: 9),
- (c: 'A'; Data: '605051506'; chk: 10),
- (c: 'B'; Data: '506051506'; chk: 11),
- (c: 'C'; Data: '606051505'; chk: 12),
- (c: 'D'; Data: '505061506'; chk: 13),
- (c: 'E'; Data: '605061505'; chk: 14),
- (c: 'F'; Data: '506061505'; chk: 15),
- (c: 'G'; Data: '505051606'; chk: 16),
- (c: 'H'; Data: '605051605'; chk: 17),
- (c: 'I'; Data: '506051600'; chk: 18),
- (c: 'J'; Data: '505061605'; chk: 19),
- (c: 'K'; Data: '605050516'; chk: 20),
- (c: 'L'; Data: '506050516'; chk: 21),
- (c: 'M'; Data: '606050515'; chk: 22),
- (c: 'N'; Data: '505060516'; chk: 23),
- (c: 'O'; Data: '605060515'; chk: 24),
- (c: 'P'; Data: '506060515'; chk: 25),
- (c: 'Q'; Data: '505050616'; chk: 26),
- (c: 'R'; Data: '605050615'; chk: 27),
- (c: 'S'; Data: '506050615'; chk: 28),
- (c: 'T'; Data: '505060615'; chk: 29),
- (c: 'U'; Data: '615050506'; chk: 30),
- (c: 'V'; Data: '516050506'; chk: 31),
- (c: 'W'; Data: '616050505'; chk: 32),
- (c: 'X'; Data: '515060506'; chk: 33),
- (c: 'Y'; Data: '615060505'; chk: 34),
- (c: 'Z'; Data: '516060505'; chk: 35),
- (c: '-'; Data: '515050606'; chk: 36),
- (c: '.'; Data: '615050605'; chk: 37),
- (c: ' '; Data: '516050605'; chk: 38),
- (c: '*'; Data: '515060605'; chk: 0),
- (c: '$'; Data: '515151505'; chk: 39),
- (c: '/'; Data: '515150515'; chk: 40),
- (c: '+'; Data: '515051515'; chk: 41),
- (c: '%'; Data: '505151515'; chk: 42)
- );
- function FindIdx(z: char): integer;
- var
- i: integer;
- begin
- Result := -1;
- for i := 0 to High(tabelle_39) do
- begin
- if z = tabelle_39[i].c then
- begin
- Result := i;
- Break;
- end;
- end;
- end;
- var
- i, idx: integer;
- vChecksum: integer;
- begin
- vChecksum := 0;
- // Startcode
- Result := tabelle_39[FindIdx('*')].Data + '0';
- for i := 1 to Length(FText) do
- begin
- idx := FindIdx(FText[i]);
- if idx < 0 then
- continue;
- Result := Result + tabelle_39[idx].Data + '0';
- Inc(vChecksum, tabelle_39[idx].chk);
- end;
- // Calculate Checksum Data
- if FCheckSum then
- begin
- vChecksum := vChecksum mod 43;
- for i := 0 to High(tabelle_39) do
- if vChecksum = tabelle_39[i].chk then
- begin
- Result := Result + tabelle_39[i].Data + '0';
- exit;
- end;
- end;
- // Stopcode
- Result := Result + tabelle_39[FindIdx('*')].Data;
- end;
- function TBarcode.Code_39Extended: string;
- const
- code39x: 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
- save: string;
- i: integer;
- begin
- save := FText;
- FText := '';
- for i := 1 to Length(save) do
- begin
- if Ord(save[i]) <= 127 then
- FText := FText + code39x[Ord(save[i])];
- end;
- Result := Code_39;
- FText := save;
- end;
- {
- Code 128
- }
- function TBarcode.Code_128: string;
- type
- TCode128 = record
- a, b: char;
- c: string[2];
- Data: string[6];
- end;
- const
- tabelle_128: array[0..102] of TCode128 = (
- (a: ' '; b: ' '; c: '00'; Data: '212222'; ),
- (a: '!'; b: '!'; c: '01'; Data: '222122'; ),
- (a: '"'; b: '"'; c: '02'; Data: '222221'; ),
- (a: '#'; b: '#'; c: '03'; Data: '121223'; ),
- (a: '$'; b: '$'; c: '04'; Data: '121322'; ),
- (a: '%'; b: '%'; c: '05'; Data: '131222'; ),
- (a: '&'; b: '&'; c: '06'; Data: '122213'; ),
- (a: ''''; b: ''''; c: '07'; Data: '122312'; ),
- (a: '('; b: '('; c: '08'; Data: '132212'; ),
- (a: ')'; b: ')'; c: '09'; Data: '221213'; ),
- (a: '*'; b: '*'; c: '10'; Data: '221312'; ),
- (a: '+'; b: '+'; c: '11'; Data: '231212'; ),
- (a: ','; b: ','; c: '12'; Data: '112232'; ),
- (a: '-'; b: '-'; c: '13'; Data: '122132'; ),
- (a: '.'; b: '.'; c: '14'; Data: '122231'; ),
- (a: '/'; b: '/'; c: '15'; Data: '113222'; ),
- (a: '0'; b: '0'; c: '16'; Data: '123122'; ),
- (a: '1'; b: '1'; c: '17'; Data: '123221'; ),
- (a: '2'; b: '2'; c: '18'; Data: '223211'; ),
- (a: '3'; b: '3'; c: '19'; Data: '221132'; ),
- (a: '4'; b: '4'; c: '20'; Data: '221231'; ),
- (a: '5'; b: '5'; c: '21'; Data: '213212'; ),
- (a: '6'; b: '6'; c: '22'; Data: '223112'; ),
- (a: '7'; b: '7'; c: '23'; Data: '312131'; ),
- (a: '8'; b: '8'; c: '24'; Data: '311222'; ),
- (a: '9'; b: '9'; c: '25'; Data: '321122'; ),
- (a: ':'; b: ':'; c: '26'; Data: '321221'; ),
- (a: ';'; b: ';'; c: '27'; Data: '312212'; ),
- (a: '<'; b: '<'; c: '28'; Data: '322112'; ),
- (a: '='; b: '='; c: '29'; Data: '322211'; ),
- (a: '>'; b: '>'; c: '30'; Data: '212123'; ),
- (a: '?'; b: '?'; c: '31'; Data: '212321'; ),
- (a: '@'; b: '@'; c: '32'; Data: '232121'; ),
- (a: 'A'; b: 'A'; c: '33'; Data: '111323'; ),
- (a: 'B'; b: 'B'; c: '34'; Data: '131123'; ),
- (a: 'C'; b: 'C'; c: '35'; Data: '131321'; ),
- (a: 'D'; b: 'D'; c: '36'; Data: '112313'; ),
- (a: 'E'; b: 'E'; c: '37'; Data: '132113'; ),
- (a: 'F'; b: 'F'; c: '38'; Data: '132311'; ),
- (a: 'G'; b: 'G'; c: '39'; Data: '211313'; ),
- (a: 'H'; b: 'H'; c: '40'; Data: '231113'; ),
- (a: 'I'; b: 'I'; c: '41'; Data: '231311'; ),
- (a: 'J'; b: 'J'; c: '42'; Data: '112133'; ),
- (a: 'K'; b: 'K'; c: '43'; Data: '112331'; ),
- (a: 'L'; b: 'L'; c: '44'; Data: '132131'; ),
- (a: 'M'; b: 'M'; c: '45'; Data: '113123'; ),
- (a: 'N'; b: 'N'; c: '46'; Data: '113321'; ),
- (a: 'O'; b: 'O'; c: '47'; Data: '133121'; ),
- (a: 'P'; b: 'P'; c: '48'; Data: '313121'; ),
- (a: 'Q'; b: 'Q'; c: '49'; Data: '211331'; ),
- (a: 'R'; b: 'R'; c: '50'; Data: '231131'; ),
- (a: 'S'; b: 'S'; c: '51'; Data: '213113'; ),
- (a: 'T'; b: 'T'; c: '52'; Data: '213311'; ),
- (a: 'U'; b: 'U'; c: '53'; Data: '213131'; ),
- (a: 'V'; b: 'V'; c: '54'; Data: '311123'; ),
- (a: 'W'; b: 'W'; c: '55'; Data: '311321'; ),
- (a: 'X'; b: 'X'; c: '56'; Data: '331121'; ),
- (a: 'Y'; b: 'Y'; c: '57'; Data: '312113'; ),
- (a: 'Z'; b: 'Z'; c: '58'; Data: '312311'; ),
- (a: '['; b: '['; c: '59'; Data: '332111'; ),
- (a: '\'; b: '\'; c: '60'; Data: '314111'; ),
- (a: ']'; b: ']'; c: '61'; Data: '221411'; ),
- (a: '^'; b: '^'; c: '62'; Data: '431111'; ),
- (a: '_'; b: '_'; c: '63'; Data: '111224'; ),
- (a: ' '; b: '`'; c: '64'; Data: '111422'; ),
- (a: ' '; b: 'a'; c: '65'; Data: '121124'; ),
- (a: ' '; b: 'b'; c: '66'; Data: '121421'; ),
- (a: ' '; b: 'c'; c: '67'; Data: '141122'; ),
- (a: ' '; b: 'd'; c: '68'; Data: '141221'; ),
- (a: ' '; b: 'e'; c: '69'; Data: '112214'; ),
- (a: ' '; b: 'f'; c: '70'; Data: '112412'; ),
- (a: ' '; b: 'g'; c: '71'; Data: '122114'; ),
- (a: ' '; b: 'h'; c: '72'; Data: '122411'; ),
- (a: ' '; b: 'i'; c: '73'; Data: '142112'; ),
- (a: ' '; b: 'j'; c: '74'; Data: '142211'; ),
- (a: ' '; b: 'k'; c: '75'; Data: '241211'; ),
- (a: ' '; b: 'l'; c: '76'; Data: '221114'; ),
- (a: ' '; b: 'm'; c: '77'; Data: '413111'; ),
- (a: ' '; b: 'n'; c: '78'; Data: '241112'; ),
- (a: ' '; b: 'o'; c: '79'; Data: '134111'; ),
- (a: ' '; b: 'p'; c: '80'; Data: '111242'; ),
- (a: ' '; b: 'q'; c: '81'; Data: '121142'; ),
- (a: ' '; b: 'r'; c: '82'; Data: '121241'; ),
- (a: ' '; b: 's'; c: '83'; Data: '114212'; ),
- (a: ' '; b: 't'; c: '84'; Data: '124112'; ),
- (a: ' '; b: 'u'; c: '85'; Data: '124211'; ),
- (a: ' '; b: 'v'; c: '86'; Data: '411212'; ),
- (a: ' '; b: 'w'; c: '87'; Data: '421112'; ),
- (a: ' '; b: 'x'; c: '88'; Data: '421211'; ),
- (a: ' '; b: 'y'; c: '89'; Data: '212141'; ),
- (a: ' '; b: 'z'; c: '90'; Data: '214121'; ),
- (a: ' '; b: '{'; c: '91'; Data: '412121'; ),
- (a: ' '; b: '|'; c: '92'; Data: '111143'; ),
- (a: ' '; b: '}'; c: '93'; Data: '111341'; ),
- (a: ' '; b: '~'; c: '94'; Data: '131141'; ),
- (a: ' '; b: ' '; c: '95'; Data: '114113'; ),
- (a: ' '; b: ' '; c: '96'; Data: '114311'; ),
- (a: ' '; b: ' '; c: '97'; Data: '411113'; ),
- (a: ' '; b: ' '; c: '98'; Data: '411311'; ),
- (a: ' '; b: ' '; c: '99'; Data: '113141'; ),
- (a: ' '; b: ' '; c: ' '; Data: '114131'; ),
- (a: ' '; b: ' '; c: ' '; Data: '311141'; ),
- (a: ' '; b: ' '; c: ' '; Data: '411131'; )
- );
- StartA = '211412';
- StartB = '211214';
- StartC = '211232';
- Stop = '2331112';
- // find Code 128 Codeset A or B
- function Find_Code128AB(c: char): integer;
- var
- i: integer;
- v: char;
- begin
- for i := 0 to High(tabelle_128) do
- begin
- if FTyp = bcCode128A then
- v := tabelle_128[i].a
- else
- v := tabelle_128[i].b;
- if c = v then
- begin
- Result := i;
- exit;
- end;
- end;
- Result := -1;
- end;
- var
- i, idx: integer;
- startcode, tmp: string;
- vChecksum: integer;
- begin
- vChecksum := 0; // Added by TZ
- case FTyp of
- bcCode128A:
- begin
- vChecksum := 103;
- startcode := StartA;
- FCodeText := FText;
- end;
- bcCode128B:
- begin
- vChecksum := 104;
- startcode := StartB;
- FCodeText := FText;
- end;
- bcCode128C:
- begin
- vChecksum := 105;
- startcode := StartC;
- // make sure we have an even numeric only string
- FCodeText := '';
- for i := 1 to Length(FText) do
- if not (FText[i] in ['0'..'9']) then
- FCodeText := FCodeText + '0'
- else
- FCodeText := FCodeText + FText[i];
- if Odd(Length(FText)) then
- FCodeText := '0' + FText;
- end;
- end;
- Result := Convert(startcode); // Startcode
- if FTyp = bcCode128C then
- begin
- tmp := '';
- i := 1;
- while i<Length(FCodeText) do
- begin
- tmp := tmp + chr( StrToIntDef(Copy(FCodeText, i, 2), 0) );
- inc(i,2);
- end;
- end else
- tmp := FCodeText;
- for i := 1 to Length(tmp) do
- begin
- if FTyp = bcCode128C then
- idx := Ord(tmp[i])
- else begin
- idx := Find_Code128AB(tmp[i]);
- if idx < 0 then
- idx := Find_Code128AB(' ');
- end;
- Result := Result + Convert(tabelle_128[idx].Data);
- Inc(vChecksum, idx * i);
- end;
- vChecksum := vChecksum mod 103;
- Result := Result + Convert(tabelle_128[vChecksum].Data);
- Result := Result + Convert(Stop); // Stopcode
- end;
- function TBarcode.Code_93: string;
- type
- TCode93 = record
- c: char;
- Data: array[0..5] of char;
- end;
- const
- tabelle_93: array[0..46] of TCode93 = (
- (c: '0'; Data: '131112'),
- (c: '1'; Data: '111213'),
- (c: '2'; Data: '111312'),
- (c: '3'; Data: '111411'),
- (c: '4'; Data: '121113'),
- (c: '5'; Data: '121212'),
- (c: '6'; Data: '121311'),
- (c: '7'; Data: '111114'),
- (c: '8'; Data: '131211'),
- (c: '9'; Data: '141111'),
- (c: 'A'; Data: '211113'),
- (c: 'B'; Data: '211212'),
- (c: 'C'; Data: '211311'),
- (c: 'D'; Data: '221112'),
- (c: 'E'; Data: '221211'),
- (c: 'F'; Data: '231111'),
- (c: 'G'; Data: '112113'),
- (c: 'H'; Data: '112212'),
- (c: 'I'; Data: '112311'),
- (c: 'J'; Data: '122112'),
- (c: 'K'; Data: '132111'),
- (c: 'L'; Data: '111123'),
- (c: 'M'; Data: '111222'),
- (c: 'N'; Data: '111321'),
- (c: 'O'; Data: '121122'),
- (c: 'P'; Data: '131121'),
- (c: 'Q'; Data: '212112'),
- (c: 'R'; Data: '212211'),
- (c: 'S'; Data: '211122'),
- (c: 'T'; Data: '211221'),
- (c: 'U'; Data: '221121'),
- (c: 'V'; Data: '222111'),
- (c: 'W'; Data: '112122'),
- (c: 'X'; Data: '112221'),
- (c: 'Y'; Data: '122121'),
- (c: 'Z'; Data: '123111'),
- (c: '-'; Data: '121131'),
- (c: '.'; Data: '311112'),
- (c: ' '; Data: '311211'),
- (c: '$'; Data: '321111'),
- (c: '/'; Data: '112131'),
- (c: '+'; Data: '113121'),
- (c: '%'; Data: '211131'),
- (c: '['; Data: '121221'), // only used for Extended Code 93
- (c: ']'; Data: '312111'), // only used for Extended Code 93
- (c: '{'; Data: '311121'), // only used for Extended Code 93
- (c: '}'; Data: '122211') // only used for Extended Code 93
- );
- // find Code 93
- function Find_Code93(c: char): integer;
- var
- i: integer;
- begin
- for i := 0 to High(tabelle_93) do
- begin
- if c = tabelle_93[i].c then
- begin
- Result := i;
- exit;
- end;
- end;
- Result := -1;
- end;
- var
- i, idx: integer;
- checkC, checkK, // Checksums
- weightC, weightK: integer;
- begin
- Result := Convert('111141'); // Startcode
- for i := 1 to Length(FText) do
- begin
- idx := Find_Code93(FText[i]);
- if idx < 0 then
- raise Exception.CreateFmt('%s:Code93 bad Data <%s>', [self.ClassName, FText]);
- Result := Result + Convert(tabelle_93[idx].Data);
- end;
- checkC := 0;
- checkK := 0;
- weightC := 1;
- weightK := 2;
- for i := Length(FText) downto 1 do
- begin
- idx := Find_Code93(FText[i]);
- Inc(checkC, idx * weightC);
- Inc(checkK, idx * weightK);
- Inc(weightC);
- if weightC > 20 then
- weightC := 1;
- Inc(weightK);
- if weightK > 15 then
- weightC := 1;
- end;
- Inc(checkK, checkC);
- checkC := checkC mod 47;
- checkK := checkK mod 47;
- Result := Result + Convert(tabelle_93[checkC].Data) +
- Convert(tabelle_93[checkK].Data);
- Result := Result + Convert('1111411'); // Stopcode
- end;
- function TBarcode.Code_93Extended: string;
- const
- code93x: 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
- // save:array[0..254] of char;
- // old:string;
- save: string;
- i: integer;
- begin
- // CharToOem(PChar(FText), save);
- save := FText;
- FText := '';
- for i := 0 to Length(save) - 1 do
- begin
- if Ord(save[i]) <= 127 then
- FText := FText + code93x[Ord(save[i])];
- end;
- //Showmessage(Format('Text: <%s>', [FText]));
- Result := Code_93;
- FText := save;
- end;
- function TBarcode.Code_MSI: string;
- const
- tabelle_MSI: array['0'..'9'] of string[8] =
- (
- ('51515151'), // '0'
- ('51515160'), // '1'
- ('51516051'), // '2'
- ('51516060'), // '3'
- ('51605151'), // '4'
- ('51605160'), // '5'
- ('51606051'), // '6'
- ('51606060'), // '7'
- ('60515151'), // '8'
- ('60515160') // '9'
- );
- var
- i: integer;
- check_even, check_odd, vChecksum: integer;
- begin
- Result := '60'; // Startcode
- check_even := 0;
- check_odd := 0;
- for i := 1 to Length(FText) do
- begin
- if odd(i - 1) then
- check_odd := check_odd * 10 + Ord(FText[i])
- else
- check_even := check_even + Ord(FText[i]);
- Result := Result + tabelle_MSI[FText[i]];
- end;
- vChecksum := quersumme(check_odd * 2) + check_even;
- vChecksum := vChecksum mod 10;
- if vChecksum > 0 then
- vChecksum := 10 - vChecksum;
- Result := Result + tabelle_MSI[chr(Ord('0') + vChecksum)];
- Result := Result + '515'; // Stopcode
- end;
- function TBarcode.Code_PostNet: string;
- const
- tabelle_PostNet: array['0'..'9'] of string[10] =
- (
- ('5151A1A1A1'), // '0'
- ('A1A1A15151'), // '1'
- ('A1A151A151'), // '2'
- ('A1A15151A1'), // '3'
- ('A151A1A151'), // '4'
- ('A151A151A1'), // '5'
- ('A15151A1A1'), // '6'
- ('51A1A1A151'), // '7'
- ('51A1A151A1'), // '8'
- ('51A151A1A1') // '9'
- );
- var
- i: integer;
- begin
- Result := '51';
- for i := 1 to Length(FText) do
- begin
- Result := Result + tabelle_PostNet[FText[i]];
- end;
- Result := Result + '5';
- end;
- function TBarcode.Code_Codabar: string;
- type
- TCodabar = record
- c: char;
- Data: array[0..6] of char;
- end;
- const
- tabelle_cb: array[0..19] of TCodabar = (
- (c: '1'; Data: '5050615'),
- (c: '2'; Data: '5051506'),
- (c: '3'; Data: '6150505'),
- (c: '4'; Data: '5060515'),
- (c: '5'; Data: '6050515'),
- (c: '6'; Data: '5150506'),
- (c: '7'; Data: '5150605'),
- (c: '8'; Data: '5160505'),
- (c: '9'; Data: '6051505'),
- (c: '0'; Data: '5050516'),
- (c: '-'; Data: '5051605'),
- (c: '$'; Data: '5061505'),
- (c: ':'; Data: '6050606'),
- (c: '/'; Data: '6060506'),
- (c: '.'; Data: '6060605'),
- (c: '+'; Data: '5060606'),
- (c: 'A'; Data: '5061515'),
- (c: 'B'; Data: '5151506'),
- (c: 'C'; Data: '5051516'),
- (c: 'D'; Data: '5051615')
- );
- // find Codabar
- function Find_Codabar(c: char): integer;
- var
- i: integer;
- begin
- for i := 0 to High(tabelle_cb) do
- begin
- if c = tabelle_cb[i].c then
- begin
- Result := i;
- exit;
- end;
- end;
- Result := -1;
- end;
- var
- i, idx: integer;
- begin
- Result := tabelle_cb[Find_Codabar('A')].Data + '0';
- for i := 1 to Length(FText) do
- begin
- idx := Find_Codabar(FText[i]);
- Result := Result + tabelle_cb[idx].Data + '0';
- end;
- Result := Result + tabelle_cb[Find_Codabar('B')].Data;
- end;
- procedure TBarcode.MakeModules;
- begin
- case Typ of
- bcCode_2_5_interleaved,
- bcCode_2_5_industrial,
- bcCode39,
- bcCodeEAN8,
- bcCodeEAN13,
- bcCode39Extended,
- bcCodeCodabar:
- begin
- if Ratio < 2.0 then
- Ratio := 2.0;
- if Ratio > 3.0 then
- Ratio := 3.0;
- end;
- bcCode_2_5_matrix:
- begin
- if Ratio < 2.25 then
- Ratio := 2.25;
- if Ratio > 3.0 then
- Ratio := 3.0;
- end;
- bcCode128A,
- bcCode128B,
- bcCode128C,
- bcCode93,
- bcCode93Extended,
- bcCodeMSI,
- bcCodePostNet: ;
- end;
- modules[0] := FModul;
- modules[1] := Round(FModul * FRatio);
- modules[2] := modules[1] * 3 div 2;
- modules[3] := modules[1] * 2;
- end;
- {
- Draw the Barcode
- Parameter :
- 'data' holds the pattern for a Barcode.
- A barcode begins always with a black line and
- ends with a black line.
- The white Lines builds the space between the black Lines.
- A black line must always followed by a white Line and vica versa.
- Examples:
- '50505' // 3 thin black Lines with 2 thin white Lines
- '606' // 2 fat black Lines with 1 thin white Line
- '5605015' // Error
- data[] : see procedure OneBarProps
- }
- procedure TBarcode.DoLines(Data: string; Canvas: TCanvas);
- var
- i: integer;
- lt: TBarLineType;
- xadd: integer;
- w, h: integer;
- a, b, c, d, // Edges of a line (we need 4 Point because the line
- // is a recangle
- orgin: TPoint;
- alpha: double;
- begin
- xadd := 0;
- orgin.x := FLeft;
- orgin.y := FTop;
- alpha := FAngle * pi / 180.0;
- with Canvas do
- begin
- Pen.Width := 1;
- for i := 1 to Length(Data) do // examine the pattern string
- begin
- OneBarProps(Data[i], w, lt);
- {
- case data[i] of
- '0': begin w := modules[0]; lt := white; end;
- '1': begin w := modules[1]; lt := white; end;
- '2': begin w := modules[2]; lt := white; end;
- '3': begin w := modules[3]; lt := white; end;
- '5': begin w := modules[0]; lt := black; end;
- '6': begin w := modules[1]; lt := black; end;
- '7': begin w := modules[2]; lt := black; end;
- '8': begin w := modules[3]; lt := black; end;
- 'A': begin w := modules[0]; lt := black_half; end;
- 'B': begin w := modules[1]; lt := black_half; end;
- 'C': begin w := modules[2]; lt := black_half; end;
- 'D': begin w := modules[3]; lt := black_half; end;
- else
- begin
- // something went wrong
- // mistyped pattern table
- raise Exception.CreateFmt('%s: internal Error', [self.ClassName]);
- end;
- end;
- }
- if (lt = black) or (lt = black_half) then
- begin
- Pen.Color := clBlack;
- end
- else
- begin
- Pen.Color := clWhite;
- end;
- Brush.Color := Pen.Color;
- if lt = black_half then
- H := FHeight * 2 div 5
- else
- H := FHeight;
- a.x := xadd;
- a.y := 0;
- b.x := xadd;
- b.y := H;
- // c.x := xadd+width;
- c.x := xadd + W - 1; // 23.04.1999 Line was 1 Pixel too wide
- c.y := H;
- // d.x := xadd+width;
- d.x := xadd + W - 1; // 23.04.1999 Line was 1 Pixel too wide
- d.y := 0;
- // a,b,c,d builds the rectangle we want to draw
- // rotate the rectangle
- a := Translate2D(Rotate2D(a, alpha), orgin);
- b := Translate2D(Rotate2D(b, alpha), orgin);
- c := Translate2D(Rotate2D(c, alpha), orgin);
- d := Translate2D(Rotate2D(d, alpha), orgin);
- // draw the rectangle
- Polygon([a, b, c, d]);
- xadd := xadd + w;
- end;
- end;
- end;
- procedure TBarcode.DrawBarcode(Canvas: TCanvas);
- var
- Data: string;
- SaveFont: TFont;
- SavePen: TPen;
- SaveBrush: TBrush;
- begin
- Savefont := TFont.Create;
- SavePen := TPen.Create;
- SaveBrush := TBrush.Create;
- // get barcode pattern
- Data := MakeData;
- try
- // store Canvas properties
- Savefont.Assign(Canvas.Font);
- SavePen.Assign(Canvas.Pen);
- SaveBrush.Assign(Canvas.Brush);
- DoLines(Data, Canvas); // draw the barcode
- if FShowText then
- DrawText(Canvas); // show readable Text
- // restore old Canvas properties
- Canvas.Font.Assign(savefont);
- Canvas.Pen.Assign(SavePen);
- Canvas.Brush.Assign(SaveBrush);
- finally
- Savefont.Free;
- SavePen.Free;
- SaveBrush.Free;
- end;
- end;
- {
- draw contents and type/name of barcode
- as human readable text at the left
- upper edge of the barcode.
- main use for this procedure is testing.
- note: this procedure changes Pen and Brush
- of the current canvas.
- }
- procedure TBarcode.DrawText(Canvas: TCanvas);
- begin
- with Canvas do
- begin
- Font.Size := 4;
- // the fixed font size is a problem, if you
- // use very large or small barcodes
- Pen.Color := clBlack;
- Brush.Color := clWhite;
- TextOut(FLeft, FTop, FText); // contents of Barcode
- TextOut(FLeft, FTop + 14, GetTypText); // type/name of barcode
- end;
- end;
- // this function returns true for those symbols that correct them selves
- // in case invalid data is fed. For example feeding ABCD to 128C numeric
- // only symbol, the generated barcode will be for 0000
- function TBarcode.BarcodeTypeChecked(AType: TBarcodeType): boolean;
- begin
- result := aType in [ bcCode128A, bcCode128B, bcCode128C, bcCodeEAN8,
- bcCodeEAN13 ];
- end;
- function TBarcode.CleanEANValue(const AValue:string; const ASize: Byte): string;
- var
- tmp: string;
- n,i: Integer;
- begin
- tmp := AValue;
- n := Length(tmp);
- // check if there is any strange char in string
- for i:=1 to n do
- if not (tmp[i] in ['0'..'9']) then
- tmp[i] := '0';
- // enforce a ASize char string by adding a 0
- // verifier digit if necesary or calc it if
- // checksum was specified
- if n<ASize then begin
- tmp := stringofchar('0', ASize-n-1) + tmp + '0';
- // TODO: if not FCheckSum was specified
- // resulting barcode might be invalid
- // as a '0' checksum digit was forced.
- end;
- if FCheckSum then
- Result := getEAN(copy(tmp, 1, ASize-1) + '0')
- else
- Result := copy(tmp, 1, ASize);
- end;
- end.