📄 barcode.pas
字号:
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鋘derte Dateien ist nicht zul鋝sig.
F黵 die Korrektheit der erzeugten Barcodes kann keine Garantie
黚ernommen 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)
-----------------------
- Code128C not implemented (could someone else
do this for me ?)
- Wrapper Class for Quick Reports
}
interface
uses
Windows, Messages, 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 = 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;
modules:array[0..3] of shortint;
procedure OneBarProps(code:char; var Width:integer; var 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;
protected
{ Protected-Deklarationen }
function MakeData : string;
public
{ Public-Deklarationen }
constructor Create(Owner:TComponent); override;
procedure DrawBarcode(Canvas:TCanvas);
procedure DrawText(Canvas:TCanvas);
published
{ Published-Deklarationen }
// Height of Barcode (Pixel)
property Height : integer read FHeight write FHeight;
property Text : string read FText write FText;
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(Owner:TComponent);
begin
inherited Create(owner);
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; var Width:integer; var lt:TBarLineType);
begin
case code of
'0': begin width := modules[0]; lt := white; end;
'1': begin width := modules[1]; lt := white; end;
'2': begin width := modules[2]; lt := white; end;
'3': begin width := modules[3]; lt := white; end;
'5': begin width := modules[0]; lt := black; end;
'6': begin width := modules[1]; lt := black; end;
'7': begin width := modules[2]; lt := black; end;
'8': begin width := modules[3]; lt := black; end;
'A': begin width := modules[0]; lt := black_half; end;
'B': begin width := modules[1]; lt := black_half; end;
'C': begin width := modules[2]; lt := black_half; end;
'D': begin width := 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;
////////////////////////////// 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'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -