mirror of
https://git.code.sf.net/p/zint/code
synced 2025-12-18 02:17:06 +00:00
general: split up some source files to lessen ZXing-C++ bloat
when `ZXING_USE_BUNDLED_ZINT` set
This commit is contained in:
428
backend/code.c
428
backend/code.c
@@ -1,7 +1,7 @@
|
||||
/* code.c - Handles Code 11, 39, 39+, 93, PZN, Channel and VIN */
|
||||
/* code.c - Handles Code 39, 39+, 93 and VIN */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2025 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@@ -36,20 +36,11 @@
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
|
||||
#define SODIUM_MNS_F (IS_NUM_F | IS_MNS_F) /* SODIUM "0123456789-" */
|
||||
|
||||
/* Same as TECHNETIUM (HIBC) with "abcd" added for CODE93 */
|
||||
static const char SILVER[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd";
|
||||
|
||||
#define ARSENIC_F (IS_NUM_F | IS_ARS_F) /* ARSENIC "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" */
|
||||
|
||||
static const char C11Table[11 + 1][6] = {
|
||||
{'1','1','1','1','2','1'}, {'2','1','1','1','2','1'}, {'1','2','1','1','2','1'}, {'2','2','1','1','1','1'},
|
||||
{'1','1','2','1','2','1'}, {'2','1','2','1','1','1'}, {'1','2','2','1','1','1'}, {'1','1','1','2','2','1'},
|
||||
{'2','1','1','2','1','1'}, {'2','1','1','1','1','1'}, {'1','1','2','1','1','1'},
|
||||
{'1','1','2','2','1','1'} /* Start character (full 6), Stop character (first 5) */
|
||||
};
|
||||
|
||||
/* Code 39 character assignments (ISO/IEC 16388:2007 Table 1 and Table A.1) */
|
||||
static const char C39Table[43 + 1][10] = {
|
||||
{'1','1','1','2','2','1','2','1','1','1'}, {'2','1','1','2','1','1','1','1','2','1'},
|
||||
@@ -127,115 +118,6 @@ static const char C93Table[47][6] = {
|
||||
{'3','1','2','1','1','1'}, {'3','1','1','1','2','1'}, {'1','2','2','2','1','1'}
|
||||
};
|
||||
|
||||
/* Code 11 */
|
||||
INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
int i;
|
||||
int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
|
||||
int weight[141]; /* 140 + 1 extra for 1st check */
|
||||
char dest[864]; /* 6 + 140 * 6 + 2 * 6 + 5 + 1 = 864 */
|
||||
int error_number = 0;
|
||||
char *d = dest;
|
||||
int num_check_digits;
|
||||
char checkstr[3] = {0};
|
||||
static const char checkchrs[11] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' };
|
||||
|
||||
/* Suppresses clang-tidy clang-analyzer-core.UndefinedBinaryOperatorResult warning */
|
||||
assert(length > 0);
|
||||
|
||||
if (length > 140) { /* 8 (Start) + 140 * 8 + 2 * 8 (Check) + 7 (Stop) = 1151 */
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 320, "Input length %d too long (maximum 140)", length);
|
||||
}
|
||||
if ((i = not_sane(SODIUM_MNS_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 321,
|
||||
"Invalid character at position %d in input (digits and \"-\" only)", i);
|
||||
}
|
||||
|
||||
if (symbol->option_2 < 0 || symbol->option_2 > 2) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 339, "Invalid check digit version '%d' (1 or 2 only)",
|
||||
symbol->option_2);
|
||||
}
|
||||
if (symbol->option_2 == 2) {
|
||||
num_check_digits = 0;
|
||||
} else if (symbol->option_2 == 1) {
|
||||
num_check_digits = 1;
|
||||
} else {
|
||||
num_check_digits = 2;
|
||||
}
|
||||
|
||||
c_weight = 1;
|
||||
c_count = 0;
|
||||
k_weight = 1;
|
||||
k_count = 0;
|
||||
|
||||
/* start character */
|
||||
memcpy(d, C11Table[11], 6);
|
||||
d += 6;
|
||||
|
||||
/* Draw main body of barcode */
|
||||
for (i = 0; i < length; i++, d += 6) {
|
||||
if (source[i] == '-')
|
||||
weight[i] = 10;
|
||||
else
|
||||
weight[i] = ctoi(source[i]);
|
||||
memcpy(d, C11Table[weight[i]], 6);
|
||||
}
|
||||
|
||||
if (num_check_digits) {
|
||||
/* Calculate C checksum */
|
||||
for (h = length - 1; h >= 0; h--) {
|
||||
c_count += (c_weight * weight[h]);
|
||||
c_weight++;
|
||||
|
||||
if (c_weight > 10) {
|
||||
c_weight = 1;
|
||||
}
|
||||
}
|
||||
c_digit = c_count % 11;
|
||||
|
||||
checkstr[0] = checkchrs[c_digit];
|
||||
memcpy(d, C11Table[c_digit], 6);
|
||||
d += 6;
|
||||
|
||||
if (num_check_digits == 2) {
|
||||
weight[length] = c_digit;
|
||||
|
||||
/* Calculate K checksum */
|
||||
for (h = length; h >= 0; h--) {
|
||||
k_count += (k_weight * weight[h]);
|
||||
k_weight++;
|
||||
|
||||
if (k_weight > 9) {
|
||||
k_weight = 1;
|
||||
}
|
||||
}
|
||||
k_digit = k_count % 11;
|
||||
|
||||
checkstr[1] = checkchrs[k_digit];
|
||||
memcpy(d, C11Table[k_digit], 6);
|
||||
d += 6;
|
||||
}
|
||||
}
|
||||
|
||||
if (symbol->debug & ZINT_DEBUG_PRINT) {
|
||||
printf("Check digit (%d): %s\n", num_check_digits, num_check_digits ? checkstr : "<none>");
|
||||
}
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, C11Table[11], 5);
|
||||
d += 5;
|
||||
|
||||
expand(symbol, dest, d - dest);
|
||||
|
||||
/* TODO: Find documentation on BARCODE_CODE11 dimensions/height */
|
||||
|
||||
ustrcpy(symbol->text, source);
|
||||
if (num_check_digits) {
|
||||
ustrcat(symbol->text, checkstr);
|
||||
}
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Code 39 */
|
||||
INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int i;
|
||||
@@ -353,91 +235,6 @@ INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Pharmazentralnummer (PZN) */
|
||||
/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA_Info_Code_39_EN.pdf */
|
||||
/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/
|
||||
IFA-Info_Check_Digit_Calculations_PZN_PPN_UDI_EN.pdf */
|
||||
INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
int i, error_number, zeroes;
|
||||
int count, check_digit;
|
||||
unsigned char have_check_digit = '\0';
|
||||
char localstr[1 + 8 + 1]; /* '-' prefix + 8 digits + NUL */
|
||||
const int pzn7 = symbol->option_2 == 1;
|
||||
|
||||
if (length > 8 - pzn7) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 325, "Input length %1$d too long (maximum %2$d)", length,
|
||||
8 - pzn7);
|
||||
}
|
||||
if (length == 8 - pzn7) {
|
||||
have_check_digit = source[7 - pzn7];
|
||||
length--;
|
||||
}
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 326,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
localstr[0] = '-';
|
||||
zeroes = 7 - pzn7 - length + 1;
|
||||
for (i = 1; i < zeroes; i++)
|
||||
localstr[i] = '0';
|
||||
ustrcpy(localstr + zeroes, source);
|
||||
|
||||
count = 0;
|
||||
for (i = 1; i < 8 - pzn7; i++) {
|
||||
count += (i + pzn7) * ctoi(localstr[i]);
|
||||
}
|
||||
|
||||
check_digit = count % 11;
|
||||
|
||||
if (symbol->debug & ZINT_DEBUG_PRINT) {
|
||||
printf("PZN: %s, check digit %d\n", localstr, (int) check_digit);
|
||||
}
|
||||
|
||||
if (check_digit == 10) {
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 327, "Invalid PZN, check digit is '10'");
|
||||
}
|
||||
if (have_check_digit && ctoi(have_check_digit) != check_digit) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 890, "Invalid check digit '%1$c', expecting '%2$c'",
|
||||
have_check_digit, itoc(check_digit));
|
||||
}
|
||||
|
||||
localstr[8 - pzn7] = itoc(check_digit);
|
||||
localstr[9 - pzn7] = '\0';
|
||||
|
||||
if (pzn7) {
|
||||
symbol->option_2 = 0; /* Need to overwrite this so `code39()` doesn't add a check digit itself */
|
||||
}
|
||||
|
||||
error_number = code39(symbol, (unsigned char *) localstr, 9 - pzn7);
|
||||
|
||||
if (pzn7) {
|
||||
symbol->option_2 = 1; /* Restore */
|
||||
}
|
||||
|
||||
ustrcpy(symbol->text, "PZN - "); /* Note changed to put space after hyphen */
|
||||
ustrcat(symbol->text, localstr + 1);
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* Technical Information regarding PZN Coding V 2.1 (25 Feb 2019) Code size
|
||||
https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA_Info_Code_39_EN.pdf
|
||||
"normal" X 0.25mm (0.187mm - 0.45mm), height 8mm - 20mm for 0.25mm X, 10mm mentioned so use that
|
||||
as default, 10mm / 0.25mm = 40 */
|
||||
if (error_number < ZINT_ERROR) {
|
||||
const float min_height = 17.7777786f; /* 8.0 / 0.45 */
|
||||
const float max_height = 106.951874f; /* 20.0 / 0.187 */
|
||||
error_number = set_height(symbol, min_height, 40.0f, max_height, 0 /*no_errtxt*/);
|
||||
}
|
||||
} else {
|
||||
if (error_number < ZINT_ERROR) {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
|
||||
INTERNAL int excode39(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
@@ -599,227 +396,6 @@ INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
return error_number;
|
||||
}
|
||||
|
||||
typedef const struct s_channel_precalc {
|
||||
int value; unsigned char B[8]; unsigned char S[8]; unsigned char bmax[7]; unsigned char smax[7];
|
||||
} channel_precalc;
|
||||
|
||||
#if 0
|
||||
#define CHANNEL_GENERATE_PRECALCS
|
||||
#endif
|
||||
|
||||
#ifdef CHANNEL_GENERATE_PRECALCS
|
||||
/* To generate precalc tables uncomment CHANNEL_GENERATE_PRECALCS define and run
|
||||
"backend/tests/test_channel -f generate -g" and place result in "channel_precalcs.h" */
|
||||
static void channel_generate_precalc(int channels, int value, int mod, int last, int B[8], int S[8], int bmax[7],
|
||||
int smax[7]) {
|
||||
int i;
|
||||
if (value == mod) printf("static channel_precalc channel_precalcs%d[] = {\n", channels);
|
||||
printf(" { %7ld, {", value); for (i = 0; i < 8; i++) printf(" %d,", B[i]); fputs(" },", stdout);
|
||||
fputs(" {", stdout); for (i = 0; i < 8; i++) printf(" %d,", S[i]); fputs(" },", stdout);
|
||||
fputs(" {", stdout); for (i = 0; i < 7; i++) printf(" %d,", bmax[i]); fputs(" },", stdout);
|
||||
fputs(" {", stdout); for (i = 0; i < 7; i++) printf(" %d,", smax[i]); fputs(" }, },\n", stdout);
|
||||
if (value == last) fputs("};\n", stdout);
|
||||
}
|
||||
#else
|
||||
#include "channel_precalcs.h"
|
||||
#endif
|
||||
|
||||
static int channel_copy_precalc(channel_precalc *const precalc, int B[8], int S[8], int bmax[7], int smax[7]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
B[i] = precalc->B[i];
|
||||
S[i] = precalc->S[i];
|
||||
bmax[i] = precalc->bmax[i];
|
||||
smax[i] = precalc->smax[i];
|
||||
}
|
||||
B[7] = precalc->B[7];
|
||||
S[7] = precalc->S[7];
|
||||
|
||||
return precalc->value;
|
||||
}
|
||||
|
||||
/* CHNCHR is adapted from ANSI/AIM BC12-1998 Annex D Figure D5 and is Copyright (c) AIM 1997 */
|
||||
|
||||
/* It is used here on the understanding that it forms part of the specification
|
||||
for Channel Code and therefore its use is permitted under the following terms
|
||||
set out in that document:
|
||||
|
||||
"It is the intent and understanding of AIM [t]hat the symbology presented in this
|
||||
specification is entirely in the public domain and free of all use restrictions,
|
||||
licenses and fees. AIM USA, its member companies, or individual officers
|
||||
assume no liability for the use of this document." */
|
||||
static void CHNCHR(int channels, int target_value, int B[8], int S[8]) {
|
||||
/* Use of initial pre-calculations taken from Barcode Writer in Pure PostScript (BWIPP)
|
||||
* Copyright (c) 2004-2020 Terry Burton (MIT/X-Consortium license) */
|
||||
static channel_precalc initial_precalcs[6] = {
|
||||
{ 0, { 1, 1, 1, 1, 1, 2, 1, 2, }, { 1, 1, 1, 1, 1, 1, 1, 3, }, { 1, 1, 1, 1, 1, 3, 2, },
|
||||
{ 1, 1, 1, 1, 1, 3, 3, }, },
|
||||
{ 0, { 1, 1, 1, 1, 2, 1, 1, 3, }, { 1, 1, 1, 1, 1, 1, 1, 4, }, { 1, 1, 1, 1, 4, 3, 3, },
|
||||
{ 1, 1, 1, 1, 4, 4, 4, }, },
|
||||
{ 0, { 1, 1, 1, 2, 1, 1, 2, 3, }, { 1, 1, 1, 1, 1, 1, 1, 5, }, { 1, 1, 1, 5, 4, 4, 4, },
|
||||
{ 1, 1, 1, 5, 5, 5, 5, }, },
|
||||
{ 0, { 1, 1, 2, 1, 1, 2, 1, 4, }, { 1, 1, 1, 1, 1, 1, 1, 6, }, { 1, 1, 6, 5, 5, 5, 4, },
|
||||
{ 1, 1, 6, 6, 6, 6, 6, }, },
|
||||
{ 0, { 1, 2, 1, 1, 2, 1, 1, 5, }, { 1, 1, 1, 1, 1, 1, 1, 7, }, { 1, 7, 6, 6, 6, 5, 5, },
|
||||
{ 1, 7, 7, 7, 7, 7, 7, }, },
|
||||
{ 0, { 2, 1, 1, 2, 1, 1, 2, 5, }, { 1, 1, 1, 1, 1, 1, 1, 8, }, { 8, 7, 7, 7, 6, 6, 6, },
|
||||
{ 8, 8, 8, 8, 8, 8, 8, }, },
|
||||
};
|
||||
int bmax[7], smax[7];
|
||||
int value = 0;
|
||||
|
||||
channel_copy_precalc(&initial_precalcs[channels - 3], B, S, bmax, smax);
|
||||
|
||||
#ifndef CHANNEL_GENERATE_PRECALCS
|
||||
if (channels == 7 && target_value >= channel_precalcs7[0].value) {
|
||||
value = channel_copy_precalc(&channel_precalcs7[(target_value / channel_precalcs7[0].value) - 1], B, S, bmax,
|
||||
smax);
|
||||
} else if (channels == 8 && target_value >= channel_precalcs8[0].value) {
|
||||
value = channel_copy_precalc(&channel_precalcs8[(target_value / channel_precalcs8[0].value) - 1], B, S, bmax,
|
||||
smax);
|
||||
}
|
||||
#endif
|
||||
|
||||
goto chkchr;
|
||||
|
||||
ls0:smax[1] = smax[0] + 1 - S[0]; B[0] = 1;
|
||||
if (S[0] == 1) goto nb0;
|
||||
lb0: bmax[1] = bmax[0] + 1 - B[0]; S[1] = 1;
|
||||
ls1: smax[2] = smax[1] + 1 - S[1]; B[1] = 1;
|
||||
if (S[0] + B[0] + S[1] == 3) goto nb1;
|
||||
lb1: bmax[2] = bmax[1] + 1 - B[1]; S[2] = 1;
|
||||
ls2: smax[3] = smax[2] + 1 - S[2]; B[2] = 1;
|
||||
if (B[0] + S[1] + B[1] + S[2] == 4) goto nb2;
|
||||
lb2: bmax[3] = bmax[2] + 1 - B[2]; S[3] = 1;
|
||||
ls3: smax[4] = smax[3] + 1 - S[3]; B[3] = 1;
|
||||
if (B[1] + S[2] + B[2] + S[3] == 4) goto nb3;
|
||||
lb3: bmax[4] = bmax[3] + 1 - B[3]; S[4] = 1;
|
||||
ls4: smax[5] = smax[4] + 1 - S[4]; B[4] = 1;
|
||||
if (B[2] + S[3] + B[3] + S[4] == 4) goto nb4;
|
||||
lb4: bmax[5] = bmax[4] + 1 - B[4]; S[5] = 1;
|
||||
ls5: smax[6] = smax[5] + 1 - S[5]; B[5] = 1;
|
||||
if (B[3] + S[4] + B[4] + S[5] == 4) goto nb5;
|
||||
lb5: bmax[6] = bmax[5] + 1 - B[5]; S[6] = 1;
|
||||
ls6: S[7] = smax[6] + 1 - S[6]; B[6] = 1;
|
||||
if (B[4] + S[5] + B[5] + S[6] == 4) goto nb6;
|
||||
lb6: B[7] = bmax[6] + 1 - B[6];
|
||||
if (B[5] + S[6] + B[6] + S[7] + B[7] == 5) goto nb6;
|
||||
chkchr:
|
||||
#ifdef CHANNEL_GENERATE_PRECALCS
|
||||
/* 115338 == (576688 + 2) / 5 */
|
||||
if (channels == 7 && value && value % 115338 == 0) {
|
||||
channel_generate_precalc(channels, value, 115338,
|
||||
115338 * (5 - 1), B, S, bmax, smax);
|
||||
/* 119121 == (7742862 + 3) / 65 */
|
||||
} else if (channels == 8 && value && value % 119121 == 0) {
|
||||
channel_generate_precalc(channels, value, 119121,
|
||||
119121 * (65 - 1), B, S, bmax, smax);
|
||||
}
|
||||
#endif
|
||||
if (value == target_value) return;
|
||||
value++;
|
||||
nb6: if (++B[6] <= bmax[6]) goto lb6;
|
||||
if (++S[6] <= smax[6]) goto ls6;
|
||||
nb5: if (++B[5] <= bmax[5]) goto lb5;
|
||||
if (++S[5] <= smax[5]) goto ls5;
|
||||
nb4: if (++B[4] <= bmax[4]) goto lb4;
|
||||
if (++S[4] <= smax[4]) goto ls4;
|
||||
nb3: if (++B[3] <= bmax[3]) goto lb3;
|
||||
if (++S[3] <= smax[3]) goto ls3;
|
||||
nb2: if (++B[2] <= bmax[2]) goto lb2;
|
||||
if (++S[2] <= smax[2]) goto ls2;
|
||||
nb1: if (++B[1] <= bmax[1]) goto lb1;
|
||||
if (++S[1] <= smax[1]) goto ls1;
|
||||
nb0: if (++B[0] <= bmax[0]) goto lb0;
|
||||
if (++S[0] <= smax[0]) goto ls0;
|
||||
}
|
||||
|
||||
/* Channel Code - According to ANSI/AIM BC12-1998 */
|
||||
INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
static const int max_ranges[] = { -1, -1, -1, 26, 292, 3493, 44072, 576688, 7742862 };
|
||||
int S[8] = {0}, B[8] = {0};
|
||||
int target_value;
|
||||
char dest[30];
|
||||
char *d = dest;
|
||||
int channels, i;
|
||||
int error_number = 0, zeroes;
|
||||
|
||||
if (length > 7) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 333, "Input length %d too long (maximum 7)", length);
|
||||
}
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 334,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
target_value = to_int(source, length);
|
||||
|
||||
if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) {
|
||||
channels = 0;
|
||||
} else {
|
||||
channels = symbol->option_2;
|
||||
}
|
||||
|
||||
if (channels == 0) {
|
||||
channels = length + 1;
|
||||
if (target_value > 576688 && channels < 8) {
|
||||
channels = 8;
|
||||
} else if (target_value > 44072 && channels < 7) {
|
||||
channels = 7;
|
||||
} else if (target_value > 3493 && channels < 6) {
|
||||
channels = 6;
|
||||
} else if (target_value > 292 && channels < 5) {
|
||||
channels = 5;
|
||||
} else if (target_value > 26 && channels < 4) {
|
||||
channels = 4;
|
||||
}
|
||||
}
|
||||
if (channels == 2) {
|
||||
channels = 3;
|
||||
}
|
||||
|
||||
if (target_value > max_ranges[channels]) {
|
||||
if (channels == 8) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 318, "Input value \"%1$d\" out of range (0 to %2$d)",
|
||||
target_value, max_ranges[channels]);
|
||||
}
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 335,
|
||||
"Input value \"%1$d\" out of range (0 to %2$d for %3$d channels)",
|
||||
target_value, max_ranges[channels], channels);
|
||||
}
|
||||
|
||||
CHNCHR(channels, target_value, B, S);
|
||||
|
||||
memcpy(d, "111111111", 9); /* Finder pattern */
|
||||
d += 9;
|
||||
for (i = 8 - channels; i < 8; i++) {
|
||||
*d++ = itoc(S[i]);
|
||||
*d++ = itoc(B[i]);
|
||||
}
|
||||
|
||||
zeroes = channels - 1 - length;
|
||||
if (zeroes < 0) {
|
||||
zeroes = 0;
|
||||
} else if (zeroes) {
|
||||
memset(symbol->text, '0', zeroes);
|
||||
}
|
||||
ustrcpy(symbol->text + zeroes, source);
|
||||
|
||||
expand(symbol, dest, d - dest);
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* ANSI/AIM BC12-1998 gives min height as 5mm or 15% of length; X left as application specification so use
|
||||
length = 1X (left qz) + (9 (finder) + 4 * 8 - 2) * X + 2X (right qz);
|
||||
use 20 as default based on figures in spec */
|
||||
const float min_height = stripf((1 + 9 + 4 * channels - 2 + 2) * 0.15f);
|
||||
error_number = set_height(symbol, min_height, 20.0f, 0.0f, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Vehicle Identification Number (VIN) */
|
||||
INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user