source: trunk/Packages/lazbarcodes/src/lbc_telepen.pas

Last change on this file was 123, checked in by chronos, 3 years ago
  • Added: QR code image visible in contact others tab. It can be saved as image to file.
File size: 5.3 KB
Line 
1{ lbc_telepen.pas - Handles telepen alpha, and telepen numeric barcodes.
2
3 Based on Zint (done by Robin Stuart and the Zint team)
4 http://github.com/zint/zint
5 and Pascal adaption by TheUnknownOnes
6 http://theunknownones.net
7
8 Refactoring: W.Pamler
9
10 Fixes: Usage of character 'X' in input string.
11}
12unit lbc_telepen;
13
14{$mode objfpc}{$H+}
15
16interface
17
18uses
19 SysUtils, zint;
20
21function telepen(ASymbol: PZintSymbol; const ASource: String): Integer;
22function telepen_num(ASymbol: PZintSymbol; const ASource: String): Integer;
23
24implementation
25
26uses
27 lbc_helper;
28
29const TeleTable: array[0..126] of String = (
30 '1111111111111111', '1131313111', '33313111', '1111313131', '3111313111',
31 '11333131', '13133131', '111111313111', '31333111', '1131113131',
32 '33113131', '1111333111', '3111113131', '1113133111', '1311133111',
33 '111111113131', '3131113111', '11313331', '333331', '111131113111',
34 '31113331', '1133113111', '1313113111', '1111113331', '31131331',
35 '113111113111', '3311113111', '1111131331', '311111113111', '1113111331',
36 '1311111331', '11111111113111', '31313311', '1131311131', '33311131',
37 '1111313311', '3111311131', '11333311', '13133311', '111111311131',
38 '31331131', '1131113311', '33113311', '1111331131', '3111113311',
39 '1113131131', '1311131131', '111111113311', '3131111131', '1131131311',
40 '33131311', '111131111131', '3111131311', '1133111131', '1313111131',
41 '111111131311', '3113111311', '113111111131', '3311111131', '111113111311',
42 '311111111131', '111311111311', '131111111311', '11111111111131', '3131311111',
43 '11313133', '333133', '111131311111', '31113133', '1133311111',
44 '1313311111', '1111113133', '313333', '113111311111', '3311311111',
45 '11113333', '311111311111', '11131333', '13111333', '11111111311111',
46 '31311133', '1131331111', '33331111', '1111311133', '3111331111',
47 '11331133', '13131133', '111111331111', '3113131111', '1131111133',
48 '33111133', '111113131111', '3111111133', '111311131111', '131111131111',
49 '111111111133', '31311313', '113131111111', '3331111111', '1111311313',
50 '311131111111', '11331313', '13131313', '11111131111111', '3133111111',
51 '1131111313', '33111313', '111133111111', '3111111313', '111313111111',
52 '131113111111', '111111111313', '313111111111', '1131131113', '33131113',
53 '11113111111111', '3111131113', '113311111111', '131311111111', '111111131113',
54 '3113111113', '11311111111111', '331111111111', '111113111113', '31111111111111',
55 '111311111113', '131111111113'
56);
57
58function CheckSum_telepen(ASource: String): String;
59var
60 i, sum: Integer;
61 check_digit: Integer;
62begin
63 sum := 0;
64 for i := 1 to Length(ASource) do
65 inc(sum, ord(ASource[i]));
66
67 check_digit := 127 - sum mod 127;
68 if (check_digit = 127) then check_digit := 0;
69
70 Result := char(check_digit);
71end;
72
73function telepen(ASymbol: PZintSymbol; const ASource: String): Integer;
74var
75 i: Integer;
76begin
77 for i := 1 to Length(ASource) do
78 if ASource[i] > #126 then
79 begin
80 // Cannot encode extended ASCII
81 ASymbol^.SetErrorText('Invalid characters in input data.');
82 Result := ERROR_INVALID_DATA;
83 exit;
84 end;
85
86 Result := basic_encoder(ASymbol, ASource,
87 30, '', TeleTable[ord('_')], TeleTable, TeleTable[ord('z')], @CheckSum_telepen, false);
88end;
89
90function telepen_num(ASymbol: PZintSymbol; const ASource: String): Integer;
91const
92 VALID_CHARS = NEON + 'X';
93var
94 src, dest: String;
95 i, pair, checksum: Integer;
96begin
97 if Length(ASource) > 60 then
98 begin
99 ASymbol^.SetErrorText('Input too long (max 60 characters).');
100 Result := ERROR_TOO_LONG;
101 exit;
102 end;
103
104 src := UpperCase(ASource);
105 Result := is_sane(VALID_CHARS, src);
106 if Result = ERROR_INVALID_DATA then
107 begin
108 ASymbol^.SetErrorText('Invalid characters in data.');
109 exit;
110 end;
111
112 // Add a leading zero if required (the input string length must be even).
113 if odd(Length(src)) then
114 src := '0' +src;
115
116 // START character
117 dest := TeleTable[ord('_')];
118
119 // Extract pairs of digits. Their numerical value is encoded. An 'X' is
120 // allowed to identify single-digit numbers; it must be the LAST character of
121 // a pair.
122 // Example: 466X33 is valid (pairs 46, 6X, 33)
123 // 46X333 is not valid (pairs 46, X3, 33)
124 i := 1;
125 checksum := 0;
126 while i < Length(src) do
127 begin
128 if src[i] = 'X' then
129 begin
130 ASymbol^.SetErrorText('Invalid position of X in Telepen data.');
131 Result := ERROR_INVALID_DATA;
132 exit;
133 end;
134 if src[i+1] = 'X' then
135 pair := StrToInt(src[i]) + 17
136 else
137 pair := StrToInt(src[i] + src[i+1]) + 27;
138 dest := dest + TeleTable[pair];
139 inc(checksum, pair);
140 inc(i, 2);
141 end;
142
143 checksum := 127 - checksum mod 127;
144 if checksum = 127 then checksum := 0;
145 dest := dest + TeleTable[checksum];
146
147 // STOP character
148 dest := dest + TeleTable[ord('z')];
149
150 // Expand to modules
151 expand(ASymbol, dest);
152
153 // Store human-readable text.
154 ASymbol^.SetText(src);
155end;
156
157end.
158
159
Note: See TracBrowser for help on using the repository browser.