1 unit Barcode;
2
3 {
4 Barcode Component
5 Version 1.5 (23 Apr 1999)
6 Copyright 1998-99 Andreas Schmidt and friends
7
8 Freeware
9
10 for use with Delphi 2/3/4
11
12
13 this component is for private use only !
14 i'am not responsible for wrong barcodes
15
16 bug-reports, enhancements:
17 mailto:shmia@bizerba.de or a_j_schmidt@rocketmail.com
18
19 get latest version from
20 http://members.tripod.de/AJSchmidt/index.html
21
22
23 thanx to Nikolay Simeonov, Wolfgang Koranda, Norbert Waas,
24 Richard Hugues and Olivier Guilbaud.
25
26
27
28 Diese Komponente darf nur in privaten Projekten verwendet werden.
29 Die Weitergabe von ver�nderte Dateien ist nicht zul�ssig.
30 F�r die Korrektheit der erzeugten Barcodes kann keine Garantie
31 �bernommen werden.
32 Anregungen, Bug-Reports, Danksagungen an:
33 mailto:shmia@bizerba.de
34
35
36
37 History:
38 ----------------------------------------------------------------------
39 Version 1.0:
40 - initial release
41 Version 1.1:
42 - more comments
43 - changed function Code_93Extended (now correct ?)
44 Version 1.2:
45 - Bugs (found by Nikolay Simeonov) removed
46 Version 1.3:
47 - EAN8/EAN13 added by Wolfgang Koranda (wkoranda@csi.com)
48 Version 1.4:
49 - Bug (found by Norbert Waas) removed
50 Component must save the Canvas-properties Font,Pen and Brush
51 Version 1.5:
52 - Bug (found by Richard Hugues) removed
53 Last line of barcode was 1 Pixel too wide
54 Version 1.6:
55 - new read-only property 'Width'
56
57
58
59 Todo (missing features)
60 -----------------------
61 - Wrapper Class for Quick Reports
62
63
64
65 }
66
67
68 interface
69
70 {$I lr_vers.inc}
71
72 uses
73 SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
74
75 type
76 TBarcodeType = (bcCode_2_5_interleaved,
77 bcCode_2_5_industrial,
78 bcCode_2_5_matrix,
79 bcCode39,
80 bcCode39Extended,
81 bcCode128A,
82 bcCode128B,
83 bcCode128C,
84 bcCode93,
85 bcCode93Extended,
86 bcCodeMSI,
87 bcCodePostNet,
88 bcCodeCodabar,
89 bcCodeEAN8,
90 bcCodeEAN13
91 );
92
93
94 TBarLineType = (white, black, black_half); // for internal use only
95 // black_half means a black line with 2/5 height (used for PostNet)
96
97
98 { TBarcode }
99
100 TBarcode = class(TComponent)
101 private
102 { Private-Deklarationen }
103 FHeight: integer;
104 FText: string;
105 FTop: integer;
106 FLeft: integer;
107 FModul: integer;
108 FRatio: double;
109 FTyp: TBarcodeType;
110 FCheckSum: boolean;
111 FShowText: boolean;
112 FAngle: double;
113 FCodetext: string;
114
115 modules: array[0..3] of shortint;
116
117
118 procedure OneBarProps(code: char; out aWidth: integer; out lt: TBarLineType);
119
120 procedure DoLines(Data: string; Canvas: TCanvas);
121
Code_2_5_interleavednull122 function Code_2_5_interleaved: string;
Code_2_5_industrialnull123 function Code_2_5_industrial: string;
Code_2_5_matrixnull124 function Code_2_5_matrix: string;
Code_39null125 function Code_39: string;
Code_39Extendednull126 function Code_39Extended: string;
Code_128null127 function Code_128: string;
Code_93null128 function Code_93: string;
Code_93Extendednull129 function Code_93Extended: string;
Code_MSInull130 function Code_MSI: string;
Code_PostNetnull131 function Code_PostNet: string;
Code_Codabarnull132 function Code_Codabar: string;
Code_EAN8null133 function Code_EAN8: string;
Code_EAN13null134 function Code_EAN13: string;
135
GetTypTextnull136 function GetTypText: string;
137 procedure MakeModules;
138
139 procedure SetModul(v: integer);
140
GetWidthnull141 function GetWidth: integer;
142 procedure SetText(AValue: string);
CleanEANValuenull143 function CleanEANValue(const AValue: string; const ASize:Byte): string;
144
145 protected
146 { Protected-Deklarationen }
MakeDatanull147 function MakeData: string;
148
149 public
150 { Public-Deklarationen }
151 constructor Create(aOwner: TComponent); override;
152 procedure DrawBarcode(Canvas: TCanvas);
153 procedure DrawText(Canvas: TCanvas);
BarcodeTypeCheckednull154 function BarcodeTypeChecked(AType: TBarcodeType): boolean;
155
156 property CodeText: string read FCodetext write FCodeText;
157 published
158 { Published-Deklarationen }
159 // Height of Barcode (Pixel)
160 property Height: integer read FHeight write FHeight;
161 property Text: string read FText write SetText;
162 property Top: integer read FTop write FTop;
163 property Left: integer read FLeft write FLeft;
164 // Width of the smallest line in a Barcode
165 property Modul: integer read FModul write SetModul;
166 property Ratio: double read FRatio write FRatio;
167 property Typ: TBarcodeType read FTyp write FTyp default bcCode_2_5_interleaved;
168 // build CheckSum ?
169 property Checksum: boolean read FCheckSum write FCheckSum default False;
170 // 0 - 360 degree
171 property Angle: double read FAngle write FAngle;
172
173 property ShowText: boolean read FShowText write FShowText default False;
174 property Width: integer read GetWidth;
175 end;
176
177 // procedure Register; // Removed by TZ
178
179 implementation
180
181
182 {
183 converts a string from '321' to the internal representation '715'
184 i need this function because some pattern tables have a different
185 format :
186
187 '00111'
188 converts to '05161'
189 }
Convertnull190 function Convert(s: string): string;
191 var
192 i, v: integer;
193 t: string;
194 begin
195 t := '';
196 for i := 1 to Length(s) do
197 begin
198 v := Ord(s[i]) - 1;
199
200 if odd(i) then
201 Inc(v, 5);
202 t := t + Chr(v);
203 end;
204 Convert := t;
205 end;
206
207 (*
208 * Berechne die Quersumme aus einer Zahl x
209 * z.B.: Quersumme von 1234 ist 10
210 *)
quersummenull211 function quersumme(x: integer): integer;
212 var
213 sum: integer;
214 begin
215 sum := 0;
216
217 while x > 0 do
218 begin
219 sum := sum + (x mod 10);
220 x := x div 10;
221 end;
222 Result := sum;
223 end;
224
225
226 {
227 Rotate a Point by Angle 'alpha'
228 }
Rotate2Dnull229 function Rotate2D(p: TPoint; alpha: double): TPoint;
230 var
231 sinus, cosinus: extended;
232 begin
233 sinus := sin(alpha);
234 cosinus := cos(alpha);
235 Result.x := Round(p.x * cosinus + p.y * sinus);
236 Result.y := Round(-p.x * sinus + p.y * cosinus);
237 end;
238
239 {
240 Move Point a by Vector b
241 }
Translate2Dnull242 function Translate2D(a, b: TPoint): TPoint;
243 begin
244 Result.x := a.x + b.x;
245 Result.y := a.y + b.y;
246 end;
247
248 constructor TBarcode.Create(aOwner: TComponent);
249 begin
250 inherited Create(aOwner);
251
252 FAngle := 0.0;
253 FRatio := 2.0;
254 FModul := 1;
255 FTyp := bcCodeEAN13;
256 FCheckSum := False;
257 FShowText := False;
258 end;
259
TBarcode.GetTypTextnull260 function TBarcode.GetTypText: string;
261 const
262 bcNames: array[bcCode_2_5_interleaved..bcCodeEAN13] of string =
263 (
264 ('2_5_interleaved'),
265 ('2_5_industrial'),
266 ('2_5_matrix'),
267 ('Code39'),
268 ('Code39 Extended'),
269 ('Code128A'),
270 ('Code128B'),
271 ('Code128C'),
272 ('Code93'),
273 ('Code93 Extended'),
274 ('MSI'),
275 ('PostNet'),
276 ('Codebar'),
277 ('EAN8'),
278 ('EAN13')
279 );
280 begin
281 Result := bcNames[FTyp];
282 end;
283
284 // set Modul Width
285 procedure TBarcode.SetModul(v: integer);
286 begin
287 if (v >= 1) and (v < 50) then
288 FModul := v;
289 end;
290
291 {
292 calculate the width and the linetype of a sigle bar
293
294
295 Code Line-Color Width Height
296 ------------------------------------------------------------------
297 '0' white 100% full
298 '1' white 100%*Ratio full
299 '2' white 150%*Ratio full
300 '3' white 200%*Ratio full
301 '5' black 100% full
302 '6' black 100%*Ratio full
303 '7' black 150%*Ratio full
304 '8' black 200%*Ratio full
305 'A' black 100% 2/5 (used for PostNet)
306 'B' black 100%*Ratio 2/5 (used for PostNet)
307 'C' black 150%*Ratio 2/5 (used for PostNet)
308 'D' black 200%*Ratio 2/5 (used for PostNet)
309 }
310 procedure TBarcode.OneBarProps(code: char; out aWidth: integer; out lt: TBarLineType);
311 begin
312 case code of
313 '0':
314 begin
315 aWidth := modules[0];
316 lt := white;
317 end;
318 '1':
319 begin
320 aWidth := modules[1];
321 lt := white;
322 end;
323 '2':
324 begin
325 aWidth := modules[2];
326 lt := white;
327 end;
328 '3':
329 begin
330 aWidth := modules[3];
331 lt := white;
332 end;
333
334
335 '5':
336 begin
337 aWidth := modules[0];
338 lt := black;
339 end;
340 '6':
341 begin
342 aWidth := modules[1];
343 lt := black;
344 end;
345 '7':
346 begin
347 aWidth := modules[2];
348 lt := black;
349 end;
350 '8':
351 begin
352 aWidth := modules[3];
353 lt := black;
354 end;
355
356 'A':
357 begin
358 aWidth := modules[0];
359 lt := black_half;
360 end;
361 'B':
362 begin
363 aWidth := modules[1];
364 lt := black_half;
365 end;
366 'C':
367 begin
368 aWidth := modules[2];
369 lt := black_half;
370 end;
371 'D':
372 begin
373 aWidth := modules[3];
374 lt := black_half;
375 end;
376 else
377 begin
378 // something went wrong :-(
379 // mistyped pattern table
380 raise Exception.CreateFmt('%s: internal Error', [self.ClassName]);
381 end;
382 end;
383 end;
384
385
TBarcode.MakeDatanull386 function TBarcode.MakeData: string;
387 begin
388 // calculate the with of the different lines (modules)
389 MakeModules;
390
391 // get the pattern of the barcode
392 case Typ of
393 bcCode_2_5_interleaved:
394 Result := Code_2_5_interleaved;
395 bcCode_2_5_industrial:
396 Result := Code_2_5_industrial;
397 bcCode_2_5_matrix:
398 Result := Code_2_5_matrix;
399 bcCode39:
400 Result := Code_39;
401 bcCode39Extended:
402 Result := Code_39Extended;
403 bcCode128A,
404 bcCode128B,
405 bcCode128C:
406 Result := Code_128;
407 bcCode93:
408 Result := Code_93;
409 bcCode93Extended:
410 Result := Code_93Extended;
411 bcCodeMSI:
412 Result := Code_MSI;
413 bcCodePostNet:
414 Result := Code_PostNet;
415 bcCodeCodabar:
416 Result := Code_Codabar;
417 bcCodeEAN8:
418 Result := Code_EAN8;
419 bcCodeEAN13:
420 Result := Code_EAN13;
421 else
422 raise Exception.CreateFmt('%s: wrong BarcodeType', [self.ClassName]);
423 end;
424
425 //Showmessage(Format('Data <%s>', [Result]));
426 end;
427
428
TBarcode.GetWidthnull429 function TBarcode.GetWidth: integer;
430 var
431 Data: string;
432 i: integer;
433 w: integer;
434 lt: TBarLineType;
435 begin
436 Result := 0;
437
438 // get barcode pattern
439 Data := MakeData;
440
441 for i := 1 to Length(Data) do // examine the pattern string
442 begin
443 OneBarProps(Data[i], w, lt);
444 Inc(Result, w);
445 end;
446 end;
447
448 procedure TBarcode.SetText(AValue: string);
449 begin
450 if FText=AValue then Exit;
451 FText:=AValue;
452 FCodeText:=AValue;
453 end;
454
455
456 ////////////////////////////// EAN /////////////////////////////////////////
457
getEANnull458 function getEAN(Nr: string): string;
459 var
460 i, fak, sum: integer;
461 tmp: string;
462 begin
463 sum := 0;
464 tmp := copy(nr, 1, Length(Nr) - 1);
465 fak := Length(tmp);
466 for i := 1 to length(tmp) do
467 begin
468 if (fak mod 2) = 0 then
469 sum := sum + (StrToInt(tmp[i]) * 1)
470 else
471 sum := sum + (StrToInt(tmp[i]) * 3);
472 Dec(fak);
473 end;
474 if (sum mod 10) = 0 then
475 Result := tmp + '0'
476 else
477 Result := tmp + IntToStr(10 - (sum mod 10));
478 end;
479
480 ////////////////////////////// EAN8 /////////////////////////////////////////
481
482 // Pattern for Barcode EAN Zeichensatz A
483 // L1 S1 L2 S2
484 const
485 tabelle_EAN_A: array['0'..'9', 1..4] of char =
486 (
487 ('2', '6', '0', '5'), // 0
488 ('1', '6', '1', '5'), // 1
489 ('1', '5', '1', '6'), // 2
490 ('0', '8', '0', '5'), // 3
491 ('0', '5', '2', '6'), // 4
492 ('0', '6', '2', '5'), // 5
493 ('0', '5', '0', '8'), // 6
494 ('0', '7', '0', '6'), // 7
495 ('0', '6', '0', '7'), // 8
496 ('2', '5', '0', '6') // 9
497 );
498
499 // Pattern for Barcode EAN Zeichensatz C
500 // S1 L1 S2 L2
501 const
502 tabelle_EAN_C: array['0'..'9', 1..4] of char =
503 (
504 ('7', '1', '5', '0'), // 0
505 ('6', '1', '6', '0'), // 1
506 ('6', '0', '6', '1'), // 2
507 ('5', '3', '5', '0'), // 3
508 ('5', '0', '7', '1'), // 4
509 ('5', '1', '7', '0'), // 5
510 ('5', '0', '5', '3'), // 6
511 ('5', '2', '5', '1'), // 7
512 ('5', '1', '5', '2'), // 8
513 ('7', '0', '5', '1') // 9
514 );
515
516
Code_EAN8null517 function TBarcode.Code_EAN8: string;
518 var
519 i, j: integer;
520 begin
521
522 FCodeText := CleanEANValue(FText, 8);
523
524 Result := '505'; // Startcode
525
526 for i := 1 to 4 do
527 for j := 1 to 4 do
528 begin
529 Result := Result + tabelle_EAN_A[FCodeText[i], j];
530 end;
531
532 Result := Result + '05050'; // Trennzeichen
533
534 for i := 5 to 8 do
535 for j := 1 to 4 do
536 begin
537 Result := Result + tabelle_EAN_C[FCodeText[i], j];
538 end;
539
540 Result := Result + '505'; // Stopcode
541 end;
542
543 ////////////////////////////// EAN13 ///////////////////////////////////////
544
545 // Pattern for Barcode EAN Zeichensatz B
546 // L1 S1 L2 S2
547 const
548 tabelle_EAN_B: array['0'..'9', 1..4] of char =
549 (
550 ('0', '5', '1', '7'), // 0
551 ('0', '6', '1', '6'), // 1
552 ('1', '6', '0', '6'), // 2
553 ('0', '5', '3', '5'), // 3
554 ('1', '7', '0', '5'), // 4
555 ('0', '7', '1', '5'), // 5
556 ('3', '5', '0', '5'), // 6
557 ('1', '5', '2', '5'), // 7
558 ('2', '5', '1', '5'), // 8
559 ('1', '5', '0', '7') // 9
560 );
561
562 // Zuordung der Paraitaetsfolgen f�r EAN13
563 const
564 tabelle_ParityEAN13: array[0..9, 1..6] of char =
565 (
566 ('A', 'A', 'A', 'A', 'A', 'A'), // 0
567 ('A', 'A', 'B', 'A', 'B', 'B'), // 1
568 ('A', 'A', 'B', 'B', 'A', 'B'), // 2
569 ('A', 'A', 'B', 'B', 'B', 'A'), // 3
570 ('A', 'B', 'A', 'A', 'B', 'B'), // 4
571 ('A', 'B', 'B', 'A', 'A', 'B'), // 5
572 ('A', 'B', 'B', 'B', 'A', 'A'), // 6
573 ('A', 'B', 'A', 'B', 'A', 'B'), // 7
574 ('A', 'B', 'A', 'B', 'B', 'A'), // 8
575 ('A', 'B', 'B', 'A', 'B', 'A') // 9
576 );
577
Code_EAN13null578 function TBarcode.Code_EAN13: string;
579 var
580 i, j, LK: integer;
581 tmp: string;
582 begin
583
584 FCodeText := CleanEanValue(FText, 13);
585
586 LK := StrToInt(FCodeText[1]);
587 tmp := copy(FCodeText, 2, 12);
588
589 Result := '505'; // Startcode
590
591 for i := 1 to 6 do
592 begin
593 case tabelle_ParityEAN13[LK, i] of
594 'A':
595 for j := 1 to 4 do
596 Result := Result + tabelle_EAN_A[tmp[i], j];
597 'B':
598 for j := 1 to 4 do
599 Result := Result + tabelle_EAN_B[tmp[i], j];
600 'C':
601 for j := 1 to 4 do
602 Result := Result + tabelle_EAN_C[tmp[i], j];
603 end;
604 end;
605
606 Result := Result + '05050'; // Trennzeichen
607
608 for i := 7 to 12 do
609 for j := 1 to 4 do
610 begin
611 Result := Result + tabelle_EAN_C[tmp[i], j];
612 end;
613
614 Result := Result + '505'; // Stopcode
615 end;
616
617 // Pattern for Barcode 2 of 5
618 const
619 tabelle_2_5: array['0'..'9', 1..5] of char =
620 (
621 ('0', '0', '1', '1', '0'), // 0
622 ('1', '0', '0', '0', '1'), // 1
623 ('0', '1', '0', '0', '1'), // 2
624 ('1', '1', '0', '0', '0'), // 3
625 ('0', '0', '1', '0', '1'), // 4
626 ('1', '0', '1', '0', '0'), // 5
627 ('0', '1', '1', '0', '0'), // 6
628 ('0', '0', '0', '1', '1'), // 7
629 ('1', '0', '0', '1', '0'), // 8
630 ('0', '1', '0', '1', '0') // 9
631 );
632
Code_2_5_interleavednull633 function TBarcode.Code_2_5_interleaved: string;
634 var
635 i, j: integer;
636 c: char;
637
638 begin
639 Result := '5050'; // Startcode
640
641 for i := 1 to Length(FText) div 2 do
642 begin
643 for j := 1 to 5 do
644 begin
645 if tabelle_2_5[FText[i * 2 - 1], j] = '1' then
646 c := '6'
647 else
648 c := '5';
649 Result := Result + c;
650 if tabelle_2_5[FText[i * 2], j] = '1' then
651 c := '1'
652 else
653 c := '0';
654 Result := Result + c;
655 end;
656 end;
657
658 Result := Result + '605'; // Stopcode
659 end;
660
661
TBarcode.Code_2_5_industrialnull662 function TBarcode.Code_2_5_industrial: string;
663 var
664 i, j: integer;
665 begin
666 Result := '606050'; // Startcode
667
668 for i := 1 to Length(FText) do
669 begin
670 for j := 1 to 5 do
671 begin
672 if tabelle_2_5[FText[i], j] = '1' then
673 Result := Result + '60'
674 else
675 Result := Result + '50';
676 end;
677 end;
678
679 Result := Result + '605060'; // Stopcode
680 end;
681
Code_2_5_matrixnull682 function TBarcode.Code_2_5_matrix: string;
683 var
684 i, j: integer;
685 c: char;
686 begin
687 Result := '705050'; // Startcode
688
689 for i := 1 to Length(FText) do
690 begin
691 for j := 1 to 5 do
692 begin
693 if tabelle_2_5[FText[i], j] = '1' then
694 c := '1'
695 else
696 c := '0';
697
698 // Falls i ungerade ist dann mache L�cke zu Strich
699 if odd(j) then
700 c := chr(Ord(c) + 5);
701 Result := Result + c;
702 end;
703 Result := Result + '0'; // L�cke zwischen den Zeichen
704 end;
705
706 Result := Result + '70505'; // Stopcode
707 end;
708
709
Code_39null710 function TBarcode.Code_39: string;
711
712 type
713 TCode39 = record
714 c: char;
715 Data: array[0..9] of char;
716 chk: shortint;
717 end;
718
719 const
720 tabelle_39: array[0..43] of TCode39 = (
721 (c: '0'; Data: '505160605'; chk: 0),
722 (c: '1'; Data: '605150506'; chk: 1),
723 (c: '2'; Data: '506150506'; chk: 2),
724 (c: '3'; Data: '606150505'; chk: 3),
725 (c: '4'; Data: '505160506'; chk: 4),
726 (c: '5'; Data: '605160505'; chk: 5),
727 (c: '6'; Data: '506160505'; chk: 6),
728 (c: '7'; Data: '505150606'; chk: 7),
729 (c: '8'; Data: '605150605'; chk: 8),
730 (c: '9'; Data: '506150605'; chk: 9),
731 (c: 'A'; Data: '605051506'; chk: 10),
732 (c: 'B'; Data: '506051506'; chk: 11),
733 (c: 'C'; Data: '606051505'; chk: 12),
734 (c: 'D'; Data: '505061506'; chk: 13),
735 (c: 'E'; Data: '605061505'; chk: 14),
736 (c: 'F'; Data: '506061505'; chk: 15),
737 (c: 'G'; Data: '505051606'; chk: 16),
738 (c: 'H'; Data: '605051605'; chk: 17),
739 (c: 'I'; Data: '506051600'; chk: 18),
740 (c: 'J'; Data: '505061605'; chk: 19),
741 (c: 'K'; Data: '605050516'; chk: 20),
742 (c: 'L'; Data: '506050516'; chk: 21),
743 (c: 'M'; Data: '606050515'; chk: 22),
744 (c: 'N'; Data: '505060516'; chk: 23),
745 (c: 'O'; Data: '605060515'; chk: 24),
746 (c: 'P'; Data: '506060515'; chk: 25),
747 (c: 'Q'; Data: '505050616'; chk: 26),
748 (c: 'R'; Data: '605050615'; chk: 27),
749 (c: 'S'; Data: '506050615'; chk: 28),
750 (c: 'T'; Data: '505060615'; chk: 29),
751 (c: 'U'; Data: '615050506'; chk: 30),
752 (c: 'V'; Data: '516050506'; chk: 31),
753 (c: 'W'; Data: '616050505'; chk: 32),
754 (c: 'X'; Data: '515060506'; chk: 33),
755 (c: 'Y'; Data: '615060505'; chk: 34),
756 (c: 'Z'; Data: '516060505'; chk: 35),
757 (c: '-'; Data: '515050606'; chk: 36),
758 (c: '.'; Data: '615050605'; chk: 37),
759 (c: ' '; Data: '516050605'; chk: 38),
760 (c: '*'; Data: '515060605'; chk: 0),
761 (c: '$'; Data: '515151505'; chk: 39),
762 (c: '/'; Data: '515150515'; chk: 40),
763 (c: '+'; Data: '515051515'; chk: 41),
764 (c: '%'; Data: '505151515'; chk: 42)
765 );
766
767
FindIdxnull768 function FindIdx(z: char): integer;
769 var
770 i: integer;
771 begin
772 Result := -1;
773 for i := 0 to High(tabelle_39) do
774 begin
775 if z = tabelle_39[i].c then
776 begin
777 Result := i;
778 Break;
779 end;
780 end;
781 end;
782
783 var
784 i, idx: integer;
785 vChecksum: integer;
786
787 begin
788 vChecksum := 0;
789 // Startcode
790 Result := tabelle_39[FindIdx('*')].Data + '0';
791
792 for i := 1 to Length(FText) do
793 begin
794 idx := FindIdx(FText[i]);
795 if idx < 0 then
796 continue;
797 Result := Result + tabelle_39[idx].Data + '0';
798 Inc(vChecksum, tabelle_39[idx].chk);
799 end;
800
801 // Calculate Checksum Data
802 if FCheckSum then
803 begin
804 vChecksum := vChecksum mod 43;
805 for i := 0 to High(tabelle_39) do
806 if vChecksum = tabelle_39[i].chk then
807 begin
808 Result := Result + tabelle_39[i].Data + '0';
809 exit;
810 end;
811 end;
812
813 // Stopcode
814 Result := Result + tabelle_39[FindIdx('*')].Data;
815 end;
816
TBarcode.Code_39Extendednull817 function TBarcode.Code_39Extended: string;
818
819 const
820 code39x: array[0..127] of string[2] =
821 (
822 ('%U'), ('$A'), ('$B'), ('$C'), ('$D'), ('$E'), ('$F'), ('$G'),
823 ('$H'), ('$I'), ('$J'), ('$K'), ('$L'), ('$M'), ('$N'), ('$O'),
824 ('$P'), ('$Q'), ('$R'), ('$S'), ('$T'), ('$U'), ('$V'), ('$W'),
825 ('$X'), ('$Y'), ('$Z'), ('%A'), ('%B'), ('%C'), ('%D'), ('%E'),
826 (' '), ('/A'), ('/B'), ('/C'), ('/D'), ('/E'), ('/F'), ('/G'),
827 ('/H'), ('/I'), ('/J'), ('/K'), ('/L'), ('/M'), ('/N'), ('/O'),
828 ('0'), ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'),
829 ('8'), ('9'), ('/Z'), ('%F'), ('%G'), ('%H'), ('%I'), ('%J'),
830 ('%V'), ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'),
831 ('H'), ('I'), ('J'), ('K'), ('L'), ('M'), ('N'), ('O'),
832 ('P'), ('Q'), ('R'), ('S'), ('T'), ('U'), ('V'), ('W'),
833 ('X'), ('Y'), ('Z'), ('%K'), ('%L'), ('%M'), ('%N'), ('%O'),
834 ('%W'), ('+A'), ('+B'), ('+C'), ('+D'), ('+E'), ('+F'), ('+G'),
835 ('+H'), ('+I'), ('+J'), ('+K'), ('+L'), ('+M'), ('+N'), ('+O'),
836 ('+P'), ('+Q'), ('+R'), ('+S'), ('+T'), ('+U'), ('+V'), ('+W'),
837 ('+X'), ('+Y'), ('+Z'), ('%P'), ('%Q'), ('%R'), ('%S'), ('%T')
838 );
839
840 var
841 save: string;
842 i: integer;
843 begin
844 save := FText;
845 FText := '';
846
847 for i := 1 to Length(save) do
848 begin
849 if Ord(save[i]) <= 127 then
850 FText := FText + code39x[Ord(save[i])];
851 end;
852 Result := Code_39;
853 FText := save;
854 end;
855
856
857 {
858 Code 128
859 }
Code_128null860 function TBarcode.Code_128: string;
861 type
862 TCode128 = record
863 a, b: char;
864 c: string[2];
865 Data: string[6];
866 end;
867
868 const
869 tabelle_128: array[0..102] of TCode128 = (
870 (a: ' '; b: ' '; c: '00'; Data: '212222'; ),
871 (a: '!'; b: '!'; c: '01'; Data: '222122'; ),
872 (a: '"'; b: '"'; c: '02'; Data: '222221'; ),
873 (a: '#'; b: '#'; c: '03'; Data: '121223'; ),
874 (a: '$'; b: '$'; c: '04'; Data: '121322'; ),
875 (a: '%'; b: '%'; c: '05'; Data: '131222'; ),
876 (a: '&'; b: '&'; c: '06'; Data: '122213'; ),
877 (a: ''''; b: ''''; c: '07'; Data: '122312'; ),
878 (a: '('; b: '('; c: '08'; Data: '132212'; ),
879 (a: ')'; b: ')'; c: '09'; Data: '221213'; ),
880 (a: '*'; b: '*'; c: '10'; Data: '221312'; ),
881 (a: '+'; b: '+'; c: '11'; Data: '231212'; ),
882 (a: ','; b: ','; c: '12'; Data: '112232'; ),
883 (a: '-'; b: '-'; c: '13'; Data: '122132'; ),
884 (a: '.'; b: '.'; c: '14'; Data: '122231'; ),
885 (a: '/'; b: '/'; c: '15'; Data: '113222'; ),
886 (a: '0'; b: '0'; c: '16'; Data: '123122'; ),
887 (a: '1'; b: '1'; c: '17'; Data: '123221'; ),
888 (a: '2'; b: '2'; c: '18'; Data: '223211'; ),
889 (a: '3'; b: '3'; c: '19'; Data: '221132'; ),
890 (a: '4'; b: '4'; c: '20'; Data: '221231'; ),
891 (a: '5'; b: '5'; c: '21'; Data: '213212'; ),
892 (a: '6'; b: '6'; c: '22'; Data: '223112'; ),
893 (a: '7'; b: '7'; c: '23'; Data: '312131'; ),
894 (a: '8'; b: '8'; c: '24'; Data: '311222'; ),
895 (a: '9'; b: '9'; c: '25'; Data: '321122'; ),
896 (a: ':'; b: ':'; c: '26'; Data: '321221'; ),
897 (a: ';'; b: ';'; c: '27'; Data: '312212'; ),
898 (a: '<'; b: '<'; c: '28'; Data: '322112'; ),
899 (a: '='; b: '='; c: '29'; Data: '322211'; ),
900 (a: '>'; b: '>'; c: '30'; Data: '212123'; ),
901 (a: '?'; b: '?'; c: '31'; Data: '212321'; ),
902 (a: '@'; b: '@'; c: '32'; Data: '232121'; ),
903 (a: 'A'; b: 'A'; c: '33'; Data: '111323'; ),
904 (a: 'B'; b: 'B'; c: '34'; Data: '131123'; ),
905 (a: 'C'; b: 'C'; c: '35'; Data: '131321'; ),
906 (a: 'D'; b: 'D'; c: '36'; Data: '112313'; ),
907 (a: 'E'; b: 'E'; c: '37'; Data: '132113'; ),
908 (a: 'F'; b: 'F'; c: '38'; Data: '132311'; ),
909 (a: 'G'; b: 'G'; c: '39'; Data: '211313'; ),
910 (a: 'H'; b: 'H'; c: '40'; Data: '231113'; ),
911 (a: 'I'; b: 'I'; c: '41'; Data: '231311'; ),
912 (a: 'J'; b: 'J'; c: '42'; Data: '112133'; ),
913 (a: 'K'; b: 'K'; c: '43'; Data: '112331'; ),
914 (a: 'L'; b: 'L'; c: '44'; Data: '132131'; ),
915 (a: 'M'; b: 'M'; c: '45'; Data: '113123'; ),
916 (a: 'N'; b: 'N'; c: '46'; Data: '113321'; ),
917 (a: 'O'; b: 'O'; c: '47'; Data: '133121'; ),
918 (a: 'P'; b: 'P'; c: '48'; Data: '313121'; ),
919 (a: 'Q'; b: 'Q'; c: '49'; Data: '211331'; ),
920 (a: 'R'; b: 'R'; c: '50'; Data: '231131'; ),
921 (a: 'S'; b: 'S'; c: '51'; Data: '213113'; ),
922 (a: 'T'; b: 'T'; c: '52'; Data: '213311'; ),
923 (a: 'U'; b: 'U'; c: '53'; Data: '213131'; ),
924 (a: 'V'; b: 'V'; c: '54'; Data: '311123'; ),
925 (a: 'W'; b: 'W'; c: '55'; Data: '311321'; ),
926 (a: 'X'; b: 'X'; c: '56'; Data: '331121'; ),
927 (a: 'Y'; b: 'Y'; c: '57'; Data: '312113'; ),
928 (a: 'Z'; b: 'Z'; c: '58'; Data: '312311'; ),
929 (a: '['; b: '['; c: '59'; Data: '332111'; ),
930 (a: '\'; b: '\'; c: '60'; Data: '314111'; ),
931 (a: ']'; b: ']'; c: '61'; Data: '221411'; ),
932 (a: '^'; b: '^'; c: '62'; Data: '431111'; ),
933 (a: '_'; b: '_'; c: '63'; Data: '111224'; ),
934 (a: ' '; b: '`'; c: '64'; Data: '111422'; ),
935 (a: ' '; b: 'a'; c: '65'; Data: '121124'; ),
936 (a: ' '; b: 'b'; c: '66'; Data: '121421'; ),
937 (a: ' '; b: 'c'; c: '67'; Data: '141122'; ),
938 (a: ' '; b: 'd'; c: '68'; Data: '141221'; ),
939 (a: ' '; b: 'e'; c: '69'; Data: '112214'; ),
940 (a: ' '; b: 'f'; c: '70'; Data: '112412'; ),
941 (a: ' '; b: 'g'; c: '71'; Data: '122114'; ),
942 (a: ' '; b: 'h'; c: '72'; Data: '122411'; ),
943 (a: ' '; b: 'i'; c: '73'; Data: '142112'; ),
944 (a: ' '; b: 'j'; c: '74'; Data: '142211'; ),
945 (a: ' '; b: 'k'; c: '75'; Data: '241211'; ),
946 (a: ' '; b: 'l'; c: '76'; Data: '221114'; ),
947 (a: ' '; b: 'm'; c: '77'; Data: '413111'; ),
948 (a: ' '; b: 'n'; c: '78'; Data: '241112'; ),
949 (a: ' '; b: 'o'; c: '79'; Data: '134111'; ),
950 (a: ' '; b: 'p'; c: '80'; Data: '111242'; ),
951 (a: ' '; b: 'q'; c: '81'; Data: '121142'; ),
952 (a: ' '; b: 'r'; c: '82'; Data: '121241'; ),
953 (a: ' '; b: 's'; c: '83'; Data: '114212'; ),
954 (a: ' '; b: 't'; c: '84'; Data: '124112'; ),
955 (a: ' '; b: 'u'; c: '85'; Data: '124211'; ),
956 (a: ' '; b: 'v'; c: '86'; Data: '411212'; ),
957 (a: ' '; b: 'w'; c: '87'; Data: '421112'; ),
958 (a: ' '; b: 'x'; c: '88'; Data: '421211'; ),
959 (a: ' '; b: 'y'; c: '89'; Data: '212141'; ),
960 (a: ' '; b: 'z'; c: '90'; Data: '214121'; ),
961 (a: ' '; b: '{'; c: '91'; Data: '412121'; ),
962 (a: ' '; b: '|'; c: '92'; Data: '111143'; ),
963 (a: ' '; b: '}'; c: '93'; Data: '111341'; ),
964 (a: ' '; b: '~'; c: '94'; Data: '131141'; ),
965 (a: ' '; b: ' '; c: '95'; Data: '114113'; ),
966 (a: ' '; b: ' '; c: '96'; Data: '114311'; ),
967 (a: ' '; b: ' '; c: '97'; Data: '411113'; ),
968 (a: ' '; b: ' '; c: '98'; Data: '411311'; ),
969 (a: ' '; b: ' '; c: '99'; Data: '113141'; ),
970 (a: ' '; b: ' '; c: ' '; Data: '114131'; ),
971 (a: ' '; b: ' '; c: ' '; Data: '311141'; ),
972 (a: ' '; b: ' '; c: ' '; Data: '411131'; )
973 );
974
975 StartA = '211412';
976 StartB = '211214';
977 StartC = '211232';
978 Stop = '2331112';
979
980
981 // find Code 128 Codeset A or B
Find_Code128ABnull982 function Find_Code128AB(c: char): integer;
983 var
984 i: integer;
985 v: char;
986 begin
987 for i := 0 to High(tabelle_128) do
988 begin
989 if FTyp = bcCode128A then
990 v := tabelle_128[i].a
991 else
992 v := tabelle_128[i].b;
993
994 if c = v then
995 begin
996 Result := i;
997 exit;
998 end;
999 end;
1000 Result := -1;
1001 end;
1002
1003 var
1004 i, idx: integer;
1005 startcode, tmp: string;
1006 vChecksum: integer;
1007
1008 begin
1009
1010 vChecksum := 0; // Added by TZ
1011 case FTyp of
1012 bcCode128A:
1013 begin
1014 vChecksum := 103;
1015 startcode := StartA;
1016 FCodeText := FText;
1017 end;
1018 bcCode128B:
1019 begin
1020 vChecksum := 104;
1021 startcode := StartB;
1022 FCodeText := FText;
1023 end;
1024 bcCode128C:
1025 begin
1026 vChecksum := 105;
1027 startcode := StartC;
1028
1029 // make sure we have an even numeric only string
1030 FCodeText := '';
1031 for i := 1 to Length(FText) do
1032 if not (FText[i] in ['0'..'9']) then
1033 FCodeText := FCodeText + '0'
1034 else
1035 FCodeText := FCodeText + FText[i];
1036
1037 if Odd(Length(FText)) then
1038 FCodeText := '0' + FText;
1039 end;
1040 end;
1041
1042 Result := Convert(startcode); // Startcode
1043
1044 if FTyp = bcCode128C then
1045 begin
1046 tmp := '';
1047 i := 1;
1048 while i<Length(FCodeText) do
1049 begin
1050 tmp := tmp + chr( StrToIntDef(Copy(FCodeText, i, 2), 0) );
1051 inc(i,2);
1052 end;
1053 end else
1054 tmp := FCodeText;
1055
1056 for i := 1 to Length(tmp) do
1057 begin
1058 if FTyp = bcCode128C then
1059 idx := Ord(tmp[i])
1060 else begin
1061 idx := Find_Code128AB(tmp[i]);
1062 if idx < 0 then
1063 idx := Find_Code128AB(' ');
1064 end;
1065 Result := Result + Convert(tabelle_128[idx].Data);
1066 Inc(vChecksum, idx * i);
1067 end;
1068
1069 vChecksum := vChecksum mod 103;
1070 Result := Result + Convert(tabelle_128[vChecksum].Data);
1071
1072 Result := Result + Convert(Stop); // Stopcode
1073 end;
1074
1075
TBarcode.Code_93null1076 function TBarcode.Code_93: string;
1077 type
1078 TCode93 = record
1079 c: char;
1080 Data: array[0..5] of char;
1081 end;
1082
1083 const
1084 tabelle_93: array[0..46] of TCode93 = (
1085 (c: '0'; Data: '131112'),
1086 (c: '1'; Data: '111213'),
1087 (c: '2'; Data: '111312'),
1088 (c: '3'; Data: '111411'),
1089 (c: '4'; Data: '121113'),
1090 (c: '5'; Data: '121212'),
1091 (c: '6'; Data: '121311'),
1092 (c: '7'; Data: '111114'),
1093 (c: '8'; Data: '131211'),
1094 (c: '9'; Data: '141111'),
1095 (c: 'A'; Data: '211113'),
1096 (c: 'B'; Data: '211212'),
1097 (c: 'C'; Data: '211311'),
1098 (c: 'D'; Data: '221112'),
1099 (c: 'E'; Data: '221211'),
1100 (c: 'F'; Data: '231111'),
1101 (c: 'G'; Data: '112113'),
1102 (c: 'H'; Data: '112212'),
1103 (c: 'I'; Data: '112311'),
1104 (c: 'J'; Data: '122112'),
1105 (c: 'K'; Data: '132111'),
1106 (c: 'L'; Data: '111123'),
1107 (c: 'M'; Data: '111222'),
1108 (c: 'N'; Data: '111321'),
1109 (c: 'O'; Data: '121122'),
1110 (c: 'P'; Data: '131121'),
1111 (c: 'Q'; Data: '212112'),
1112 (c: 'R'; Data: '212211'),
1113 (c: 'S'; Data: '211122'),
1114 (c: 'T'; Data: '211221'),
1115 (c: 'U'; Data: '221121'),
1116 (c: 'V'; Data: '222111'),
1117 (c: 'W'; Data: '112122'),
1118 (c: 'X'; Data: '112221'),
1119 (c: 'Y'; Data: '122121'),
1120 (c: 'Z'; Data: '123111'),
1121 (c: '-'; Data: '121131'),
1122 (c: '.'; Data: '311112'),
1123 (c: ' '; Data: '311211'),
1124 (c: '$'; Data: '321111'),
1125 (c: '/'; Data: '112131'),
1126 (c: '+'; Data: '113121'),
1127 (c: '%'; Data: '211131'),
1128 (c: '['; Data: '121221'), // only used for Extended Code 93
1129 (c: ']'; Data: '312111'), // only used for Extended Code 93
1130 (c: '{'; Data: '311121'), // only used for Extended Code 93
1131 (c: '}'; Data: '122211') // only used for Extended Code 93
1132 );
1133
1134
1135 // find Code 93
Find_Code93null1136 function Find_Code93(c: char): integer;
1137 var
1138 i: integer;
1139 begin
1140 for i := 0 to High(tabelle_93) do
1141 begin
1142 if c = tabelle_93[i].c then
1143 begin
1144 Result := i;
1145 exit;
1146 end;
1147 end;
1148 Result := -1;
1149 end;
1150
1151 var
1152 i, idx: integer;
1153 checkC, checkK, // Checksums
1154 weightC, weightK: integer;
1155 begin
1156 Result := Convert('111141'); // Startcode
1157
1158 for i := 1 to Length(FText) do
1159 begin
1160 idx := Find_Code93(FText[i]);
1161 if idx < 0 then
1162 raise Exception.CreateFmt('%s:Code93 bad Data <%s>', [self.ClassName, FText]);
1163 Result := Result + Convert(tabelle_93[idx].Data);
1164 end;
1165
1166 checkC := 0;
1167 checkK := 0;
1168
1169 weightC := 1;
1170 weightK := 2;
1171
1172 for i := Length(FText) downto 1 do
1173 begin
1174 idx := Find_Code93(FText[i]);
1175
1176 Inc(checkC, idx * weightC);
1177 Inc(checkK, idx * weightK);
1178
1179 Inc(weightC);
1180 if weightC > 20 then
1181 weightC := 1;
1182 Inc(weightK);
1183 if weightK > 15 then
1184 weightK := 1;
1185 end;
1186
1187 Inc(checkK, checkC);
1188
1189 checkC := checkC mod 47;
1190 checkK := checkK mod 47;
1191
1192 Result := Result + Convert(tabelle_93[checkC].Data) +
1193 Convert(tabelle_93[checkK].Data);
1194
1195 Result := Result + Convert('1111411'); // Stopcode
1196 end;
1197
1198
TBarcode.Code_93Extendednull1199 function TBarcode.Code_93Extended: string;
1200 const
1201 code93x: array[0..127] of string[2] =
1202 (
1203 (']U'), ('[A'), ('[B'), ('[C'), ('[D'), ('[E'), ('[F'), ('[G'),
1204 ('[H'), ('[I'), ('[J'), ('[K'), ('[L'), ('[M'), ('[N'), ('[O'),
1205 ('[P'), ('[Q'), ('[R'), ('[S'), ('[T'), ('[U'), ('[V'), ('[W'),
1206 ('[X'), ('[Y'), ('[Z'), (']A'), (']B'), (']C'), (']D'), (']E'),
1207 (' '), ('{A'), ('{B'), ('{C'), ('{D'), ('{E'), ('{F'), ('{G'),
1208 ('{H'), ('{I'), ('{J'), ('{K'), ('{L'), ('{M'), ('{N'), ('{O'),
1209 ('0'), ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'),
1210 ('8'), ('9'), ('{Z'), (']F'), (']G'), (']H'), (']I'), (']J'),
1211 (']V'), ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'),
1212 ('H'), ('I'), ('J'), ('K'), ('L'), ('M'), ('N'), ('O'),
1213 ('P'), ('Q'), ('R'), ('S'), ('T'), ('U'), ('V'), ('W'),
1214 ('X'), ('Y'), ('Z'), (']K'), (']L'), (']M'), (']N'), (']O'),
1215 (']W'), ('}A'), ('}B'), ('}C'), ('}D'), ('}E'), ('}F'), ('}G'),
1216 ('}H'), ('}I'), ('}J'), ('}K'), ('}L'), ('}M'), ('}N'), ('}O'),
1217 ('}P'), ('}Q'), ('}R'), ('}S'), ('}T'), ('}U'), ('}V'), ('}W'),
1218 ('}X'), ('}Y'), ('}Z'), (']P'), (']Q'), (']R'), (']S'), (']T')
1219 );
1220
1221 var
1222 // save:array[0..254] of char;
1223 // old:string;
1224 save: string;
1225 i: integer;
1226 begin
1227 // CharToOem(PChar(FText), save);
1228 save := FText;
1229 FText := '';
1230
1231
1232 for i := 1 to Length(save) do
1233 begin
1234 if Ord(save[i]) <= 127 then
1235 FText := FText + code93x[Ord(save[i])];
1236 end;
1237
1238 //Showmessage(Format('Text: <%s>', [FText]));
1239
1240 Result := Code_93;
1241 FText := save;
1242 end;
1243
1244
Code_MSInull1245 function TBarcode.Code_MSI: string;
1246 const
1247 tabelle_MSI: array['0'..'9'] of string[8] =
1248 (
1249 ('51515151'), // '0'
1250 ('51515160'), // '1'
1251 ('51516051'), // '2'
1252 ('51516060'), // '3'
1253 ('51605151'), // '4'
1254 ('51605160'), // '5'
1255 ('51606051'), // '6'
1256 ('51606060'), // '7'
1257 ('60515151'), // '8'
1258 ('60515160') // '9'
1259 );
1260
1261 var
1262 i: integer;
1263 check_even, check_odd, vChecksum: integer;
1264 begin
1265 Result := '60'; // Startcode
1266 check_even := 0;
1267 check_odd := 0;
1268
1269 for i := 1 to Length(FText) do
1270 begin
1271 if odd(i - 1) then
1272 check_odd := check_odd * 10 + Ord(FText[i])
1273 else
1274 check_even := check_even + Ord(FText[i]);
1275
1276 Result := Result + tabelle_MSI[FText[i]];
1277 end;
1278
1279 vChecksum := quersumme(check_odd * 2) + check_even;
1280
1281 vChecksum := vChecksum mod 10;
1282 if vChecksum > 0 then
1283 vChecksum := 10 - vChecksum;
1284
1285 Result := Result + tabelle_MSI[chr(Ord('0') + vChecksum)];
1286
1287 Result := Result + '515'; // Stopcode
1288 end;
1289
1290
TBarcode.Code_PostNetnull1291 function TBarcode.Code_PostNet: string;
1292 const
1293 tabelle_PostNet: array['0'..'9'] of string[10] =
1294 (
1295 ('5151A1A1A1'), // '0'
1296 ('A1A1A15151'), // '1'
1297 ('A1A151A151'), // '2'
1298 ('A1A15151A1'), // '3'
1299 ('A151A1A151'), // '4'
1300 ('A151A151A1'), // '5'
1301 ('A15151A1A1'), // '6'
1302 ('51A1A1A151'), // '7'
1303 ('51A1A151A1'), // '8'
1304 ('51A151A1A1') // '9'
1305 );
1306 var
1307 i: integer;
1308 begin
1309 Result := '51';
1310
1311 for i := 1 to Length(FText) do
1312 begin
1313 Result := Result + tabelle_PostNet[FText[i]];
1314 end;
1315 Result := Result + '5';
1316 end;
1317
1318
TBarcode.Code_Codabarnull1319 function TBarcode.Code_Codabar: string;
1320 type
1321 TCodabar = record
1322 c: char;
1323 Data: array[0..6] of char;
1324 end;
1325
1326 const
1327 tabelle_cb: array[0..19] of TCodabar = (
1328 (c: '1'; Data: '5050615'),
1329 (c: '2'; Data: '5051506'),
1330 (c: '3'; Data: '6150505'),
1331 (c: '4'; Data: '5060515'),
1332 (c: '5'; Data: '6050515'),
1333 (c: '6'; Data: '5150506'),
1334 (c: '7'; Data: '5150605'),
1335 (c: '8'; Data: '5160505'),
1336 (c: '9'; Data: '6051505'),
1337 (c: '0'; Data: '5050516'),
1338 (c: '-'; Data: '5051605'),
1339 (c: '$'; Data: '5061505'),
1340 (c: ':'; Data: '6050606'),
1341 (c: '/'; Data: '6060506'),
1342 (c: '.'; Data: '6060605'),
1343 (c: '+'; Data: '5060606'),
1344 (c: 'A'; Data: '5061515'),
1345 (c: 'B'; Data: '5151506'),
1346 (c: 'C'; Data: '5051516'),
1347 (c: 'D'; Data: '5051615')
1348 );
1349
1350
1351 // find Codabar
Find_Codabarnull1352 function Find_Codabar(c: char): integer;
1353 var
1354 i: integer;
1355 begin
1356 for i := 0 to High(tabelle_cb) do
1357 begin
1358 if c = tabelle_cb[i].c then
1359 begin
1360 Result := i;
1361 exit;
1362 end;
1363 end;
1364 Result := -1;
1365 end;
1366
1367 var
1368 i, idx: integer;
1369 begin
1370 Result := tabelle_cb[Find_Codabar('A')].Data + '0';
1371 for i := 1 to Length(FText) do
1372 begin
1373 idx := Find_Codabar(FText[i]);
1374 Result := Result + tabelle_cb[idx].Data + '0';
1375 end;
1376 Result := Result + tabelle_cb[Find_Codabar('B')].Data;
1377 end;
1378
1379 procedure TBarcode.MakeModules;
1380 begin
1381 case Typ of
1382 bcCode_2_5_interleaved,
1383 bcCode_2_5_industrial,
1384 bcCode39,
1385 bcCodeEAN8,
1386 bcCodeEAN13,
1387 bcCode39Extended,
1388 bcCodeCodabar:
1389 begin
1390 if Ratio < 2.0 then
1391 Ratio := 2.0;
1392 if Ratio > 3.0 then
1393 Ratio := 3.0;
1394 end;
1395
1396 bcCode_2_5_matrix:
1397 begin
1398 if Ratio < 2.25 then
1399 Ratio := 2.25;
1400 if Ratio > 3.0 then
1401 Ratio := 3.0;
1402 end;
1403 bcCode128A,
1404 bcCode128B,
1405 bcCode128C,
1406 bcCode93,
1407 bcCode93Extended,
1408 bcCodeMSI,
1409 bcCodePostNet: ;
1410 end;
1411
1412 modules[0] := FModul;
1413 modules[1] := Round(FModul * FRatio);
1414 modules[2] := modules[1] * 3 div 2;
1415 modules[3] := modules[1] * 2;
1416 end;
1417
1418
1419 {
1420 Draw the Barcode
1421
1422 Parameter :
1423 'data' holds the pattern for a Barcode.
1424 A barcode begins always with a black line and
1425 ends with a black line.
1426
1427 The white Lines builds the space between the black Lines.
1428
1429 A black line must always followed by a white Line and vica versa.
1430
1431 Examples:
1432 '50505' // 3 thin black Lines with 2 thin white Lines
1433 '606' // 2 fat black Lines with 1 thin white Line
1434
1435 '5605015' // Error
1436
1437
1438 data[] : see procedure OneBarProps
1439
1440 }
1441 procedure TBarcode.DoLines(Data: string; Canvas: TCanvas);
1442
1443 var
1444 i: integer;
1445 lt: TBarLineType;
1446 xadd: integer;
1447 w, h: integer;
1448 a, b, c, d, // Edges of a line (we need 4 Point because the line
1449 // is a recangle
1450 orgin: TPoint;
1451 alpha: double;
1452
1453 begin
1454 xadd := 0;
1455 orgin.x := FLeft;
1456 orgin.y := FTop;
1457 alpha := FAngle * pi / 180.0;
1458
1459 with Canvas do
1460 begin
1461 Pen.Width := 1;
1462
1463 for i := 1 to Length(Data) do // examine the pattern string
1464 begin
1465 OneBarProps(Data[i], w, lt);
1466
1467 {
1468 case data[i] of
1469 '0': begin w := modules[0]; lt := white; end;
1470 '1': begin w := modules[1]; lt := white; end;
1471 '2': begin w := modules[2]; lt := white; end;
1472 '3': begin w := modules[3]; lt := white; end;
1473
1474
1475 '5': begin w := modules[0]; lt := black; end;
1476 '6': begin w := modules[1]; lt := black; end;
1477 '7': begin w := modules[2]; lt := black; end;
1478 '8': begin w := modules[3]; lt := black; end;
1479
1480 'A': begin w := modules[0]; lt := black_half; end;
1481 'B': begin w := modules[1]; lt := black_half; end;
1482 'C': begin w := modules[2]; lt := black_half; end;
1483 'D': begin w := modules[3]; lt := black_half; end;
1484 else
1485 begin
1486 // something went wrong
1487 // mistyped pattern table
1488 raise Exception.CreateFmt('%s: internal Error', [self.ClassName]);
1489 end;
1490 end;
1491 }
1492
1493 if (lt = black) or (lt = black_half) then
1494 begin
1495 Pen.Color := clBlack;
1496 end
1497 else
1498 begin
1499 Pen.Color := clWhite;
1500 end;
1501 Brush.Color := Pen.Color;
1502
1503 if lt = black_half then
1504 H := FHeight * 2 div 5
1505 else
1506 H := FHeight;
1507
1508
1509 a.x := xadd;
1510 a.y := 0;
1511
1512 b.x := xadd;
1513 b.y := H;
1514
1515 // c.x := xadd+width;
1516 c.x := xadd + W - 1; // 23.04.1999 Line was 1 Pixel too wide
1517 c.y := H;
1518
1519 // d.x := xadd+width;
1520 d.x := xadd + W - 1; // 23.04.1999 Line was 1 Pixel too wide
1521 d.y := 0;
1522
1523 // a,b,c,d builds the rectangle we want to draw
1524
1525
1526 // rotate the rectangle
1527 a := Translate2D(Rotate2D(a, alpha), orgin);
1528 b := Translate2D(Rotate2D(b, alpha), orgin);
1529 c := Translate2D(Rotate2D(c, alpha), orgin);
1530 d := Translate2D(Rotate2D(d, alpha), orgin);
1531
1532 // draw the rectangle
1533 Polygon([a, b, c, d]);
1534
1535 xadd := xadd + w;
1536 end;
1537 end;
1538 end;
1539
1540
1541 procedure TBarcode.DrawBarcode(Canvas: TCanvas);
1542 var
1543 Data: string;
1544 SaveFont: TFont;
1545 SavePen: TPen;
1546 SaveBrush: TBrush;
1547 begin
1548 Savefont := TFont.Create;
1549 SavePen := TPen.Create;
1550 SaveBrush := TBrush.Create;
1551
1552 // get barcode pattern
1553 Data := MakeData;
1554
1555 try
1556 // store Canvas properties
1557 Savefont.Assign(Canvas.Font);
1558 SavePen.Assign(Canvas.Pen);
1559 SaveBrush.Assign(Canvas.Brush);
1560
1561 DoLines(Data, Canvas); // draw the barcode
1562
1563 if FShowText then
1564 DrawText(Canvas); // show readable Text
1565
1566 // restore old Canvas properties
1567 Canvas.Font.Assign(savefont);
1568 Canvas.Pen.Assign(SavePen);
1569 Canvas.Brush.Assign(SaveBrush);
1570 finally
1571 Savefont.Free;
1572 SavePen.Free;
1573 SaveBrush.Free;
1574 end;
1575 end;
1576
1577
1578 {
1579 draw contents and type/name of barcode
1580 as human readable text at the left
1581 upper edge of the barcode.
1582
1583 main use for this procedure is testing.
1584
1585 note: this procedure changes Pen and Brush
1586 of the current canvas.
1587 }
1588 procedure TBarcode.DrawText(Canvas: TCanvas);
1589 begin
1590 with Canvas do
1591 begin
1592 Font.Size := 4;
1593 // the fixed font size is a problem, if you
1594 // use very large or small barcodes
1595
1596 Pen.Color := clBlack;
1597 Brush.Color := clWhite;
1598 TextOut(FLeft, FTop, FText); // contents of Barcode
1599 TextOut(FLeft, FTop + 14, GetTypText); // type/name of barcode
1600 end;
1601 end;
1602
returnsnull1603 // this function returns true for those symbols that correct them selves
1604 // in case invalid data is fed. For example feeding ABCD to 128C numeric
1605 // only symbol, the generated barcode will be for 0000
1606 function TBarcode.BarcodeTypeChecked(AType: TBarcodeType): boolean;
1607 begin
1608 result := aType in [ bcCode128A, bcCode128B, bcCode128C, bcCodeEAN8,
1609 bcCodeEAN13 ];
1610 end;
1611
TBarcode.CleanEANValuenull1612 function TBarcode.CleanEANValue(const AValue:string; const ASize: Byte): string;
1613 var
1614 tmp: string;
1615 n,i: Integer;
1616 begin
1617 tmp := AValue;
1618 n := Length(tmp);
1619
1620 // check if there is any strange char in string
1621 for i:=1 to n do
1622 if not (tmp[i] in ['0'..'9']) then
1623 tmp[i] := '0';
1624
1625 // enforce a ASize char string by adding a 0
1626 // verifier digit if necesary or calc it if
1627 // checksum was specified
1628 if n<ASize then begin
1629 tmp := stringofchar('0', ASize-n-1) + tmp + '0';
1630 // TODO: if not FCheckSum was specified
1631 // resulting barcode might be invalid
1632 // as a '0' checksum digit was forced.
1633 end;
1634
1635 if FCheckSum then
1636 Result := getEAN(copy(tmp, 1, ASize-1) + '0')
1637 else
1638 Result := copy(tmp, 1, ASize);
1639
1640 end;
1641
1642
1643
1644 end.
1645
1646