| 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 | }
|
|---|
| 12 | unit lbc_telepen;
|
|---|
| 13 |
|
|---|
| 14 | {$mode objfpc}{$H+}
|
|---|
| 15 |
|
|---|
| 16 | interface
|
|---|
| 17 |
|
|---|
| 18 | uses
|
|---|
| 19 | SysUtils, zint;
|
|---|
| 20 |
|
|---|
| 21 | function telepen(ASymbol: PZintSymbol; const ASource: String): Integer;
|
|---|
| 22 | function telepen_num(ASymbol: PZintSymbol; const ASource: String): Integer;
|
|---|
| 23 |
|
|---|
| 24 | implementation
|
|---|
| 25 |
|
|---|
| 26 | uses
|
|---|
| 27 | lbc_helper;
|
|---|
| 28 |
|
|---|
| 29 | const 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 |
|
|---|
| 58 | function CheckSum_telepen(ASource: String): String;
|
|---|
| 59 | var
|
|---|
| 60 | i, sum: Integer;
|
|---|
| 61 | check_digit: Integer;
|
|---|
| 62 | begin
|
|---|
| 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);
|
|---|
| 71 | end;
|
|---|
| 72 |
|
|---|
| 73 | function telepen(ASymbol: PZintSymbol; const ASource: String): Integer;
|
|---|
| 74 | var
|
|---|
| 75 | i: Integer;
|
|---|
| 76 | begin
|
|---|
| 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);
|
|---|
| 88 | end;
|
|---|
| 89 |
|
|---|
| 90 | function telepen_num(ASymbol: PZintSymbol; const ASource: String): Integer;
|
|---|
| 91 | const
|
|---|
| 92 | VALID_CHARS = NEON + 'X';
|
|---|
| 93 | var
|
|---|
| 94 | src, dest: String;
|
|---|
| 95 | i, pair, checksum: Integer;
|
|---|
| 96 | begin
|
|---|
| 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);
|
|---|
| 155 | end;
|
|---|
| 156 |
|
|---|
| 157 | end.
|
|---|
| 158 |
|
|---|
| 159 |
|
|---|