Files
lazarus-ccr/components/lazbarcodes/src/uhelper.pas

486 lines
12 KiB
ObjectPascal
Raw Normal View History

unit uhelper;
{$mode objfpc}{$H+}
interface
uses sysutils,zint;
const RHODIUM = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
const NEON = '0123456789';
function IsTrue(aBoolean: Boolean): Boolean;
function IsTrue(aInteger: Integer): Boolean;
function iif(const aBoolean: integer; const aCh1,aCh2: pchar): pchar;
function iif(const aBoolean: integer; const aCh1,aCh2: char): char;
function iif(const aBoolean: Boolean; const aV1,aV2: Word): word;
procedure concat(const aText: pchar; const aChar: char);
procedure concat(const aText: pchar; const aText2: pchar);
procedure concat(var aText: array of char; const aText2: pchar);
procedure strcpy(const aText: pchar; const aText2: pchar);
procedure strcpy(var aText: array of char; const aText2: pchar); overload;
function posn(const aText: pchar; const aChar: Char): integer;
function strlen(const aText: array of char): integer;
function is_sane(test_string: PChar; source: PBYTE; length: Integer): Integer;
function utf8toutf16(symbol: PointerTo_zint_symbol; source: PBYTE; vals: PInteger; length: PInteger): Integer;
procedure set_module(symbol: PointerTo_zint_symbol; y_coord: Integer; x_coord: Integer);
procedure unset_module(symbol: PointerTo_zint_symbol; y_coord: Integer; x_coord: Integer);
function module_is_set(symbol: PointerTo_zint_symbol; y_coord: Integer; x_coord: Integer): Boolean;
function PostInc(var v: integer): integer;
function PostDec(var v: integer): integer;
function is_extendable(symbology: Integer): Boolean;
function is_stackable(symbology: Integer): Boolean;
function NotBoolean(const aValue: integer): Boolean;
function NotBoolean(const aValue: Boolean): Boolean;
function latin1_process(symbol: PointerTo_zint_symbol; source: PBYTE; preprocessed: PBYTE; length: PInteger): Integer;
function ctoi(c: char): integer;
function ctoi(c: BYTE): integer;
function BooleanNot(const aValue: integer): Boolean;
procedure memset(const p: Pointer; const aValue: BYTE; const aSize: integer);
function istwodigits(source: PBYTE; position: Integer): Boolean;
implementation
function istwodigits(source: PBYTE; position: Integer): Boolean;
begin
if (Char(source[position]) in ['0'..'9']) and (Char(source[position+1]) in ['0'..'9']) then begin
Result:=true;
end else begin
Result:=false;
end;
end;
function PostInc(var v: integer): integer;
begin
Result:=v;
inc(v);
end;
function PostDec(var v: integer): integer;
begin
Result:=v;
Dec(v);
end;
function IsTrue(aBoolean: Boolean): Boolean;
begin
Result:=aBoolean;
end;
function IsTrue(aInteger: Integer): Boolean;
begin
if aInteger=0 then Result:=false else Result:=true;
end;
function iif(const aBoolean: integer; const aCh1, aCh2: pchar): pchar;
begin
if aBoolean=0 then begin
Result:=aCh2;
end else begin
Result:=aCh1;
end;
end;
function iif(const aBoolean: integer; const aCh1,aCh2: char): char;
begin
if aBoolean=0 then begin
Result:=aCh2;
end else begin
Result:=aCh1;
end;
end;
function iif(const aBoolean: Boolean; const aV1,aV2: Word): word;
begin
if aBoolean then Result:=aV1 else Result:=aV2;
end;
procedure concat(const aText: pchar; const aChar: char);
var
i: integer;
begin
i:=sysutils.strlen(aText);
aText[i]:=aChar;
inc(i);
aText[i]:=#0;
end;
procedure concat(const aText: pchar; const aText2: pchar);
var
i: integer;
begin
i:=sysutils.strlen(aText);
move(aText2^,aText[i],sysutils.strlen(aText2)+1);
end;
procedure concat(var aText: array of char; const aText2: pchar);
begin
concat(pchar(@aText[0]),aText2);
end;
procedure strcpy(const aText: pchar; const aText2: pchar);
begin
move(aText2^,aText^,sysutils.strlen(aText2)+1);
end;
procedure strcpy(var aText: array of char; const aText2: pchar);
begin
move(aText2^,aText[0],sysutils.strlen(aText2)+1);
end;
function posn(const aText: pchar; const aChar: Char): integer;
var
p: Pchar;
c: integer;
begin
p:=aText;
c:=0;
while p^<>#0 do begin
if p^<>aChar then begin
inc(c);
inc(p);
end else begin
Exit(c);
end;
end;
Result:=0;
end;
function strlen(const aText: array of char): integer;
begin
Result:=sysutils.strlen(pchar(@aText[0]));
end;
function is_sane(test_string: PChar; source: PBYTE; length: Integer): Integer;
var
latch: Boolean;
j: Cardinal;
i: Integer;
lt: Cardinal;
begin
{INITCODE} lt := sysutils.strlen (test_string);
i := 0;
while i < length do
begin
latch := FALSE;
j := 0;
while j < lt do
begin
if Boolean(source[i] = BYTE(test_string[j])) then
begin
latch := TRUE;
break;
end;
Inc (j);
end;
if Boolean(NotBoolean (latch)) then
begin
exit (ERROR_INVALID_DATA);
end;
Inc (i);
end;
exit (0);
end;
function utf8toutf16(symbol: PointerTo_zint_symbol; source: PBYTE; vals: PInteger; length: PInteger): Integer;
var
error_number: Integer;
jpos: Integer;
bpos: Integer;
next: Integer;
begin
bpos := 0;
jpos := 0;
error_number := 0;
next := 0;
repeat
if source[bpos] <= $7F then
begin
vals[jpos] := source[bpos];
next := bpos + 1;
Inc (jpos);
end else begin
if (source[bpos] >= $80) and (source[bpos] <= $BF) then
begin
strcpy (symbol^.errtxt, 'Corrupt Unicode data');
exit (ERROR_INVALID_DATA);
end;
if (source[bpos] >= $C0) and (source[bpos] <= $C1) then
begin
strcpy (symbol^.errtxt, 'Overlong encoding not supported');
exit (ERROR_INVALID_DATA);
end;
if (source[bpos] >= $C2) and (source[bpos] <= $DF) then
begin
vals[jpos] := ((source[bpos] and $1F) shl 6) + (source[bpos + 1] and $3F);
next := bpos + 2;
Inc (jpos);
end else begin
if (source[bpos] >= $E0) and (source[bpos] <= $EF) then
begin
vals[jpos] := ((source[bpos] and $0F) shl 12) + ((source[bpos + 1] and $3F) shl 6) + (source[bpos + 2] and $3F);
next := bpos + 3;
Inc (jpos);
end else begin
if source[bpos] >= $F0 then
begin
strcpy (symbol^.errtxt, 'Unicode sequences of more than 3 bytes not supported');
exit (ERROR_INVALID_DATA);
end;
end;
end;
end;
bpos := next;
until not (bpos < length^);
length^ := jpos;
exit (error_number);
end;
function module_is_set(symbol: PointerTo_zint_symbol; y_coord: Integer; x_coord: Integer): Boolean;
var
x_sub: Integer;
x_char: Integer;
begin
x_char := x_coord div 7;
x_sub := x_coord mod 7;
{$PUSH}{$R-}
Result:=((symbol^.encoded_data[y_coord][x_coord div 7] shr (x_coord mod 7)) and 1)<>0;
{$POP}
exit;
Result:=false;
case x_sub of
0: if Boolean((symbol^.encoded_data[y_coord][x_char] and $01) <> 0) then
begin
result := true;
end;
1: if Boolean((symbol^.encoded_data[y_coord][x_char] and $02) <> 0) then
begin
result := true;
end;
2: if Boolean((symbol^.encoded_data[y_coord][x_char] and $04) <> 0) then
begin
result := true;
end;
3: if Boolean((symbol^.encoded_data[y_coord][x_char] and $08) <> 0) then
begin
result := true;
end;
4: if Boolean((symbol^.encoded_data[y_coord][x_char] and $10) <> 0) then
begin
result := true;
end;
5: if Boolean((symbol^.encoded_data[y_coord][x_char] and $20) <> 0) then
begin
result := true;
end;
6: if Boolean((symbol^.encoded_data[y_coord][x_char] and $40) <> 0) then
begin
result := true;
end;
else
result:=false;
end;
end;
procedure set_module(symbol: PointerTo_zint_symbol; y_coord: Integer; x_coord: Integer);
var
x_sub: Integer;
x_char: Integer;
begin
x_char := x_coord div 7;
x_sub := x_coord mod 7;
case x_sub of
0: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $01;
1: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $02;
2: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $04;
3: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $08;
4: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $10;
5: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $20;
6: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] + $40;
end;
end;
procedure unset_module(symbol: PointerTo_zint_symbol; y_coord: Integer; x_coord: Integer);
var
x_sub: Integer;
x_char: Integer;
begin
x_char := x_coord div 7;
x_sub := x_coord mod 7;
case x_sub of
0: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $01;
1: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $02;
2: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $04;
3: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $08;
4: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $10;
5: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $20;
6: symbol^.encoded_data[y_coord][x_char] := symbol^.encoded_data[y_coord][x_char] - $40;
end;
end;
procedure to_upper(a: PBYTE);
begin
while a^<>0 do begin
if char(a^) in ['a'..'z'] then begin
a^:=BYTE(upCase(char(a^)));
end;
inc(a);
end;
end;
function ctoi(c: char): integer;
begin
if c in ['0'..'9'] then begin
Result:=BYTE(c)-48;
end else begin
Result:=-1;
end;
end;
function ctoi(c: BYTE): integer;
begin
Result:=ctoi(char(c));
end;
function BooleanNot(const aValue: integer): Boolean;
begin
Result:=NotBoolean(aValue);
end;
procedure memset(const p: Pointer; const aValue: BYTE; const aSize: integer);
begin
FillByte(PBYTE(p)^,aSize,aValue);
end;
function is_extendable(symbology: Integer): Boolean;
begin
if symbology = BARCODE_EANX then
begin
exit (true);
end;
if symbology = BARCODE_UPCA then
begin
exit (true);
end;
if symbology = BARCODE_UPCE then
begin
exit (true);
end;
if symbology = BARCODE_ISBNX then
begin
exit (true);
end;
if symbology = BARCODE_UPCA_CC then
begin
exit (true);
end;
if symbology = BARCODE_UPCE_CC then
begin
exit (true);
end;
if symbology = BARCODE_EANX_CC then
begin
exit (true);
end;
exit (false);
end;
function is_stackable(symbology: Integer): Boolean;
begin
if symbology < BARCODE_PDF417 then
begin
exit (true);
end;
if symbology = BARCODE_CODE128B then
begin
exit (true);
end;
if symbology = BARCODE_ISBNX then
begin
exit (true);
end;
if symbology = BARCODE_EAN14 then
begin
exit (true);
end;
if symbology = BARCODE_NVE18 then
begin
exit (true);
end;
if symbology = BARCODE_KOREAPOST then
begin
exit (true);
end;
if symbology = BARCODE_PLESSEY then
begin
exit (true);
end;
if symbology = BARCODE_TELEPEN_NUM then
begin
exit (true);
end;
if symbology = BARCODE_ITF14 then
begin
exit (true);
end;
if symbology = BARCODE_CODE32 then
begin
exit (true);
end;
exit (false);
end;
function NotBoolean(const aValue: integer): Boolean;
begin
if aValue=0 then Result:=true else Result:=false;
end;
function NotBoolean(const aValue: Boolean): Boolean;
begin
if aValue=false then Result:=true else Result:=false;
end;
function latin1_process(symbol: PointerTo_zint_symbol; source: PBYTE; preprocessed: PBYTE; length: PInteger): Integer;
var
next: Integer;
i: Integer;
j: Integer;
begin
j := 0;
i := 0;
repeat
next := -1;
if Boolean(source[i] < 128) then
begin
preprocessed[j] := source[i];
Inc (j);
next := i + 1;
end else begin
if Boolean(source[i] = $C2) then
begin
preprocessed[j] := source[i + 1];
Inc (j);
next := i + 2;
end;
if Boolean(source[i] = $C3) then
begin
preprocessed[j] := source[i + 1] + 64;
Inc (j);
next := i + 2;
end;
end;
if Boolean(next = -1) then
begin
strcpy (symbol^.errtxt, 'error: Invalid character in input string (only Latin-1 characters supported)');
exit (ERROR_INVALID_DATA);
end;
i := next;
until not (i < length^);
preprocessed[j] := 0;
length^ := j;
exit (0);
end;
end.