MAXICODE: scmvv option #212; postcode needn't be space-filled

This commit is contained in:
gitlost 2020-12-19 17:13:35 +00:00
parent 0ef9fdf684
commit 2b85585e69
23 changed files with 1703 additions and 378 deletions

View File

@ -36,7 +36,7 @@
#endif #endif
#include "common.h" #include "common.h"
/* Converts a character 0-9 to its equivalent integer value */ /* Converts a character 0-9, A-F to its equivalent integer value */
INTERNAL int ctoi(const char source) { INTERNAL int ctoi(const char source) {
if ((source >= '0') && (source <= '9')) if ((source >= '0') && (source <= '9'))
return (source - '0'); return (source - '0');
@ -47,32 +47,6 @@ INTERNAL int ctoi(const char source) {
return -1; return -1;
} }
/* Convert an integer value to a string representing its binary equivalent */
INTERNAL void bin_append(const int arg, const int length, char *binary) {
int posn = (int) strlen(binary);
bin_append_posn(arg, length, binary, posn);
binary[posn + length] = '\0';
}
/* Convert an integer value to a string representing its binary equivalent at a set position */
INTERNAL int bin_append_posn(const int arg, const int length, char *binary, int posn) {
int i;
int start;
start = 0x01 << (length - 1);
for (i = 0; i < length; i++) {
if (arg & (start >> i)) {
binary[posn + i] = '1';
} else {
binary[posn + i] = '0';
}
}
return posn + length;
}
/* Converts an integer value to its hexadecimal character */ /* Converts an integer value to its hexadecimal character */
INTERNAL char itoc(const int source) { INTERNAL char itoc(const int source) {
if ((source >= 0) && (source <= 9)) { if ((source >= 0) && (source <= 9)) {
@ -82,9 +56,25 @@ INTERNAL char itoc(const int source) {
} }
} }
/* Converts decimal string of length <= 9 to integer value. Returns -1 if not numeric */
INTERNAL int to_int(const unsigned char source[], const int length) {
int val = 0;
int i;
for (i = 0; i < length; i++) {
if (source[i] < '0' || source[i] > '9') {
return -1;
}
val *= 10;
val += source[i] - '0';
}
return val;
}
/* Converts lower case characters to upper case in a string source[] */ /* Converts lower case characters to upper case in a string source[] */
INTERNAL void to_upper(unsigned char source[]) { INTERNAL void to_upper(unsigned char source[]) {
size_t i, src_len = ustrlen(source); int i, src_len = (int) ustrlen(source);
for (i = 0; i < src_len; i++) { for (i = 0; i < src_len; i++) {
if ((source[i] >= 'a') && (source[i] <= 'z')) { if ((source[i] >= 'a') && (source[i] <= 'z')) {
@ -94,9 +84,8 @@ INTERNAL void to_upper(unsigned char source[]) {
} }
/* Verifies that a string only uses valid characters */ /* Verifies that a string only uses valid characters */
INTERNAL int is_sane(const char test_string[], const unsigned char source[], const size_t length) { INTERNAL int is_sane(const char test_string[], const unsigned char source[], const int length) {
unsigned int j; int i, j, lt = (int) strlen(test_string);
size_t i, lt = strlen(test_string);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
unsigned int latch = FALSE; unsigned int latch = FALSE;
@ -126,6 +115,32 @@ INTERNAL void lookup(const char set_string[], const char *table[], const char da
} }
} }
/* Convert an integer value to a string representing its binary equivalent */
INTERNAL void bin_append(const int arg, const int length, char *binary) {
int bin_posn = (int) strlen(binary);
bin_append_posn(arg, length, binary, bin_posn);
binary[bin_posn + length] = '\0';
}
/* Convert an integer value to a string representing its binary equivalent at a set position */
INTERNAL int bin_append_posn(const int arg, const int length, char *binary, const int bin_posn) {
int i;
int start;
start = 0x01 << (length - 1);
for (i = 0; i < length; i++) {
if (arg & (start >> i)) {
binary[bin_posn + i] = '1';
} else {
binary[bin_posn + i] = '0';
}
}
return bin_posn + length;
}
/* Returns the position of data in set_string */ /* Returns the position of data in set_string */
INTERNAL int posn(const char set_string[], const char data) { INTERNAL int posn(const char set_string[], const char data) {
int i, n = (int) strlen(set_string); int i, n = (int) strlen(set_string);
@ -219,6 +234,7 @@ INTERNAL int is_stackable(const int symbology) {
case BARCODE_CODABLOCKF: case BARCODE_CODABLOCKF:
case BARCODE_HIBC_BLOCKF: case BARCODE_HIBC_BLOCKF:
return 1; return 1;
break;
} }
return 0; return 0;
@ -239,6 +255,7 @@ INTERNAL int is_extendable(const int symbology) {
case BARCODE_UPCA_CC: case BARCODE_UPCA_CC:
case BARCODE_UPCE_CC: case BARCODE_UPCE_CC:
return 1; return 1;
break;
} }
return 0; return 0;
@ -249,6 +266,7 @@ INTERNAL int is_composite(const int symbology) {
return symbology >= BARCODE_EANX_CC && symbology <= BARCODE_DBAR_EXPSTK_CC; return symbology >= BARCODE_EANX_CC && symbology <= BARCODE_DBAR_EXPSTK_CC;
} }
/* Whether next two characters are digits */
INTERNAL int istwodigits(const unsigned char source[], const int length, const int position) { INTERNAL int istwodigits(const unsigned char source[], const int length, const int position) {
if ((position + 1 < length) && (source[position] >= '0') && (source[position] <= '9') if ((position + 1 < length) && (source[position] >= '0') && (source[position] <= '9')
&& (source[position + 1] >= '0') && (source[position + 1] <= '9')) { && (source[position + 1] >= '0') && (source[position + 1] <= '9')) {
@ -306,7 +324,7 @@ INTERNAL unsigned int decode_utf8(unsigned int *state, unsigned int *codep, cons
/* Convert UTF-8 to Unicode. If `disallow_4byte` unset, allow all values (UTF-32). If `disallow_4byte` set, /* Convert UTF-8 to Unicode. If `disallow_4byte` unset, allow all values (UTF-32). If `disallow_4byte` set,
* only allow codepoints <= U+FFFF (ie four-byte sequences not allowed) (UTF-16, no surrogates) */ * only allow codepoints <= U+FFFF (ie four-byte sequences not allowed) (UTF-16, no surrogates) */
INTERNAL int utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[], INTERNAL int utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[],
int *length, int disallow_4byte) { int *length, const int disallow_4byte) {
int bpos; int bpos;
int jpos; int jpos;
unsigned int codepoint, state = 0; unsigned int codepoint, state = 0;
@ -362,7 +380,8 @@ INTERNAL void set_minimum_height(struct zint_symbol *symbol, const int min_heigh
} }
} }
INTERNAL int colour_to_red(int colour) { /* Returns red component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_red(const int colour) {
int return_val = 0; int return_val = 0;
switch(colour) { switch(colour) {
@ -377,7 +396,8 @@ INTERNAL int colour_to_red(int colour) {
return return_val; return return_val;
} }
INTERNAL int colour_to_green(int colour) { /* Returns green component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_green(const int colour) {
int return_val = 0; int return_val = 0;
switch(colour) { switch(colour) {
@ -392,7 +412,8 @@ INTERNAL int colour_to_green(int colour) {
return return_val; return return_val;
} }
INTERNAL int colour_to_blue(int colour) { /* Returns blue component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_blue(const int colour) {
int return_val = 0; int return_val = 0;
switch(colour) { switch(colour) {
@ -409,7 +430,7 @@ INTERNAL int colour_to_blue(int colour) {
#ifdef ZINT_TEST #ifdef ZINT_TEST
/* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */ /* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */
void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char *codewords, int length) { void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length) {
int i, max = length, cnt_len = 0; int i, max = length, cnt_len = 0;
if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */ if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */
sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */ sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */
@ -422,7 +443,8 @@ void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char *codewor
symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */ symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */
} }
void debug_test_codeword_dump_int(struct zint_symbol *symbol, int *codewords, int length) { /* Dumps decimal-formatted codewords in symbol->errtxt (for use in testing) */
void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int *codewords, const int length) {
int i, max = 0, cnt_len, errtxt_len; int i, max = 0, cnt_len, errtxt_len;
char temp[20]; char temp[20];
errtxt_len = sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */ errtxt_len = sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */

View File

@ -90,11 +90,12 @@ extern "C" {
INTERNAL int ctoi(const char source); INTERNAL int ctoi(const char source);
INTERNAL char itoc(const int source); INTERNAL char itoc(const int source);
INTERNAL int to_int(const unsigned char source[], const int length);
INTERNAL void to_upper(unsigned char source[]); INTERNAL void to_upper(unsigned char source[]);
INTERNAL int is_sane(const char test_string[], const unsigned char source[], const size_t length); INTERNAL int is_sane(const char test_string[], const unsigned char source[], const int length);
INTERNAL void lookup(const char set_string[], const char *table[], const char data, char dest[]); INTERNAL void lookup(const char set_string[], const char *table[], const char data, char dest[]);
INTERNAL void bin_append(const int arg, const int length, char *binary); INTERNAL void bin_append(const int arg, const int length, char *binary);
INTERNAL int bin_append_posn(const int arg, const int length, char *binary, int posn); INTERNAL int bin_append_posn(const int arg, const int length, char *binary, const int bin_posn);
INTERNAL int posn(const char set_string[], const char data); INTERNAL int posn(const char set_string[], const char data);
#ifndef COMMON_INLINE #ifndef COMMON_INLINE
INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
@ -110,16 +111,16 @@ extern "C" {
INTERNAL int istwodigits(const unsigned char source[], const int length, const int position); INTERNAL int istwodigits(const unsigned char source[], const int length, const int position);
INTERNAL unsigned int decode_utf8(unsigned int *state, unsigned int *codep, const unsigned char byte); INTERNAL unsigned int decode_utf8(unsigned int *state, unsigned int *codep, const unsigned char byte);
INTERNAL int utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[], INTERNAL int utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[],
int *length, int disallow_4byte); int *length, const int disallow_4byte);
INTERNAL void set_minimum_height(struct zint_symbol *symbol, const int min_height); INTERNAL void set_minimum_height(struct zint_symbol *symbol, const int min_height);
INTERNAL int colour_to_red(int colour); INTERNAL int colour_to_red(const int colour);
INTERNAL int colour_to_green(int colour); INTERNAL int colour_to_green(const int colour);
INTERNAL int colour_to_blue(int colour); INTERNAL int colour_to_blue(const int colour);
#ifdef ZINT_TEST #ifdef ZINT_TEST
void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char *codewords, int length); void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length);
void debug_test_codeword_dump_int(struct zint_symbol *symbol, int *codewords, int length); void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int *codewords, const int length);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -32,13 +32,16 @@
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
/* Includes corrections thanks to Monica Swanson @ Source Technologies */ /* Includes corrections thanks to Monica Swanson @ Source Technologies */
#include <stdio.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#include "common.h" #include "common.h"
#include "maxicode.h" #include "maxicode.h"
#include "reedsol.h" #include "reedsol.h"
/* Handles error correction of primary message */ /* Handles error correction of primary message */
static void maxi_do_primary_check(int maxi_codeword[144]) { static void maxi_do_primary_check(unsigned char maxi_codeword[144]) {
unsigned char data[15];
unsigned char results[15]; unsigned char results[15];
int j; int j;
int datalen = 10; int datalen = 10;
@ -48,17 +51,14 @@ static void maxi_do_primary_check(int maxi_codeword[144]) {
rs_init_gf(&rs, 0x43); rs_init_gf(&rs, 0x43);
rs_init_code(&rs, ecclen, 1); rs_init_code(&rs, ecclen, 1);
for (j = 0; j < datalen; j += 1) rs_encode(&rs, datalen, maxi_codeword, results);
data[j] = maxi_codeword[j];
rs_encode(&rs, datalen, data, results);
for (j = 0; j < ecclen; j += 1) for (j = 0; j < ecclen; j += 1)
maxi_codeword[ datalen + j] = results[ecclen - 1 - j]; maxi_codeword[ datalen + j] = results[ecclen - 1 - j];
} }
/* Handles error correction of odd characters in secondary */ /* Handles error correction of odd characters in secondary */
static void maxi_do_secondary_chk_odd(int maxi_codeword[144], int ecclen) { static void maxi_do_secondary_chk_odd(unsigned char maxi_codeword[144], const int ecclen) {
unsigned char data[100]; unsigned char data[100];
unsigned char results[30]; unsigned char results[30];
int j; int j;
@ -71,9 +71,8 @@ static void maxi_do_secondary_chk_odd(int maxi_codeword[144], int ecclen) {
if (ecclen == 20) if (ecclen == 20)
datalen = 84; datalen = 84;
for (j = 0; j < datalen; j += 1) for (j = 1; j < datalen; j += 2)
if (j & 1) // odd data[(j - 1) / 2] = maxi_codeword[j + 20];
data[(j - 1) / 2] = maxi_codeword[j + 20];
rs_encode(&rs, datalen / 2, data, results); rs_encode(&rs, datalen / 2, data, results);
@ -82,7 +81,7 @@ static void maxi_do_secondary_chk_odd(int maxi_codeword[144], int ecclen) {
} }
/* Handles error correction of even characters in secondary */ /* Handles error correction of even characters in secondary */
static void maxi_do_secondary_chk_even(int maxi_codeword[144], int ecclen) { static void maxi_do_secondary_chk_even(unsigned char maxi_codeword[144], const int ecclen) {
unsigned char data[100]; unsigned char data[100];
unsigned char results[30]; unsigned char results[30];
int j; int j;
@ -95,9 +94,8 @@ static void maxi_do_secondary_chk_even(int maxi_codeword[144], int ecclen) {
rs_init_gf(&rs, 0x43); rs_init_gf(&rs, 0x43);
rs_init_code(&rs, ecclen, 1); rs_init_code(&rs, ecclen, 1);
for (j = 0; j < datalen + 1; j += 1) for (j = 0; j < datalen + 1; j += 2)
if (!(j & 1)) // even data[j / 2] = maxi_codeword[j + 20];
data[j / 2] = maxi_codeword[j + 20];
rs_encode(&rs, datalen / 2, data, results); rs_encode(&rs, datalen / 2, data, results);
@ -106,63 +104,75 @@ static void maxi_do_secondary_chk_even(int maxi_codeword[144], int ecclen) {
} }
/* Moves everything up so that a shift or latch can be inserted */ /* Moves everything up so that a shift or latch can be inserted */
static void maxi_bump(int set[], int character[], int bump_posn) { static void maxi_bump(unsigned char set[], unsigned char character[], const int bump_posn) {
int i;
for (i = 143; i > bump_posn; i--) { memmove(set + bump_posn + 1, set + bump_posn, 143 - bump_posn);
set[i] = set[i - 1]; memmove(character + bump_posn + 1, character + bump_posn, 143 - bump_posn);
character[i] = character[i - 1];
}
} }
/* If the value is present in array, return the value, else return badvalue */ /* If the value is present in array, return the value, else return badvalue */
static int value_in_array(int val, int arr[], int badvalue, int arrLength) { static int value_in_array(const unsigned char val, const unsigned char arr[], const int badvalue, const int arrLength) {
int i; int i;
for(i = 0; i < arrLength; i++){ for (i = 0; i < arrLength; i++) {
if(arr[i] == val) return val; if (arr[i] == val) return val;
} }
return badvalue; return badvalue;
} }
/* Choose the best set from previous and next set in the range of the setval array, if no value can be found we return setval[0] */ /* Choose the best set from previous and next set in the range of the setval array, if no value can be found we
static int bestSurroundingSet(int index, int length, int set[], int setval[], int setLength) { * return setval[0] */
static int bestSurroundingSet(const int index, const int length, const unsigned char set[], const unsigned char setval[],
const int setLength) {
int badValue = -1; int badValue = -1;
int option1 = value_in_array(set[index - 1], setval, badValue, setLength); int option1 = value_in_array(set[index - 1], setval, badValue, setLength);
if (index + 1 < length) { if (index + 1 < length) {
// we have two options to check (previous & next) // we have two options to check (previous & next)
int option2 = value_in_array(set[index + 1], setval, badValue, setLength); int option2 = value_in_array(set[index + 1], setval, badValue, setLength);
if (option2 != badValue && option1 > option2) { if (option2 != badValue && option1 > option2) {
return option2; return option2;
} }
} }
//
if (option1 != badValue) { if (option1 != badValue) {
return option1; return option1;
} }
return setval[0]; return setval[0];
} }
/* Format text according to Appendix A */ /* Format text according to Appendix A */
static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char source[], int length, int eci) { static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, const unsigned char in_source[], int length,
/* This code doesn't make use of [Lock in C], [Lock in D] const int eci, const int scm_vv) {
and [Lock in E] and so is not always the most efficient at
compressing data, but should suffice for most applications */
int set[144], character[144], i, j, done, count, current_set; unsigned char set[144], character[144] = {0};
int i, count, current_set, padding_set;
int set15[2] = { 1, 5 }; static const unsigned char set15[2] = { 1, 5 };
int set12[2] = { 1, 2 }; static const unsigned char set12[2] = { 1, 2 };
int set12345[5] = { 1, 2, 3, 4, 5 }; static const unsigned char set12345[5] = { 1, 2, 3, 4, 5 };
if (length > 138) { const unsigned char *source = in_source;
#ifndef _MSC_VER
unsigned char source_buf[length + 9]; /* For prefixing 9-character SCM sequence */
#else
unsigned char *source_buf = (unsigned char *) _alloca(length + 9);
#endif
if (length > 144) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
for (i = 0; i < 144; i++) { if (scm_vv != -1) { /* Add SCM prefix */
set[i] = -1; if (length > 135) {
character[i] = 0; return ZINT_ERROR_TOO_LONG;
}
sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */
memcpy(source_buf + 9, in_source, length);
source = source_buf;
length += 9;
} }
memset(set, 255, 144);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
/* Look up characters in table from Appendix A - this gives /* Look up characters in table from Appendix A - this gives
value and code set for most characters */ value and code set for most characters */
@ -181,7 +191,6 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
for (i = 1; i < length; i++) { for (i = 1; i < length; i++) {
if (set[i] == 0) { if (set[i] == 0) {
done = 0;
/* Special character */ /* Special character */
if (character[i] == 13) { if (character[i] == 13) {
/* Carriage Return */ /* Carriage Return */
@ -191,37 +200,29 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
} else { } else {
character[i] = 0; character[i] = 0;
} }
done = 1;
}
if ((done == 0) && (character[i] == 28)) { } else if (character[i] == 28) {
/* FS */ /* FS */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[i] = bestSurroundingSet(i, length, set, set12345, 5);
if (set[i] == 5) { if (set[i] == 5) {
character[i] = 32; character[i] = 32;
} }
done = 1;
}
if ((done == 0) && (character[i] == 29)) { } else if (character[i] == 29) {
/* GS */ /* GS */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[i] = bestSurroundingSet(i, length, set, set12345, 5);
if (set[i] == 5) { if (set[i] == 5) {
character[i] = 33; character[i] = 33;
} }
done = 1;
}
if ((done == 0) && (character[i] == 30)) { } else if (character[i] == 30) {
/* RS */ /* RS */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[i] = bestSurroundingSet(i, length, set, set12345, 5);
if (set[i] == 5) { if (set[i] == 5) {
character[i] = 34; character[i] = 34;
} }
done = 1;
}
if ((done == 0) && (character[i] == 32)) { } else if (character[i] == 32) {
/* Space */ /* Space */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[i] = bestSurroundingSet(i, length, set, set12345, 5);
if (set[i] == 1) { if (set[i] == 1) {
@ -231,85 +232,61 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
} else { } else {
character[i] = 59; character[i] = 59;
} }
done = 1;
}
if ((done == 0) && (character[i] == 44)) { } else if (character[i] == 44) {
/* Comma */ /* Comma */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[i] = bestSurroundingSet(i, length, set, set12, 2);
if (set[i] == 2) { if (set[i] == 2) {
character[i] = 48; character[i] = 48;
} }
done = 1;
}
if ((done == 0) && (character[i] == 46)) { } else if (character[i] == 46) {
/* Full Stop */ /* Full Stop */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[i] = bestSurroundingSet(i, length, set, set12, 2);
if (set[i] == 2) { if (set[i] == 2) {
character[i] = 49; character[i] = 49;
} }
done = 1;
}
if ((done == 0) && (character[i] == 47)) { } else if (character[i] == 47) {
/* Slash */ /* Slash */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[i] = bestSurroundingSet(i, length, set, set12, 2);
if (set[i] == 2) { if (set[i] == 2) {
character[i] = 50; character[i] = 50;
} }
done = 1;
}
if ((done == 0) && (character[i] == 58)) { } else if (character[i] == 58) {
/* Colon */ /* Colon */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[i] = bestSurroundingSet(i, length, set, set12, 2);
if (set[i] == 2) { if (set[i] == 2) {
character[i] = 51; character[i] = 51;
} }
// done = 1 // As long as last branch not needed
} }
} }
} }
padding_set = set[length - 1] == 2 ? 2 : 1;
for (i = length; i < 144; i++) { for (i = length; i < 144; i++) {
/* Add the padding */ /* Add the padding */
if (set[length - 1] == 2) { set[i] = padding_set;
set[i] = 2;
} else {
set[i] = 1;
}
character[i] = 33; character[i] = 33;
} }
/* Find candidates for number compression */ /* Find candidates for number compression */
if ((mode == 2) || (mode == 3)) { /* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1)
j = 0; applies to modes 2 & 3 only */
} else {
j = 9;
}
/* Number compression not allowed in primary message */
count = 0; count = 0;
for (i = j; i < 144; i++) { for (i = 0; i < 144; i++) {
if ((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) { if ((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) {
/* Character is a number */ /* Character is a number */
count++; count++;
if (count == 9) {
/* Nine digits in a row can be compressed */
memset(set + i - 8, 6, 9);
count = 0;
}
} else { } else {
count = 0; count = 0;
} }
if (count == 9) {
/* Nine digits in a row can be compressed */
set[i] = 6;
set[i - 1] = 6;
set[i - 2] = 6;
set[i - 3] = 6;
set[i - 4] = 6;
set[i - 5] = 6;
set[i - 6] = 6;
set[i - 7] = 6;
set[i - 8] = 6;
count = 0;
}
} }
/* Add shift and latch characters */ /* Add shift and latch characters */
@ -320,9 +297,9 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
if ((set[i] != current_set) && (set[i] != 6)) { if ((set[i] != current_set) && (set[i] != 6)) {
switch (set[i]) { switch (set[i]) {
case 1: case 1:
if (i+1 < 144 && set[i + 1] == 1) { if (i + 1 < 144 && set[i + 1] == 1) {
if (i+2 < 144 && set[i + 2] == 1) { if (i + 2 < 144 && set[i + 2] == 1) {
if (i+3 < 144 && set[i + 3] == 1) { if (i + 3 < 144 && set[i + 3] == 1) {
/* Latch A */ /* Latch A */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 63; character[i] = 63;
@ -350,7 +327,7 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
} }
break; break;
case 2: case 2:
if (i+1 < 144 && set[i + 1] == 2) { if (i + 1 < 144 && set[i + 1] == 2) {
/* Latch B */ /* Latch B */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 63; character[i] = 63;
@ -365,6 +342,7 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
break; break;
case 3: case 3:
if (i + 3 < 144 && set[i + 1] == 3 && set[i + 2] == 3 && set[i + 3] == 3) { if (i + 3 < 144 && set[i + 1] == 3 && set[i + 2] == 3 && set[i + 3] == 3) {
/* Lock in C */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 60; character[i] = 60;
maxi_bump(set, character, i); maxi_bump(set, character, i);
@ -380,8 +358,8 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
} }
break; break;
case 4: case 4:
/* Shift D */
if (i + 3 < 144 && set[i + 1] == 4 && set[i + 2] == 4 && set[i + 3] == 4) { if (i + 3 < 144 && set[i + 1] == 4 && set[i + 2] == 4 && set[i + 3] == 4) {
/* Lock in D */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 61; character[i] = 61;
maxi_bump(set, character, i); maxi_bump(set, character, i);
@ -390,14 +368,15 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
length++; length++;
i += 3; i += 3;
} else { } else {
/* Shift D */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 61; character[i] = 61;
length++; length++;
} }
break; break;
case 5: case 5:
/* Shift E */
if (i + 3 < 144 && set[i + 1] == 5 && set[i + 2] == 5 && set[i + 3] == 5) { if (i + 3 < 144 && set[i + 1] == 5 && set[i + 2] == 5 && set[i + 3] == 5) {
/* Lock in E */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 62; character[i] = 62;
maxi_bump(set, character, i); maxi_bump(set, character, i);
@ -406,10 +385,11 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
length++; length++;
i += 3; i += 3;
} else { } else {
/* Shift E */
maxi_bump(set, character, i); maxi_bump(set, character, i);
character[i] = 62; character[i] = 62;
length++; length++;
} }
break; break;
} }
i++; i++;
@ -422,14 +402,7 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
do { do {
if (set[i] == 6) { if (set[i] == 6) {
/* Number compression */ /* Number compression */
char substring[10]; int value = to_int(character + i, 9);
int value;
for (j = 0; j < 9; j++) {
substring[j] = character[i + j];
}
substring[9] = '\0';
value = atoi(substring);
character[i] = 31; /* NS */ character[i] = 31; /* NS */
character[i + 1] = (value & 0x3f000000) >> 24; character[i + 1] = (value & 0x3f000000) >> 24;
@ -439,10 +412,8 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
character[i + 5] = (value & 0x3f); character[i + 5] = (value & 0x3f);
i += 6; i += 6;
for (j = i; j < 141; j++) { memmove(set + i, set + i + 3, 141 - i);
set[j] = set[j + 3]; memmove(character + i, character + i + 3, 141 - i);
character[j] = character[j + 3];
}
length -= 3; length -= 3;
} else { } else {
i++; i++;
@ -458,15 +429,13 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
character[1] = eci; character[1] = eci;
length += 2; length += 2;
} } else if (eci <= 1023) {
if ((eci >= 32) && (eci <= 1023)) {
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
character[1] = 0x20 + ((eci >> 6) & 0x0F); character[1] = 0x20 + ((eci >> 6) & 0x0F);
character[2] = eci & 0x3F; character[2] = eci & 0x3F;
length += 3; length += 3;
} } else if (eci <= 32767) {
if ((eci >= 1024) && (eci <= 32767)) {
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
@ -474,8 +443,7 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
character[2] = (eci >> 6) & 0x3F; character[2] = (eci >> 6) & 0x3F;
character[3] = eci & 0x3F; character[3] = eci & 0x3F;
length += 4; length += 4;
} } else {
if (eci >= 32768) {
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
maxi_bump(set, character, 1); maxi_bump(set, character, 1);
@ -490,34 +458,29 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
if (((mode == 2) || (mode == 3)) && (length > 84)) { if (((mode == 2) || (mode == 3)) && (length > 84)) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
}
if (((mode == 4) || (mode == 6)) && (length > 93)) { } else if (((mode == 4) || (mode == 6)) && (length > 93)) {
return ZINT_ERROR_TOO_LONG;
} else if ((mode == 5) && (length > 77)) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
if ((mode == 5) && (length > 77)) {
return ZINT_ERROR_TOO_LONG;
}
/* Copy the encoded text into the codeword array */ /* Copy the encoded text into the codeword array */
if ((mode == 2) || (mode == 3)) { if ((mode == 2) || (mode == 3)) {
for (i = 0; i < 84; i++) { /* secondary only */ for (i = 0; i < 84; i++) { /* secondary only */
maxi_codeword[i + 20] = character[i]; maxi_codeword[i + 20] = character[i];
} }
}
if ((mode == 4) || (mode == 6)) { } else if ((mode == 4) || (mode == 6)) {
for (i = 0; i < 9; i++) { /* primary */ for (i = 0; i < 9; i++) { /* primary */
maxi_codeword[i + 1] = character[i]; maxi_codeword[i + 1] = character[i];
} }
for (i = 0; i < 84; i++) { /* secondary */ for (i = 0; i < 84; i++) { /* secondary */
maxi_codeword[i + 20] = character[i + 9]; maxi_codeword[i + 20] = character[i + 9];
} }
}
if (mode == 5) { } else { /* Mode 5 */
for (i = 0; i < 9; i++) { /* primary */ for (i = 0; i < 9; i++) { /* primary */
maxi_codeword[i + 1] = character[i]; maxi_codeword[i + 1] = character[i];
} }
@ -530,18 +493,11 @@ static int maxi_text_process(int maxi_codeword[144], int mode, unsigned char sou
} }
/* Format structured primary for Mode 2 */ /* Format structured primary for Mode 2 */
static void maxi_do_primary_2(int maxi_codeword[144], char postcode[], int country, int service) { static void maxi_do_primary_2(unsigned char maxi_codeword[144], const unsigned char postcode[], const int postcode_length,
size_t postcode_length; const int country, const int service) {
int postcode_num, i; int postcode_num;
for (i = 0; i < 10; i++) { postcode_num = atoi((const char *) postcode);
if ((postcode[i] < '0') || (postcode[i] > '9')) {
postcode[i] = '\0';
}
}
postcode_length = strlen(postcode);
postcode_num = atoi(postcode);
maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2; maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2;
maxi_codeword[1] = ((postcode_num & 0xfc) >> 2); maxi_codeword[1] = ((postcode_num & 0xfc) >> 2);
@ -556,22 +512,13 @@ static void maxi_do_primary_2(int maxi_codeword[144], char postcode[], int count
} }
/* Format structured primary for Mode 3 */ /* Format structured primary for Mode 3 */
static void maxi_do_primary_3(int maxi_codeword[144], char postcode[], int country, int service) { static void maxi_do_primary_3(unsigned char maxi_codeword[144], unsigned char postcode[], const int country,
int i, h; const int service) {
int i;
h = strlen(postcode); /* Convert to Code Set A */
to_upper((unsigned char*) postcode); for (i = 0; i < 6; i++) {
for (i = 0; i < h; i++) { postcode[i] = maxiSymbolChar[postcode[i]];
if ((postcode[i] >= 'A') && (postcode[i] <= 'Z')) {
/* (Capital) letters shifted to Code Set A values */
postcode[i] -= 64;
}
if (((postcode[i] == 27) || (postcode[i] == 31)) || ((postcode[i] == 33) || (postcode[i] >= 59))) {
/* Not a valid postcode character */
postcode[i] = ' ';
}
/* Input characters lower than 27 (NUL - SUB) in postcode are
interpreted as capital letters in Code Set A (e.g. LF becomes 'J') */
} }
maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3; maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3;
@ -586,25 +533,26 @@ static void maxi_do_primary_3(int maxi_codeword[144], char postcode[], int count
maxi_codeword[9] = ((service & 0x3f0) >> 4); maxi_codeword[9] = ((service & 0x3f0) >> 4);
} }
INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char local_source[], const int length) { INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) {
int i, j, block, bit, mode, lp = 0; int i, j, block, shift, mode, lp = 0;
int bit_pattern[7], error_number = 0, eclen; int error_number = 0, eclen;
int maxi_codeword[144] = {0}; unsigned char maxi_codeword[144] = {0};
char postcode[12], countrystr[4], servicestr[4]; int scm_vv = -1;
mode = symbol->option_1; mode = symbol->option_1;
strcpy(postcode, "");
strcpy(countrystr, "");
strcpy(servicestr, "");
if (mode == -1) { /* If mode is unspecified */ if (mode <= 0) { /* If mode is unspecified (-1) or to be auto-determined (0) between 2 and 3 */
lp = strlen(symbol->primary); lp = (int) strlen(symbol->primary);
if (lp == 0) { if (lp == 0) {
if (mode == 0) { /* Require primary message to auto-determine between 2 and 3 */
strcpy(symbol->errtxt, "554: Primary Message empty");
return ZINT_ERROR_INVALID_DATA;
}
mode = 4; mode = 4;
} else { } else {
mode = 2; mode = 2;
for (i = 0; i < 10 && i < lp; i++) { for (i = 0; i < lp - 6; i++) {
if ((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) { if (((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) && (symbol->primary[i] != ' ')) {
mode = 3; mode = 3;
break; break;
} }
@ -613,65 +561,85 @@ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char local_source[],
} }
if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */ if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */
strcpy(symbol->errtxt, "550: Invalid Maxicode Mode"); strcpy(symbol->errtxt, "550: Invalid MaxiCode Mode");
return ZINT_ERROR_INVALID_OPTION; return ZINT_ERROR_INVALID_OPTION;
} }
if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */ if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */
unsigned char postcode[10];
int countrycode; int countrycode;
int service; int service;
int postcode_len;
if (lp == 0) { /* Mode set manually means lp doesn't get set */ if (lp == 0) { /* Mode set manually means lp doesn't get set */
lp = strlen(symbol->primary); lp = (int) strlen(symbol->primary);
} }
if (lp != 15) { if (lp < 7 || lp > 15) { /* 1 to 9 character postcode + 3 digit country code + 3 digit service class */
strcpy(symbol->errtxt, "551: Invalid Primary Message"); strcpy(symbol->errtxt, "551: Invalid length for Primary Message");
return ZINT_ERROR_INVALID_DATA;
}
postcode_len = lp - 6;
countrycode = to_int((const unsigned char *) (symbol->primary + postcode_len), 3);
service = to_int((const unsigned char *) (symbol->primary + postcode_len + 3), 3);
if (countrycode == -1 || service == -1) { /* check that country code and service are numeric */
strcpy(symbol->errtxt, "552: Non-numeric country code or service class in Primary Message");
return ZINT_ERROR_INVALID_DATA; return ZINT_ERROR_INVALID_DATA;
} }
for (i = 9; i < 15; i++) { /* check that country code and service are numeric */ memcpy(postcode, symbol->primary, postcode_len);
if ((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) { postcode[postcode_len] = '\0';
strcpy(symbol->errtxt, "552: Invalid Primary Message");
return ZINT_ERROR_INVALID_DATA;
}
}
memcpy(postcode, symbol->primary, 9);
postcode[9] = '\0';
if (mode == 2) { if (mode == 2) {
for (i = 0; i < 10; i++) { for (i = 0; i < postcode_len; i++) {
if (postcode[i] == ' ') { if (postcode[i] == ' ') {
postcode[i] = '\0'; postcode[i] = '\0';
postcode_len = i;
break;
} else if (postcode[i] < '0' || postcode[i] > '9') {
strcpy(symbol->errtxt, "555: Non-numeric postcode in Primary Message");
return ZINT_ERROR_INVALID_DATA;
} }
} }
} else if (mode == 3) { maxi_do_primary_2(maxi_codeword, postcode, postcode_len, countrycode, service);
} else {
/* Just truncate and space-pad */
postcode[6] = '\0'; postcode[6] = '\0';
} for (i = postcode_len; i < 6; i++) {
postcode[i] = ' ';
countrystr[0] = symbol->primary[9]; }
countrystr[1] = symbol->primary[10]; /* Upper-case and check for Code Set A characters only */
countrystr[2] = symbol->primary[11]; to_upper(postcode);
countrystr[3] = '\0'; for (i = 0; i < 6; i++) {
/* Don't allow Code Set A control characters CR, RS, GS and RS */
servicestr[0] = symbol->primary[12]; if (postcode[i] < ' ' || maxiCodeSet[postcode[i]] > 1) {
servicestr[1] = symbol->primary[13]; strcpy(symbol->errtxt, "556: Invalid characters in postcode in Primary Message");
servicestr[2] = symbol->primary[14]; return ZINT_ERROR_INVALID_DATA;
servicestr[3] = '\0'; }
}
countrycode = atoi(countrystr);
service = atoi(servicestr);
if (mode == 2) {
maxi_do_primary_2(maxi_codeword, postcode, countrycode, service);
}
if (mode == 3) {
maxi_do_primary_3(maxi_codeword, postcode, countrycode, service); maxi_do_primary_3(maxi_codeword, postcode, countrycode, service);
} }
if (symbol->option_2) { /* Check for option_2 = vv + 1, where vv is version of SCM prefix "[)>\R01\Gvv" */
if (symbol->option_2 < 0 || symbol->option_2 > 100) {
strcpy(symbol->errtxt, "557: Invalid SCM prefix version");
return ZINT_ERROR_INVALID_OPTION;
}
scm_vv = symbol->option_2 - 1;
}
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Postcode: %s, Country Code: %d, Service Class: %d\n", postcode, countrycode, service);
}
} else { } else {
maxi_codeword[0] = mode; maxi_codeword[0] = mode;
} }
i = maxi_text_process(maxi_codeword, mode, local_source, length, symbol->eci); if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Mode: %d\n", mode);
}
i = maxi_text_process(maxi_codeword, mode, source, length, symbol->eci, scm_vv);
if (i == ZINT_ERROR_TOO_LONG) { if (i == ZINT_ERROR_TOO_LONG) {
strcpy(symbol->errtxt, "553: Input data too long"); strcpy(symbol->errtxt, "553: Input data too long");
return i; return i;
@ -688,22 +656,26 @@ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char local_source[],
maxi_do_secondary_chk_even(maxi_codeword, eclen / 2); // do error correction of even maxi_do_secondary_chk_even(maxi_codeword, eclen / 2); // do error correction of even
maxi_do_secondary_chk_odd(maxi_codeword, eclen / 2); // do error correction of odd maxi_do_secondary_chk_odd(maxi_codeword, eclen / 2); // do error correction of odd
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Codewords:");
for (i = 0; i < 144; i++) printf(" %d", maxi_codeword[i]);
printf("\n");
}
#ifdef ZINT_TEST
if (symbol->debug & ZINT_DEBUG_TEST) {
debug_test_codeword_dump(symbol, maxi_codeword, 144);
}
#endif
/* Copy data into symbol grid */ /* Copy data into symbol grid */
for (i = 0; i < 33; i++) { for (i = 0; i < 33; i++) {
for (j = 0; j < 30; j++) { for (j = 0; j < 30; j++) {
block = (MaxiGrid[(i * 30) + j] + 5) / 6; block = (MaxiGrid[(i * 30) + j] + 5) / 6;
bit = (MaxiGrid[(i * 30) + j] + 5) % 6;
if (block != 0) { if (block != 0) {
shift = 5 - ((MaxiGrid[(i * 30) + j] + 5) % 6);
bit_pattern[0] = (maxi_codeword[block - 1] & 0x20) >> 5; if ((maxi_codeword[block - 1] >> shift) & 0x1) {
bit_pattern[1] = (maxi_codeword[block - 1] & 0x10) >> 4;
bit_pattern[2] = (maxi_codeword[block - 1] & 0x8) >> 3;
bit_pattern[3] = (maxi_codeword[block - 1] & 0x4) >> 2;
bit_pattern[4] = (maxi_codeword[block - 1] & 0x2) >> 1;
bit_pattern[5] = (maxi_codeword[block - 1] & 0x1);
if (bit_pattern[bit] != 0) {
set_module(symbol, i, j); set_module(symbol, i, j);
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

View File

@ -0,0 +1,376 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: Zint 2.9.1.9
%%Title: Zint Generated Symbol
%%Pages: 0
%%BoundingBox: 0 0 74 72
%%EndComments
/TL { setlinewidth moveto lineto stroke } bind def
/TD { newpath 0 360 arc fill } bind def
/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def
/TB { 2 copy } bind def
/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def
/TE { pop pop } bind def
newpath
1.00 1.00 1.00 setrgbcolor
72.00 0.00 TB 0.00 74.00 TR
TE
0.00 0.00 0.00 setrgbcolor
3.69 71.57 4.56 71.07 4.56 70.07 3.69 69.57 2.82 70.07 2.82 71.07 TH
6.15 71.57 7.02 71.07 7.02 70.07 6.15 69.57 5.28 70.07 5.28 71.07 TH
8.61 71.57 9.48 71.07 9.48 70.07 8.61 69.57 7.74 70.07 7.74 71.07 TH
11.07 71.57 11.94 71.07 11.94 70.07 11.07 69.57 10.20 70.07 10.20 71.07 TH
13.53 71.57 14.40 71.07 14.40 70.07 13.53 69.57 12.66 70.07 12.66 71.07 TH
18.45 71.57 19.32 71.07 19.32 70.07 18.45 69.57 17.58 70.07 17.58 71.07 TH
35.67 71.57 36.54 71.07 36.54 70.07 35.67 69.57 34.80 70.07 34.80 71.07 TH
50.43 71.57 51.30 71.07 51.30 70.07 50.43 69.57 49.56 70.07 49.56 71.07 TH
60.27 71.57 61.14 71.07 61.14 70.07 60.27 69.57 59.40 70.07 59.40 71.07 TH
67.65 71.57 68.52 71.07 68.52 70.07 67.65 69.57 66.78 70.07 66.78 71.07 TH
70.11 71.57 70.98 71.07 70.98 70.07 70.11 69.57 69.24 70.07 69.24 71.07 TH
72.57 71.57 73.44 71.07 73.44 70.07 72.57 69.57 71.70 70.07 71.70 71.07 TH
9.84 69.44 10.71 68.94 10.71 67.94 9.84 67.44 8.97 67.94 8.97 68.94 TH
29.52 69.44 30.39 68.94 30.39 67.94 29.52 67.44 28.65 67.94 28.65 68.94 TH
51.66 69.44 52.53 68.94 52.53 67.94 51.66 67.44 50.79 67.94 50.79 68.94 TH
56.58 69.44 57.45 68.94 57.45 67.94 56.58 67.44 55.71 67.94 55.71 68.94 TH
6.15 67.30 7.02 66.80 7.02 65.80 6.15 65.30 5.28 65.80 5.28 66.80 TH
11.07 67.30 11.94 66.80 11.94 65.80 11.07 65.30 10.20 65.80 10.20 66.80 TH
13.53 67.30 14.40 66.80 14.40 65.80 13.53 65.30 12.66 65.80 12.66 66.80 TH
20.91 67.30 21.78 66.80 21.78 65.80 20.91 65.30 20.04 65.80 20.04 66.80 TH
23.37 67.30 24.24 66.80 24.24 65.80 23.37 65.30 22.50 65.80 22.50 66.80 TH
30.75 67.30 31.62 66.80 31.62 65.80 30.75 65.30 29.88 65.80 29.88 66.80 TH
38.13 67.30 39.00 66.80 39.00 65.80 38.13 65.30 37.26 65.80 37.26 66.80 TH
40.59 67.30 41.46 66.80 41.46 65.80 40.59 65.30 39.72 65.80 39.72 66.80 TH
45.51 67.30 46.38 66.80 46.38 65.80 45.51 65.30 44.64 65.80 44.64 66.80 TH
47.97 67.30 48.84 66.80 48.84 65.80 47.97 65.30 47.10 65.80 47.10 66.80 TH
55.35 67.30 56.22 66.80 56.22 65.80 55.35 65.30 54.48 65.80 54.48 66.80 TH
62.73 67.30 63.60 66.80 63.60 65.80 62.73 65.30 61.86 65.80 61.86 66.80 TH
70.11 67.30 70.98 66.80 70.98 65.80 70.11 65.30 69.24 65.80 69.24 66.80 TH
2.46 65.17 3.33 64.67 3.33 63.67 2.46 63.17 1.59 63.67 1.59 64.67 TH
19.68 65.17 20.55 64.67 20.55 63.67 19.68 63.17 18.81 63.67 18.81 64.67 TH
29.52 65.17 30.39 64.67 30.39 63.67 29.52 63.17 28.65 63.67 28.65 64.67 TH
31.98 65.17 32.85 64.67 32.85 63.67 31.98 63.17 31.11 63.67 31.11 64.67 TH
41.82 65.17 42.69 64.67 42.69 63.67 41.82 63.17 40.95 63.67 40.95 64.67 TH
49.20 65.17 50.07 64.67 50.07 63.67 49.20 63.17 48.33 63.67 48.33 64.67 TH
6.15 63.03 7.02 62.53 7.02 61.53 6.15 61.03 5.28 61.53 5.28 62.53 TH
11.07 63.03 11.94 62.53 11.94 61.53 11.07 61.03 10.20 61.53 10.20 62.53 TH
13.53 63.03 14.40 62.53 14.40 61.53 13.53 61.03 12.66 61.53 12.66 62.53 TH
30.75 63.03 31.62 62.53 31.62 61.53 30.75 61.03 29.88 61.53 29.88 62.53 TH
35.67 63.03 36.54 62.53 36.54 61.53 35.67 61.03 34.80 61.53 34.80 62.53 TH
50.43 63.03 51.30 62.53 51.30 61.53 50.43 61.03 49.56 61.53 49.56 62.53 TH
55.35 63.03 56.22 62.53 56.22 61.53 55.35 61.03 54.48 61.53 54.48 62.53 TH
60.27 63.03 61.14 62.53 61.14 61.53 60.27 61.03 59.40 61.53 59.40 62.53 TH
62.73 63.03 63.60 62.53 63.60 61.53 62.73 61.03 61.86 61.53 61.86 62.53 TH
70.11 63.03 70.98 62.53 70.98 61.53 70.11 61.03 69.24 61.53 69.24 62.53 TH
72.57 63.03 73.44 62.53 73.44 61.53 72.57 61.03 71.70 61.53 71.70 62.53 TH
2.46 60.90 3.33 60.40 3.33 59.40 2.46 58.90 1.59 59.40 1.59 60.40 TH
4.92 60.90 5.79 60.40 5.79 59.40 4.92 58.90 4.05 59.40 4.05 60.40 TH
7.38 60.90 8.25 60.40 8.25 59.40 7.38 58.90 6.51 59.40 6.51 60.40 TH
12.30 60.90 13.17 60.40 13.17 59.40 12.30 58.90 11.43 59.40 11.43 60.40 TH
22.14 60.90 23.01 60.40 23.01 59.40 22.14 58.90 21.27 59.40 21.27 60.40 TH
36.90 60.90 37.77 60.40 37.77 59.40 36.90 58.90 36.03 59.40 36.03 60.40 TH
41.82 60.90 42.69 60.40 42.69 59.40 41.82 58.90 40.95 59.40 40.95 60.40 TH
44.28 60.90 45.15 60.40 45.15 59.40 44.28 58.90 43.41 59.40 43.41 60.40 TH
51.66 60.90 52.53 60.40 52.53 59.40 51.66 58.90 50.79 59.40 50.79 60.40 TH
61.50 60.90 62.37 60.40 62.37 59.40 61.50 58.90 60.63 59.40 60.63 60.40 TH
63.96 60.90 64.83 60.40 64.83 59.40 63.96 58.90 63.09 59.40 63.09 60.40 TH
66.42 60.90 67.29 60.40 67.29 59.40 66.42 58.90 65.55 59.40 65.55 60.40 TH
68.88 60.90 69.75 60.40 69.75 59.40 68.88 58.90 68.01 59.40 68.01 60.40 TH
1.23 58.77 2.10 58.27 2.10 57.27 1.23 56.77 0.36 57.27 0.36 58.27 TH
23.37 58.77 24.24 58.27 24.24 57.27 23.37 56.77 22.50 57.27 22.50 58.27 TH
25.83 58.77 26.70 58.27 26.70 57.27 25.83 56.77 24.96 57.27 24.96 58.27 TH
40.59 58.77 41.46 58.27 41.46 57.27 40.59 56.77 39.72 57.27 39.72 58.27 TH
47.97 58.77 48.84 58.27 48.84 57.27 47.97 56.77 47.10 57.27 47.10 58.27 TH
12.30 56.63 13.17 56.13 13.17 55.13 12.30 54.63 11.43 55.13 11.43 56.13 TH
17.22 56.63 18.09 56.13 18.09 55.13 17.22 54.63 16.35 55.13 16.35 56.13 TH
27.06 56.63 27.93 56.13 27.93 55.13 27.06 54.63 26.19 55.13 26.19 56.13 TH
34.44 56.63 35.31 56.13 35.31 55.13 34.44 54.63 33.57 55.13 33.57 56.13 TH
41.82 56.63 42.69 56.13 42.69 55.13 41.82 54.63 40.95 55.13 40.95 56.13 TH
51.66 56.63 52.53 56.13 52.53 55.13 51.66 54.63 50.79 55.13 50.79 56.13 TH
59.04 56.63 59.91 56.13 59.91 55.13 59.04 54.63 58.17 55.13 58.17 56.13 TH
61.50 56.63 62.37 56.13 62.37 55.13 61.50 54.63 60.63 55.13 60.63 56.13 TH
63.96 56.63 64.83 56.13 64.83 55.13 63.96 54.63 63.09 55.13 63.09 56.13 TH
66.42 56.63 67.29 56.13 67.29 55.13 66.42 54.63 65.55 55.13 65.55 56.13 TH
68.88 56.63 69.75 56.13 69.75 55.13 68.88 54.63 68.01 55.13 68.01 56.13 TH
1.23 54.50 2.10 54.00 2.10 53.00 1.23 52.50 0.36 53.00 0.36 54.00 TH
3.69 54.50 4.56 54.00 4.56 53.00 3.69 52.50 2.82 53.00 2.82 54.00 TH
6.15 54.50 7.02 54.00 7.02 53.00 6.15 52.50 5.28 53.00 5.28 54.00 TH
11.07 54.50 11.94 54.00 11.94 53.00 11.07 52.50 10.20 53.00 10.20 54.00 TH
13.53 54.50 14.40 54.00 14.40 53.00 13.53 52.50 12.66 53.00 12.66 54.00 TH
15.99 54.50 16.86 54.00 16.86 53.00 15.99 52.50 15.12 53.00 15.12 54.00 TH
35.67 54.50 36.54 54.00 36.54 53.00 35.67 52.50 34.80 53.00 34.80 54.00 TH
52.89 54.50 53.76 54.00 53.76 53.00 52.89 52.50 52.02 53.00 52.02 54.00 TH
55.35 54.50 56.22 54.00 56.22 53.00 55.35 52.50 54.48 53.00 54.48 54.00 TH
19.68 52.36 20.55 51.86 20.55 50.86 19.68 50.36 18.81 50.86 18.81 51.86 TH
22.14 52.36 23.01 51.86 23.01 50.86 22.14 50.36 21.27 50.86 21.27 51.86 TH
27.06 52.36 27.93 51.86 27.93 50.86 27.06 50.36 26.19 50.86 26.19 51.86 TH
29.52 52.36 30.39 51.86 30.39 50.86 29.52 50.36 28.65 50.86 28.65 51.86 TH
49.20 52.36 50.07 51.86 50.07 50.86 49.20 50.36 48.33 50.86 48.33 51.86 TH
54.12 52.36 54.99 51.86 54.99 50.86 54.12 50.36 53.25 50.86 53.25 51.86 TH
63.96 52.36 64.83 51.86 64.83 50.86 63.96 50.36 63.09 50.86 63.09 51.86 TH
66.42 52.36 67.29 51.86 67.29 50.86 66.42 50.36 65.55 50.86 65.55 51.86 TH
1.23 50.23 2.10 49.73 2.10 48.73 1.23 48.23 0.36 48.73 0.36 49.73 TH
6.15 50.23 7.02 49.73 7.02 48.73 6.15 48.23 5.28 48.73 5.28 49.73 TH
8.61 50.23 9.48 49.73 9.48 48.73 8.61 48.23 7.74 48.73 7.74 49.73 TH
11.07 50.23 11.94 49.73 11.94 48.73 11.07 48.23 10.20 48.73 10.20 49.73 TH
13.53 50.23 14.40 49.73 14.40 48.73 13.53 48.23 12.66 48.73 12.66 49.73 TH
28.29 50.23 29.16 49.73 29.16 48.73 28.29 48.23 27.42 48.73 27.42 49.73 TH
33.21 50.23 34.08 49.73 34.08 48.73 33.21 48.23 32.34 48.73 32.34 49.73 TH
38.13 50.23 39.00 49.73 39.00 48.73 38.13 48.23 37.26 48.73 37.26 49.73 TH
40.59 50.23 41.46 49.73 41.46 48.73 40.59 48.23 39.72 48.73 39.72 49.73 TH
50.43 50.23 51.30 49.73 51.30 48.73 50.43 48.23 49.56 48.73 49.56 49.73 TH
52.89 50.23 53.76 49.73 53.76 48.73 52.89 48.23 52.02 48.73 52.02 49.73 TH
70.11 50.23 70.98 49.73 70.98 48.73 70.11 48.23 69.24 48.73 69.24 49.73 TH
72.57 50.23 73.44 49.73 73.44 48.73 72.57 48.23 71.70 48.73 71.70 49.73 TH
7.38 48.10 8.25 47.60 8.25 46.60 7.38 46.10 6.51 46.60 6.51 47.60 TH
9.84 48.10 10.71 47.60 10.71 46.60 9.84 46.10 8.97 46.60 8.97 47.60 TH
12.30 48.10 13.17 47.60 13.17 46.60 12.30 46.10 11.43 46.60 11.43 47.60 TH
22.14 48.10 23.01 47.60 23.01 46.60 22.14 46.10 21.27 46.60 21.27 47.60 TH
27.06 48.10 27.93 47.60 27.93 46.60 27.06 46.10 26.19 46.60 26.19 47.60 TH
46.74 48.10 47.61 47.60 47.61 46.60 46.74 46.10 45.87 46.60 45.87 47.60 TH
49.20 48.10 50.07 47.60 50.07 46.60 49.20 46.10 48.33 46.60 48.33 47.60 TH
51.66 48.10 52.53 47.60 52.53 46.60 51.66 46.10 50.79 46.60 50.79 47.60 TH
56.58 48.10 57.45 47.60 57.45 46.60 56.58 46.10 55.71 46.60 55.71 47.60 TH
66.42 48.10 67.29 47.60 67.29 46.60 66.42 46.10 65.55 46.60 65.55 47.60 TH
68.88 48.10 69.75 47.60 69.75 46.60 68.88 46.10 68.01 46.60 68.01 47.60 TH
71.34 48.10 72.21 47.60 72.21 46.60 71.34 46.10 70.47 46.60 70.47 47.60 TH
8.61 45.96 9.48 45.46 9.48 44.46 8.61 43.96 7.74 44.46 7.74 45.46 TH
11.07 45.96 11.94 45.46 11.94 44.46 11.07 43.96 10.20 44.46 10.20 45.46 TH
13.53 45.96 14.40 45.46 14.40 44.46 13.53 43.96 12.66 44.46 12.66 45.46 TH
15.99 45.96 16.86 45.46 16.86 44.46 15.99 43.96 15.12 44.46 15.12 45.46 TH
45.51 45.96 46.38 45.46 46.38 44.46 45.51 43.96 44.64 44.46 44.64 45.46 TH
57.81 45.96 58.68 45.46 58.68 44.46 57.81 43.96 56.94 44.46 56.94 45.46 TH
62.73 45.96 63.60 45.46 63.60 44.46 62.73 43.96 61.86 44.46 61.86 45.46 TH
65.19 45.96 66.06 45.46 66.06 44.46 65.19 43.96 64.32 44.46 64.32 45.46 TH
2.46 43.83 3.33 43.33 3.33 42.33 2.46 41.83 1.59 42.33 1.59 43.33 TH
12.30 43.83 13.17 43.33 13.17 42.33 12.30 41.83 11.43 42.33 11.43 43.33 TH
54.12 43.83 54.99 43.33 54.99 42.33 54.12 41.83 53.25 42.33 53.25 43.33 TH
56.58 43.83 57.45 43.33 57.45 42.33 56.58 41.83 55.71 42.33 55.71 43.33 TH
59.04 43.83 59.91 43.33 59.91 42.33 59.04 41.83 58.17 42.33 58.17 43.33 TH
66.42 43.83 67.29 43.33 67.29 42.33 66.42 41.83 65.55 42.33 65.55 43.33 TH
1.23 41.69 2.10 41.19 2.10 40.19 1.23 39.69 0.36 40.19 0.36 41.19 TH
20.91 41.69 21.78 41.19 21.78 40.19 20.91 39.69 20.04 40.19 20.04 41.19 TH
47.97 41.69 48.84 41.19 48.84 40.19 47.97 39.69 47.10 40.19 47.10 41.19 TH
50.43 41.69 51.30 41.19 51.30 40.19 50.43 39.69 49.56 40.19 49.56 41.19 TH
65.19 41.69 66.06 41.19 66.06 40.19 65.19 39.69 64.32 40.19 64.32 41.19 TH
12.30 39.56 13.17 39.06 13.17 38.06 12.30 37.56 11.43 38.06 11.43 39.06 TH
17.22 39.56 18.09 39.06 18.09 38.06 17.22 37.56 16.35 38.06 16.35 39.06 TH
19.68 39.56 20.55 39.06 20.55 38.06 19.68 37.56 18.81 38.06 18.81 39.06 TH
22.14 39.56 23.01 39.06 23.01 38.06 22.14 37.56 21.27 38.06 21.27 39.06 TH
56.58 39.56 57.45 39.06 57.45 38.06 56.58 37.56 55.71 38.06 55.71 39.06 TH
71.34 39.56 72.21 39.06 72.21 38.06 71.34 37.56 70.47 38.06 70.47 39.06 TH
1.23 37.43 2.10 36.93 2.10 35.93 1.23 35.43 0.36 35.93 0.36 36.93 TH
3.69 37.43 4.56 36.93 4.56 35.93 3.69 35.43 2.82 35.93 2.82 36.93 TH
6.15 37.43 7.02 36.93 7.02 35.93 6.15 35.43 5.28 35.93 5.28 36.93 TH
20.91 37.43 21.78 36.93 21.78 35.93 20.91 35.43 20.04 35.93 20.04 36.93 TH
50.43 37.43 51.30 36.93 51.30 35.93 50.43 35.43 49.56 35.93 49.56 36.93 TH
65.19 37.43 66.06 36.93 66.06 35.93 65.19 35.43 64.32 35.93 64.32 36.93 TH
67.65 37.43 68.52 36.93 68.52 35.93 67.65 35.43 66.78 35.93 66.78 36.93 TH
72.57 37.43 73.44 36.93 73.44 35.93 72.57 35.43 71.70 35.93 71.70 36.93 TH
4.92 35.29 5.79 34.79 5.79 33.79 4.92 33.29 4.05 33.79 4.05 34.79 TH
7.38 35.29 8.25 34.79 8.25 33.79 7.38 33.29 6.51 33.79 6.51 34.79 TH
51.66 35.29 52.53 34.79 52.53 33.79 51.66 33.29 50.79 33.79 50.79 34.79 TH
61.50 35.29 62.37 34.79 62.37 33.79 61.50 33.29 60.63 33.79 60.63 34.79 TH
68.88 35.29 69.75 34.79 69.75 33.79 68.88 33.29 68.01 33.79 68.01 34.79 TH
15.99 33.16 16.86 32.66 16.86 31.66 15.99 31.16 15.12 31.66 15.12 32.66 TH
20.91 33.16 21.78 32.66 21.78 31.66 20.91 31.16 20.04 31.66 20.04 32.66 TH
23.37 33.16 24.24 32.66 24.24 31.66 23.37 31.16 22.50 31.66 22.50 32.66 TH
50.43 33.16 51.30 32.66 51.30 31.66 50.43 31.16 49.56 31.66 49.56 32.66 TH
57.81 33.16 58.68 32.66 58.68 31.66 57.81 31.16 56.94 31.66 56.94 32.66 TH
62.73 33.16 63.60 32.66 63.60 31.66 62.73 31.16 61.86 31.66 61.86 32.66 TH
72.57 33.16 73.44 32.66 73.44 31.66 72.57 31.16 71.70 31.66 71.70 32.66 TH
2.46 31.02 3.33 30.52 3.33 29.52 2.46 29.02 1.59 29.52 1.59 30.52 TH
7.38 31.02 8.25 30.52 8.25 29.52 7.38 29.02 6.51 29.52 6.51 30.52 TH
12.30 31.02 13.17 30.52 13.17 29.52 12.30 29.02 11.43 29.52 11.43 30.52 TH
22.14 31.02 23.01 30.52 23.01 29.52 22.14 29.02 21.27 29.52 21.27 30.52 TH
46.74 31.02 47.61 30.52 47.61 29.52 46.74 29.02 45.87 29.52 45.87 30.52 TH
54.12 31.02 54.99 30.52 54.99 29.52 54.12 29.02 53.25 29.52 53.25 30.52 TH
56.58 31.02 57.45 30.52 57.45 29.52 56.58 29.02 55.71 29.52 55.71 30.52 TH
59.04 31.02 59.91 30.52 59.91 29.52 59.04 29.02 58.17 29.52 58.17 30.52 TH
66.42 31.02 67.29 30.52 67.29 29.52 66.42 29.02 65.55 29.52 65.55 30.52 TH
68.88 31.02 69.75 30.52 69.75 29.52 68.88 29.02 68.01 29.52 68.01 30.52 TH
6.15 28.89 7.02 28.39 7.02 27.39 6.15 26.89 5.28 27.39 5.28 28.39 TH
18.45 28.89 19.32 28.39 19.32 27.39 18.45 26.89 17.58 27.39 17.58 28.39 TH
20.91 28.89 21.78 28.39 21.78 27.39 20.91 26.89 20.04 27.39 20.04 28.39 TH
47.97 28.89 48.84 28.39 48.84 27.39 47.97 26.89 47.10 27.39 47.10 28.39 TH
50.43 28.89 51.30 28.39 51.30 27.39 50.43 26.89 49.56 27.39 49.56 28.39 TH
52.89 28.89 53.76 28.39 53.76 27.39 52.89 26.89 52.02 27.39 52.02 28.39 TH
65.19 28.89 66.06 28.39 66.06 27.39 65.19 26.89 64.32 27.39 64.32 28.39 TH
70.11 28.89 70.98 28.39 70.98 27.39 70.11 26.89 69.24 27.39 69.24 28.39 TH
46.74 26.76 47.61 26.26 47.61 25.26 46.74 24.76 45.87 25.26 45.87 26.26 TH
49.20 26.76 50.07 26.26 50.07 25.26 49.20 24.76 48.33 25.26 48.33 26.26 TH
61.50 26.76 62.37 26.26 62.37 25.26 61.50 24.76 60.63 25.26 60.63 26.26 TH
1.23 24.62 2.10 24.12 2.10 23.12 1.23 22.62 0.36 23.12 0.36 24.12 TH
6.15 24.62 7.02 24.12 7.02 23.12 6.15 22.62 5.28 23.12 5.28 24.12 TH
11.07 24.62 11.94 24.12 11.94 23.12 11.07 22.62 10.20 23.12 10.20 24.12 TH
13.53 24.62 14.40 24.12 14.40 23.12 13.53 22.62 12.66 23.12 12.66 24.12 TH
20.91 24.62 21.78 24.12 21.78 23.12 20.91 22.62 20.04 23.12 20.04 24.12 TH
25.83 24.62 26.70 24.12 26.70 23.12 25.83 22.62 24.96 23.12 24.96 24.12 TH
30.75 24.62 31.62 24.12 31.62 23.12 30.75 22.62 29.88 23.12 29.88 24.12 TH
43.05 24.62 43.92 24.12 43.92 23.12 43.05 22.62 42.18 23.12 42.18 24.12 TH
52.89 24.62 53.76 24.12 53.76 23.12 52.89 22.62 52.02 23.12 52.02 24.12 TH
57.81 24.62 58.68 24.12 58.68 23.12 57.81 22.62 56.94 23.12 56.94 24.12 TH
62.73 24.62 63.60 24.12 63.60 23.12 62.73 22.62 61.86 23.12 61.86 24.12 TH
72.57 24.62 73.44 24.12 73.44 23.12 72.57 22.62 71.70 23.12 71.70 24.12 TH
2.46 22.49 3.33 21.99 3.33 20.99 2.46 20.49 1.59 20.99 1.59 21.99 TH
12.30 22.49 13.17 21.99 13.17 20.99 12.30 20.49 11.43 20.99 11.43 21.99 TH
14.76 22.49 15.63 21.99 15.63 20.99 14.76 20.49 13.89 20.99 13.89 21.99 TH
17.22 22.49 18.09 21.99 18.09 20.99 17.22 20.49 16.35 20.99 16.35 21.99 TH
19.68 22.49 20.55 21.99 20.55 20.99 19.68 20.49 18.81 20.99 18.81 21.99 TH
27.06 22.49 27.93 21.99 27.93 20.99 27.06 20.49 26.19 20.99 26.19 21.99 TH
31.98 22.49 32.85 21.99 32.85 20.99 31.98 20.49 31.11 20.99 31.11 21.99 TH
36.90 22.49 37.77 21.99 37.77 20.99 36.90 20.49 36.03 20.99 36.03 21.99 TH
44.28 22.49 45.15 21.99 45.15 20.99 44.28 20.49 43.41 20.99 43.41 21.99 TH
46.74 22.49 47.61 21.99 47.61 20.99 46.74 20.49 45.87 20.99 45.87 21.99 TH
51.66 22.49 52.53 21.99 52.53 20.99 51.66 20.49 50.79 20.99 50.79 21.99 TH
56.58 22.49 57.45 21.99 57.45 20.99 56.58 20.49 55.71 20.99 55.71 21.99 TH
66.42 22.49 67.29 21.99 67.29 20.99 66.42 20.49 65.55 20.99 65.55 21.99 TH
71.34 22.49 72.21 21.99 72.21 20.99 71.34 20.49 70.47 20.99 70.47 21.99 TH
3.69 20.35 4.56 19.85 4.56 18.85 3.69 18.35 2.82 18.85 2.82 19.85 TH
6.15 20.35 7.02 19.85 7.02 18.85 6.15 18.35 5.28 18.85 5.28 19.85 TH
11.07 20.35 11.94 19.85 11.94 18.85 11.07 18.35 10.20 18.85 10.20 19.85 TH
38.13 20.35 39.00 19.85 39.00 18.85 38.13 18.35 37.26 18.85 37.26 19.85 TH
43.05 20.35 43.92 19.85 43.92 18.85 43.05 18.35 42.18 18.85 42.18 19.85 TH
47.97 20.35 48.84 19.85 48.84 18.85 47.97 18.35 47.10 18.85 47.10 19.85 TH
50.43 20.35 51.30 19.85 51.30 18.85 50.43 18.35 49.56 18.85 49.56 19.85 TH
55.35 20.35 56.22 19.85 56.22 18.85 55.35 18.35 54.48 18.85 54.48 19.85 TH
62.73 20.35 63.60 19.85 63.60 18.85 62.73 18.35 61.86 18.85 61.86 19.85 TH
65.19 20.35 66.06 19.85 66.06 18.85 65.19 18.35 64.32 18.85 64.32 19.85 TH
67.65 20.35 68.52 19.85 68.52 18.85 67.65 18.35 66.78 18.85 66.78 19.85 TH
70.11 20.35 70.98 19.85 70.98 18.85 70.11 18.35 69.24 18.85 69.24 19.85 TH
72.57 20.35 73.44 19.85 73.44 18.85 72.57 18.35 71.70 18.85 71.70 19.85 TH
14.76 18.22 15.63 17.72 15.63 16.72 14.76 16.22 13.89 16.72 13.89 17.72 TH
17.22 18.22 18.09 17.72 18.09 16.72 17.22 16.22 16.35 16.72 16.35 17.72 TH
19.68 18.22 20.55 17.72 20.55 16.72 19.68 16.22 18.81 16.72 18.81 17.72 TH
27.06 18.22 27.93 17.72 27.93 16.72 27.06 16.22 26.19 16.72 26.19 17.72 TH
29.52 18.22 30.39 17.72 30.39 16.72 29.52 16.22 28.65 16.72 28.65 17.72 TH
31.98 18.22 32.85 17.72 32.85 16.72 31.98 16.22 31.11 16.72 31.11 17.72 TH
34.44 18.22 35.31 17.72 35.31 16.72 34.44 16.22 33.57 16.72 33.57 17.72 TH
36.90 18.22 37.77 17.72 37.77 16.72 36.90 16.22 36.03 16.72 36.03 17.72 TH
39.36 18.22 40.23 17.72 40.23 16.72 39.36 16.22 38.49 16.72 38.49 17.72 TH
41.82 18.22 42.69 17.72 42.69 16.72 41.82 16.22 40.95 16.72 40.95 17.72 TH
44.28 18.22 45.15 17.72 45.15 16.72 44.28 16.22 43.41 16.72 43.41 17.72 TH
46.74 18.22 47.61 17.72 47.61 16.72 46.74 16.22 45.87 16.72 45.87 17.72 TH
49.20 18.22 50.07 17.72 50.07 16.72 49.20 16.22 48.33 16.72 48.33 17.72 TH
51.66 18.22 52.53 17.72 52.53 16.72 51.66 16.22 50.79 16.72 50.79 17.72 TH
54.12 18.22 54.99 17.72 54.99 16.72 54.12 16.22 53.25 16.72 53.25 17.72 TH
63.96 18.22 64.83 17.72 64.83 16.72 63.96 16.22 63.09 16.72 63.09 17.72 TH
68.88 18.22 69.75 17.72 69.75 16.72 68.88 16.22 68.01 16.72 68.01 17.72 TH
6.15 16.09 7.02 15.59 7.02 14.59 6.15 14.09 5.28 14.59 5.28 15.59 TH
8.61 16.09 9.48 15.59 9.48 14.59 8.61 14.09 7.74 14.59 7.74 15.59 TH
11.07 16.09 11.94 15.59 11.94 14.59 11.07 14.09 10.20 14.59 10.20 15.59 TH
15.99 16.09 16.86 15.59 16.86 14.59 15.99 14.09 15.12 14.59 15.12 15.59 TH
23.37 16.09 24.24 15.59 24.24 14.59 23.37 14.09 22.50 14.59 22.50 15.59 TH
25.83 16.09 26.70 15.59 26.70 14.59 25.83 14.09 24.96 14.59 24.96 15.59 TH
28.29 16.09 29.16 15.59 29.16 14.59 28.29 14.09 27.42 14.59 27.42 15.59 TH
38.13 16.09 39.00 15.59 39.00 14.59 38.13 14.09 37.26 14.59 37.26 15.59 TH
43.05 16.09 43.92 15.59 43.92 14.59 43.05 14.09 42.18 14.59 42.18 15.59 TH
47.97 16.09 48.84 15.59 48.84 14.59 47.97 14.09 47.10 14.59 47.10 15.59 TH
50.43 16.09 51.30 15.59 51.30 14.59 50.43 14.09 49.56 14.59 49.56 15.59 TH
62.73 16.09 63.60 15.59 63.60 14.59 62.73 14.09 61.86 14.59 61.86 15.59 TH
65.19 16.09 66.06 15.59 66.06 14.59 65.19 14.09 64.32 14.59 64.32 15.59 TH
67.65 16.09 68.52 15.59 68.52 14.59 67.65 14.09 66.78 14.59 66.78 15.59 TH
2.46 13.95 3.33 13.45 3.33 12.45 2.46 11.95 1.59 12.45 1.59 13.45 TH
4.92 13.95 5.79 13.45 5.79 12.45 4.92 11.95 4.05 12.45 4.05 13.45 TH
9.84 13.95 10.71 13.45 10.71 12.45 9.84 11.95 8.97 12.45 8.97 13.45 TH
12.30 13.95 13.17 13.45 13.17 12.45 12.30 11.95 11.43 12.45 11.43 13.45 TH
14.76 13.95 15.63 13.45 15.63 12.45 14.76 11.95 13.89 12.45 13.89 13.45 TH
19.68 13.95 20.55 13.45 20.55 12.45 19.68 11.95 18.81 12.45 18.81 13.45 TH
22.14 13.95 23.01 13.45 23.01 12.45 22.14 11.95 21.27 12.45 21.27 13.45 TH
24.60 13.95 25.47 13.45 25.47 12.45 24.60 11.95 23.73 12.45 23.73 13.45 TH
31.98 13.95 32.85 13.45 32.85 12.45 31.98 11.95 31.11 12.45 31.11 13.45 TH
44.28 13.95 45.15 13.45 45.15 12.45 44.28 11.95 43.41 12.45 43.41 13.45 TH
46.74 13.95 47.61 13.45 47.61 12.45 46.74 11.95 45.87 12.45 45.87 13.45 TH
51.66 13.95 52.53 13.45 52.53 12.45 51.66 11.95 50.79 12.45 50.79 13.45 TH
59.04 13.95 59.91 13.45 59.91 12.45 59.04 11.95 58.17 12.45 58.17 13.45 TH
63.96 13.95 64.83 13.45 64.83 12.45 63.96 11.95 63.09 12.45 63.09 13.45 TH
68.88 13.95 69.75 13.45 69.75 12.45 68.88 11.95 68.01 12.45 68.01 13.45 TH
71.34 13.95 72.21 13.45 72.21 12.45 71.34 11.95 70.47 12.45 70.47 13.45 TH
13.53 11.82 14.40 11.32 14.40 10.32 13.53 9.82 12.66 10.32 12.66 11.32 TH
18.45 11.82 19.32 11.32 19.32 10.32 18.45 9.82 17.58 10.32 17.58 11.32 TH
20.91 11.82 21.78 11.32 21.78 10.32 20.91 9.82 20.04 10.32 20.04 11.32 TH
25.83 11.82 26.70 11.32 26.70 10.32 25.83 9.82 24.96 10.32 24.96 11.32 TH
28.29 11.82 29.16 11.32 29.16 10.32 28.29 9.82 27.42 10.32 27.42 11.32 TH
30.75 11.82 31.62 11.32 31.62 10.32 30.75 9.82 29.88 10.32 29.88 11.32 TH
35.67 11.82 36.54 11.32 36.54 10.32 35.67 9.82 34.80 10.32 34.80 11.32 TH
40.59 11.82 41.46 11.32 41.46 10.32 40.59 9.82 39.72 10.32 39.72 11.32 TH
47.97 11.82 48.84 11.32 48.84 10.32 47.97 9.82 47.10 10.32 47.10 11.32 TH
52.89 11.82 53.76 11.32 53.76 10.32 52.89 9.82 52.02 10.32 52.02 11.32 TH
55.35 11.82 56.22 11.32 56.22 10.32 55.35 9.82 54.48 10.32 54.48 11.32 TH
57.81 11.82 58.68 11.32 58.68 10.32 57.81 9.82 56.94 10.32 56.94 11.32 TH
65.19 11.82 66.06 11.32 66.06 10.32 65.19 9.82 64.32 10.32 64.32 11.32 TH
67.65 11.82 68.52 11.32 68.52 10.32 67.65 9.82 66.78 10.32 66.78 11.32 TH
2.46 9.68 3.33 9.18 3.33 8.18 2.46 7.68 1.59 8.18 1.59 9.18 TH
4.92 9.68 5.79 9.18 5.79 8.18 4.92 7.68 4.05 8.18 4.05 9.18 TH
7.38 9.68 8.25 9.18 8.25 8.18 7.38 7.68 6.51 8.18 6.51 9.18 TH
17.22 9.68 18.09 9.18 18.09 8.18 17.22 7.68 16.35 8.18 16.35 9.18 TH
19.68 9.68 20.55 9.18 20.55 8.18 19.68 7.68 18.81 8.18 18.81 9.18 TH
24.60 9.68 25.47 9.18 25.47 8.18 24.60 7.68 23.73 8.18 23.73 9.18 TH
27.06 9.68 27.93 9.18 27.93 8.18 27.06 7.68 26.19 8.18 26.19 9.18 TH
29.52 9.68 30.39 9.18 30.39 8.18 29.52 7.68 28.65 8.18 28.65 9.18 TH
31.98 9.68 32.85 9.18 32.85 8.18 31.98 7.68 31.11 8.18 31.11 9.18 TH
41.82 9.68 42.69 9.18 42.69 8.18 41.82 7.68 40.95 8.18 40.95 9.18 TH
51.66 9.68 52.53 9.18 52.53 8.18 51.66 7.68 50.79 8.18 50.79 9.18 TH
54.12 9.68 54.99 9.18 54.99 8.18 54.12 7.68 53.25 8.18 53.25 9.18 TH
56.58 9.68 57.45 9.18 57.45 8.18 56.58 7.68 55.71 8.18 55.71 9.18 TH
59.04 9.68 59.91 9.18 59.91 8.18 59.04 7.68 58.17 8.18 58.17 9.18 TH
63.96 9.68 64.83 9.18 64.83 8.18 63.96 7.68 63.09 8.18 63.09 9.18 TH
66.42 9.68 67.29 9.18 67.29 8.18 66.42 7.68 65.55 8.18 65.55 9.18 TH
68.88 9.68 69.75 9.18 69.75 8.18 68.88 7.68 68.01 8.18 68.01 9.18 TH
71.34 9.68 72.21 9.18 72.21 8.18 71.34 7.68 70.47 8.18 70.47 9.18 TH
1.23 7.55 2.10 7.05 2.10 6.05 1.23 5.55 0.36 6.05 0.36 7.05 TH
6.15 7.55 7.02 7.05 7.02 6.05 6.15 5.55 5.28 6.05 5.28 7.05 TH
8.61 7.55 9.48 7.05 9.48 6.05 8.61 5.55 7.74 6.05 7.74 7.05 TH
11.07 7.55 11.94 7.05 11.94 6.05 11.07 5.55 10.20 6.05 10.20 7.05 TH
13.53 7.55 14.40 7.05 14.40 6.05 13.53 5.55 12.66 6.05 12.66 7.05 TH
18.45 7.55 19.32 7.05 19.32 6.05 18.45 5.55 17.58 6.05 17.58 7.05 TH
23.37 7.55 24.24 7.05 24.24 6.05 23.37 5.55 22.50 6.05 22.50 7.05 TH
25.83 7.55 26.70 7.05 26.70 6.05 25.83 5.55 24.96 6.05 24.96 7.05 TH
28.29 7.55 29.16 7.05 29.16 6.05 28.29 5.55 27.42 6.05 27.42 7.05 TH
30.75 7.55 31.62 7.05 31.62 6.05 30.75 5.55 29.88 6.05 29.88 7.05 TH
33.21 7.55 34.08 7.05 34.08 6.05 33.21 5.55 32.34 6.05 32.34 7.05 TH
35.67 7.55 36.54 7.05 36.54 6.05 35.67 5.55 34.80 6.05 34.80 7.05 TH
47.97 7.55 48.84 7.05 48.84 6.05 47.97 5.55 47.10 6.05 47.10 7.05 TH
52.89 7.55 53.76 7.05 53.76 6.05 52.89 5.55 52.02 6.05 52.02 7.05 TH
55.35 7.55 56.22 7.05 56.22 6.05 55.35 5.55 54.48 6.05 54.48 7.05 TH
60.27 7.55 61.14 7.05 61.14 6.05 60.27 5.55 59.40 6.05 59.40 7.05 TH
62.73 7.55 63.60 7.05 63.60 6.05 62.73 5.55 61.86 6.05 61.86 7.05 TH
65.19 7.55 66.06 7.05 66.06 6.05 65.19 5.55 64.32 6.05 64.32 7.05 TH
72.57 7.55 73.44 7.05 73.44 6.05 72.57 5.55 71.70 6.05 71.70 7.05 TH
7.38 5.42 8.25 4.92 8.25 3.92 7.38 3.42 6.51 3.92 6.51 4.92 TH
14.76 5.42 15.63 4.92 15.63 3.92 14.76 3.42 13.89 3.92 13.89 4.92 TH
17.22 5.42 18.09 4.92 18.09 3.92 17.22 3.42 16.35 3.92 16.35 4.92 TH
22.14 5.42 23.01 4.92 23.01 3.92 22.14 3.42 21.27 3.92 21.27 4.92 TH
24.60 5.42 25.47 4.92 25.47 3.92 24.60 3.42 23.73 3.92 23.73 4.92 TH
27.06 5.42 27.93 4.92 27.93 3.92 27.06 3.42 26.19 3.92 26.19 4.92 TH
29.52 5.42 30.39 4.92 30.39 3.92 29.52 3.42 28.65 3.92 28.65 4.92 TH
31.98 5.42 32.85 4.92 32.85 3.92 31.98 3.42 31.11 3.92 31.11 4.92 TH
36.90 5.42 37.77 4.92 37.77 3.92 36.90 3.42 36.03 3.92 36.03 4.92 TH
39.36 5.42 40.23 4.92 40.23 3.92 39.36 3.42 38.49 3.92 38.49 4.92 TH
44.28 5.42 45.15 4.92 45.15 3.92 44.28 3.42 43.41 3.92 43.41 4.92 TH
46.74 5.42 47.61 4.92 47.61 3.92 46.74 3.42 45.87 3.92 45.87 4.92 TH
51.66 5.42 52.53 4.92 52.53 3.92 51.66 3.42 50.79 3.92 50.79 4.92 TH
56.58 5.42 57.45 4.92 57.45 3.92 56.58 3.42 55.71 3.92 55.71 4.92 TH
63.96 5.42 64.83 4.92 64.83 3.92 63.96 3.42 63.09 3.92 63.09 4.92 TH
66.42 5.42 67.29 4.92 67.29 3.92 66.42 3.42 65.55 3.92 65.55 4.92 TH
68.88 5.42 69.75 4.92 69.75 3.92 68.88 3.42 68.01 3.92 68.01 4.92 TH
6.15 3.28 7.02 2.78 7.02 1.78 6.15 1.28 5.28 1.78 5.28 2.78 TH
11.07 3.28 11.94 2.78 11.94 1.78 11.07 1.28 10.20 1.78 10.20 2.78 TH
13.53 3.28 14.40 2.78 14.40 1.78 13.53 1.28 12.66 1.78 12.66 2.78 TH
30.75 3.28 31.62 2.78 31.62 1.78 30.75 1.28 29.88 1.78 29.88 2.78 TH
33.21 3.28 34.08 2.78 34.08 1.78 33.21 1.28 32.34 1.78 32.34 2.78 TH
35.67 3.28 36.54 2.78 36.54 1.78 35.67 1.28 34.80 1.78 34.80 2.78 TH
38.13 3.28 39.00 2.78 39.00 1.78 38.13 1.28 37.26 1.78 37.26 2.78 TH
43.05 3.28 43.92 2.78 43.92 1.78 43.05 1.28 42.18 1.78 42.18 2.78 TH
45.51 3.28 46.38 2.78 46.38 1.78 45.51 1.28 44.64 1.78 44.64 2.78 TH
52.89 3.28 53.76 2.78 53.76 1.78 52.89 1.28 52.02 1.78 52.02 2.78 TH
65.19 3.28 66.06 2.78 66.06 1.78 65.19 1.28 64.32 1.78 64.32 2.78 TH
35.76 36.40 10.85 TD
1.00 1.00 1.00 setrgbcolor
35.76 36.40 8.97 TD
0.00 0.00 0.00 setrgbcolor
35.76 36.40 7.10 TD
1.00 1.00 1.00 setrgbcolor
35.76 36.40 5.22 TD
0.00 0.00 0.00 setrgbcolor
35.76 36.40 3.31 TD
1.00 1.00 1.00 setrgbcolor
35.76 36.40 1.43 TD

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,366 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="74" height="72" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<desc>Zint Generated Symbol
</desc>
<g id="barcode" fill="#000000">
<rect x="0" y="0" width="74" height="72" fill="#FFFFFF" />
<path d="M 3.69 2.43 L 4.56 1.93 L 4.56 0.93 L 3.69 0.43 L 2.82 0.93 L 2.82 1.93 Z" />
<path d="M 6.15 2.43 L 7.02 1.93 L 7.02 0.93 L 6.15 0.43 L 5.28 0.93 L 5.28 1.93 Z" />
<path d="M 8.61 2.43 L 9.48 1.93 L 9.48 0.93 L 8.61 0.43 L 7.74 0.93 L 7.74 1.93 Z" />
<path d="M 11.07 2.43 L 11.94 1.93 L 11.94 0.93 L 11.07 0.43 L 10.20 0.93 L 10.20 1.93 Z" />
<path d="M 13.53 2.43 L 14.40 1.93 L 14.40 0.93 L 13.53 0.43 L 12.66 0.93 L 12.66 1.93 Z" />
<path d="M 18.45 2.43 L 19.32 1.93 L 19.32 0.93 L 18.45 0.43 L 17.58 0.93 L 17.58 1.93 Z" />
<path d="M 35.67 2.43 L 36.54 1.93 L 36.54 0.93 L 35.67 0.43 L 34.80 0.93 L 34.80 1.93 Z" />
<path d="M 50.43 2.43 L 51.30 1.93 L 51.30 0.93 L 50.43 0.43 L 49.56 0.93 L 49.56 1.93 Z" />
<path d="M 60.27 2.43 L 61.14 1.93 L 61.14 0.93 L 60.27 0.43 L 59.40 0.93 L 59.40 1.93 Z" />
<path d="M 67.65 2.43 L 68.52 1.93 L 68.52 0.93 L 67.65 0.43 L 66.78 0.93 L 66.78 1.93 Z" />
<path d="M 70.11 2.43 L 70.98 1.93 L 70.98 0.93 L 70.11 0.43 L 69.24 0.93 L 69.24 1.93 Z" />
<path d="M 72.57 2.43 L 73.44 1.93 L 73.44 0.93 L 72.57 0.43 L 71.70 0.93 L 71.70 1.93 Z" />
<path d="M 9.84 4.56 L 10.71 4.06 L 10.71 3.06 L 9.84 2.56 L 8.97 3.06 L 8.97 4.06 Z" />
<path d="M 29.52 4.56 L 30.39 4.06 L 30.39 3.06 L 29.52 2.56 L 28.65 3.06 L 28.65 4.06 Z" />
<path d="M 51.66 4.56 L 52.53 4.06 L 52.53 3.06 L 51.66 2.56 L 50.79 3.06 L 50.79 4.06 Z" />
<path d="M 56.58 4.56 L 57.45 4.06 L 57.45 3.06 L 56.58 2.56 L 55.71 3.06 L 55.71 4.06 Z" />
<path d="M 6.15 6.70 L 7.02 6.20 L 7.02 5.20 L 6.15 4.70 L 5.28 5.20 L 5.28 6.20 Z" />
<path d="M 11.07 6.70 L 11.94 6.20 L 11.94 5.20 L 11.07 4.70 L 10.20 5.20 L 10.20 6.20 Z" />
<path d="M 13.53 6.70 L 14.40 6.20 L 14.40 5.20 L 13.53 4.70 L 12.66 5.20 L 12.66 6.20 Z" />
<path d="M 20.91 6.70 L 21.78 6.20 L 21.78 5.20 L 20.91 4.70 L 20.04 5.20 L 20.04 6.20 Z" />
<path d="M 23.37 6.70 L 24.24 6.20 L 24.24 5.20 L 23.37 4.70 L 22.50 5.20 L 22.50 6.20 Z" />
<path d="M 30.75 6.70 L 31.62 6.20 L 31.62 5.20 L 30.75 4.70 L 29.88 5.20 L 29.88 6.20 Z" />
<path d="M 38.13 6.70 L 39.00 6.20 L 39.00 5.20 L 38.13 4.70 L 37.26 5.20 L 37.26 6.20 Z" />
<path d="M 40.59 6.70 L 41.46 6.20 L 41.46 5.20 L 40.59 4.70 L 39.72 5.20 L 39.72 6.20 Z" />
<path d="M 45.51 6.70 L 46.38 6.20 L 46.38 5.20 L 45.51 4.70 L 44.64 5.20 L 44.64 6.20 Z" />
<path d="M 47.97 6.70 L 48.84 6.20 L 48.84 5.20 L 47.97 4.70 L 47.10 5.20 L 47.10 6.20 Z" />
<path d="M 55.35 6.70 L 56.22 6.20 L 56.22 5.20 L 55.35 4.70 L 54.48 5.20 L 54.48 6.20 Z" />
<path d="M 62.73 6.70 L 63.60 6.20 L 63.60 5.20 L 62.73 4.70 L 61.86 5.20 L 61.86 6.20 Z" />
<path d="M 70.11 6.70 L 70.98 6.20 L 70.98 5.20 L 70.11 4.70 L 69.24 5.20 L 69.24 6.20 Z" />
<path d="M 2.46 8.83 L 3.33 8.33 L 3.33 7.33 L 2.46 6.83 L 1.59 7.33 L 1.59 8.33 Z" />
<path d="M 19.68 8.83 L 20.55 8.33 L 20.55 7.33 L 19.68 6.83 L 18.81 7.33 L 18.81 8.33 Z" />
<path d="M 29.52 8.83 L 30.39 8.33 L 30.39 7.33 L 29.52 6.83 L 28.65 7.33 L 28.65 8.33 Z" />
<path d="M 31.98 8.83 L 32.85 8.33 L 32.85 7.33 L 31.98 6.83 L 31.11 7.33 L 31.11 8.33 Z" />
<path d="M 41.82 8.83 L 42.69 8.33 L 42.69 7.33 L 41.82 6.83 L 40.95 7.33 L 40.95 8.33 Z" />
<path d="M 49.20 8.83 L 50.07 8.33 L 50.07 7.33 L 49.20 6.83 L 48.33 7.33 L 48.33 8.33 Z" />
<path d="M 6.15 10.97 L 7.02 10.47 L 7.02 9.47 L 6.15 8.97 L 5.28 9.47 L 5.28 10.47 Z" />
<path d="M 11.07 10.97 L 11.94 10.47 L 11.94 9.47 L 11.07 8.97 L 10.20 9.47 L 10.20 10.47 Z" />
<path d="M 13.53 10.97 L 14.40 10.47 L 14.40 9.47 L 13.53 8.97 L 12.66 9.47 L 12.66 10.47 Z" />
<path d="M 30.75 10.97 L 31.62 10.47 L 31.62 9.47 L 30.75 8.97 L 29.88 9.47 L 29.88 10.47 Z" />
<path d="M 35.67 10.97 L 36.54 10.47 L 36.54 9.47 L 35.67 8.97 L 34.80 9.47 L 34.80 10.47 Z" />
<path d="M 50.43 10.97 L 51.30 10.47 L 51.30 9.47 L 50.43 8.97 L 49.56 9.47 L 49.56 10.47 Z" />
<path d="M 55.35 10.97 L 56.22 10.47 L 56.22 9.47 L 55.35 8.97 L 54.48 9.47 L 54.48 10.47 Z" />
<path d="M 60.27 10.97 L 61.14 10.47 L 61.14 9.47 L 60.27 8.97 L 59.40 9.47 L 59.40 10.47 Z" />
<path d="M 62.73 10.97 L 63.60 10.47 L 63.60 9.47 L 62.73 8.97 L 61.86 9.47 L 61.86 10.47 Z" />
<path d="M 70.11 10.97 L 70.98 10.47 L 70.98 9.47 L 70.11 8.97 L 69.24 9.47 L 69.24 10.47 Z" />
<path d="M 72.57 10.97 L 73.44 10.47 L 73.44 9.47 L 72.57 8.97 L 71.70 9.47 L 71.70 10.47 Z" />
<path d="M 2.46 13.10 L 3.33 12.60 L 3.33 11.60 L 2.46 11.10 L 1.59 11.60 L 1.59 12.60 Z" />
<path d="M 4.92 13.10 L 5.79 12.60 L 5.79 11.60 L 4.92 11.10 L 4.05 11.60 L 4.05 12.60 Z" />
<path d="M 7.38 13.10 L 8.25 12.60 L 8.25 11.60 L 7.38 11.10 L 6.51 11.60 L 6.51 12.60 Z" />
<path d="M 12.30 13.10 L 13.17 12.60 L 13.17 11.60 L 12.30 11.10 L 11.43 11.60 L 11.43 12.60 Z" />
<path d="M 22.14 13.10 L 23.01 12.60 L 23.01 11.60 L 22.14 11.10 L 21.27 11.60 L 21.27 12.60 Z" />
<path d="M 36.90 13.10 L 37.77 12.60 L 37.77 11.60 L 36.90 11.10 L 36.03 11.60 L 36.03 12.60 Z" />
<path d="M 41.82 13.10 L 42.69 12.60 L 42.69 11.60 L 41.82 11.10 L 40.95 11.60 L 40.95 12.60 Z" />
<path d="M 44.28 13.10 L 45.15 12.60 L 45.15 11.60 L 44.28 11.10 L 43.41 11.60 L 43.41 12.60 Z" />
<path d="M 51.66 13.10 L 52.53 12.60 L 52.53 11.60 L 51.66 11.10 L 50.79 11.60 L 50.79 12.60 Z" />
<path d="M 61.50 13.10 L 62.37 12.60 L 62.37 11.60 L 61.50 11.10 L 60.63 11.60 L 60.63 12.60 Z" />
<path d="M 63.96 13.10 L 64.83 12.60 L 64.83 11.60 L 63.96 11.10 L 63.09 11.60 L 63.09 12.60 Z" />
<path d="M 66.42 13.10 L 67.29 12.60 L 67.29 11.60 L 66.42 11.10 L 65.55 11.60 L 65.55 12.60 Z" />
<path d="M 68.88 13.10 L 69.75 12.60 L 69.75 11.60 L 68.88 11.10 L 68.01 11.60 L 68.01 12.60 Z" />
<path d="M 1.23 15.23 L 2.10 14.73 L 2.10 13.73 L 1.23 13.23 L 0.36 13.73 L 0.36 14.73 Z" />
<path d="M 23.37 15.23 L 24.24 14.73 L 24.24 13.73 L 23.37 13.23 L 22.50 13.73 L 22.50 14.73 Z" />
<path d="M 25.83 15.23 L 26.70 14.73 L 26.70 13.73 L 25.83 13.23 L 24.96 13.73 L 24.96 14.73 Z" />
<path d="M 40.59 15.23 L 41.46 14.73 L 41.46 13.73 L 40.59 13.23 L 39.72 13.73 L 39.72 14.73 Z" />
<path d="M 47.97 15.23 L 48.84 14.73 L 48.84 13.73 L 47.97 13.23 L 47.10 13.73 L 47.10 14.73 Z" />
<path d="M 12.30 17.37 L 13.17 16.87 L 13.17 15.87 L 12.30 15.37 L 11.43 15.87 L 11.43 16.87 Z" />
<path d="M 17.22 17.37 L 18.09 16.87 L 18.09 15.87 L 17.22 15.37 L 16.35 15.87 L 16.35 16.87 Z" />
<path d="M 27.06 17.37 L 27.93 16.87 L 27.93 15.87 L 27.06 15.37 L 26.19 15.87 L 26.19 16.87 Z" />
<path d="M 34.44 17.37 L 35.31 16.87 L 35.31 15.87 L 34.44 15.37 L 33.57 15.87 L 33.57 16.87 Z" />
<path d="M 41.82 17.37 L 42.69 16.87 L 42.69 15.87 L 41.82 15.37 L 40.95 15.87 L 40.95 16.87 Z" />
<path d="M 51.66 17.37 L 52.53 16.87 L 52.53 15.87 L 51.66 15.37 L 50.79 15.87 L 50.79 16.87 Z" />
<path d="M 59.04 17.37 L 59.91 16.87 L 59.91 15.87 L 59.04 15.37 L 58.17 15.87 L 58.17 16.87 Z" />
<path d="M 61.50 17.37 L 62.37 16.87 L 62.37 15.87 L 61.50 15.37 L 60.63 15.87 L 60.63 16.87 Z" />
<path d="M 63.96 17.37 L 64.83 16.87 L 64.83 15.87 L 63.96 15.37 L 63.09 15.87 L 63.09 16.87 Z" />
<path d="M 66.42 17.37 L 67.29 16.87 L 67.29 15.87 L 66.42 15.37 L 65.55 15.87 L 65.55 16.87 Z" />
<path d="M 68.88 17.37 L 69.75 16.87 L 69.75 15.87 L 68.88 15.37 L 68.01 15.87 L 68.01 16.87 Z" />
<path d="M 1.23 19.50 L 2.10 19.00 L 2.10 18.00 L 1.23 17.50 L 0.36 18.00 L 0.36 19.00 Z" />
<path d="M 3.69 19.50 L 4.56 19.00 L 4.56 18.00 L 3.69 17.50 L 2.82 18.00 L 2.82 19.00 Z" />
<path d="M 6.15 19.50 L 7.02 19.00 L 7.02 18.00 L 6.15 17.50 L 5.28 18.00 L 5.28 19.00 Z" />
<path d="M 11.07 19.50 L 11.94 19.00 L 11.94 18.00 L 11.07 17.50 L 10.20 18.00 L 10.20 19.00 Z" />
<path d="M 13.53 19.50 L 14.40 19.00 L 14.40 18.00 L 13.53 17.50 L 12.66 18.00 L 12.66 19.00 Z" />
<path d="M 15.99 19.50 L 16.86 19.00 L 16.86 18.00 L 15.99 17.50 L 15.12 18.00 L 15.12 19.00 Z" />
<path d="M 35.67 19.50 L 36.54 19.00 L 36.54 18.00 L 35.67 17.50 L 34.80 18.00 L 34.80 19.00 Z" />
<path d="M 52.89 19.50 L 53.76 19.00 L 53.76 18.00 L 52.89 17.50 L 52.02 18.00 L 52.02 19.00 Z" />
<path d="M 55.35 19.50 L 56.22 19.00 L 56.22 18.00 L 55.35 17.50 L 54.48 18.00 L 54.48 19.00 Z" />
<path d="M 19.68 21.64 L 20.55 21.14 L 20.55 20.14 L 19.68 19.64 L 18.81 20.14 L 18.81 21.14 Z" />
<path d="M 22.14 21.64 L 23.01 21.14 L 23.01 20.14 L 22.14 19.64 L 21.27 20.14 L 21.27 21.14 Z" />
<path d="M 27.06 21.64 L 27.93 21.14 L 27.93 20.14 L 27.06 19.64 L 26.19 20.14 L 26.19 21.14 Z" />
<path d="M 29.52 21.64 L 30.39 21.14 L 30.39 20.14 L 29.52 19.64 L 28.65 20.14 L 28.65 21.14 Z" />
<path d="M 49.20 21.64 L 50.07 21.14 L 50.07 20.14 L 49.20 19.64 L 48.33 20.14 L 48.33 21.14 Z" />
<path d="M 54.12 21.64 L 54.99 21.14 L 54.99 20.14 L 54.12 19.64 L 53.25 20.14 L 53.25 21.14 Z" />
<path d="M 63.96 21.64 L 64.83 21.14 L 64.83 20.14 L 63.96 19.64 L 63.09 20.14 L 63.09 21.14 Z" />
<path d="M 66.42 21.64 L 67.29 21.14 L 67.29 20.14 L 66.42 19.64 L 65.55 20.14 L 65.55 21.14 Z" />
<path d="M 1.23 23.77 L 2.10 23.27 L 2.10 22.27 L 1.23 21.77 L 0.36 22.27 L 0.36 23.27 Z" />
<path d="M 6.15 23.77 L 7.02 23.27 L 7.02 22.27 L 6.15 21.77 L 5.28 22.27 L 5.28 23.27 Z" />
<path d="M 8.61 23.77 L 9.48 23.27 L 9.48 22.27 L 8.61 21.77 L 7.74 22.27 L 7.74 23.27 Z" />
<path d="M 11.07 23.77 L 11.94 23.27 L 11.94 22.27 L 11.07 21.77 L 10.20 22.27 L 10.20 23.27 Z" />
<path d="M 13.53 23.77 L 14.40 23.27 L 14.40 22.27 L 13.53 21.77 L 12.66 22.27 L 12.66 23.27 Z" />
<path d="M 28.29 23.77 L 29.16 23.27 L 29.16 22.27 L 28.29 21.77 L 27.42 22.27 L 27.42 23.27 Z" />
<path d="M 33.21 23.77 L 34.08 23.27 L 34.08 22.27 L 33.21 21.77 L 32.34 22.27 L 32.34 23.27 Z" />
<path d="M 38.13 23.77 L 39.00 23.27 L 39.00 22.27 L 38.13 21.77 L 37.26 22.27 L 37.26 23.27 Z" />
<path d="M 40.59 23.77 L 41.46 23.27 L 41.46 22.27 L 40.59 21.77 L 39.72 22.27 L 39.72 23.27 Z" />
<path d="M 50.43 23.77 L 51.30 23.27 L 51.30 22.27 L 50.43 21.77 L 49.56 22.27 L 49.56 23.27 Z" />
<path d="M 52.89 23.77 L 53.76 23.27 L 53.76 22.27 L 52.89 21.77 L 52.02 22.27 L 52.02 23.27 Z" />
<path d="M 70.11 23.77 L 70.98 23.27 L 70.98 22.27 L 70.11 21.77 L 69.24 22.27 L 69.24 23.27 Z" />
<path d="M 72.57 23.77 L 73.44 23.27 L 73.44 22.27 L 72.57 21.77 L 71.70 22.27 L 71.70 23.27 Z" />
<path d="M 7.38 25.90 L 8.25 25.40 L 8.25 24.40 L 7.38 23.90 L 6.51 24.40 L 6.51 25.40 Z" />
<path d="M 9.84 25.90 L 10.71 25.40 L 10.71 24.40 L 9.84 23.90 L 8.97 24.40 L 8.97 25.40 Z" />
<path d="M 12.30 25.90 L 13.17 25.40 L 13.17 24.40 L 12.30 23.90 L 11.43 24.40 L 11.43 25.40 Z" />
<path d="M 22.14 25.90 L 23.01 25.40 L 23.01 24.40 L 22.14 23.90 L 21.27 24.40 L 21.27 25.40 Z" />
<path d="M 27.06 25.90 L 27.93 25.40 L 27.93 24.40 L 27.06 23.90 L 26.19 24.40 L 26.19 25.40 Z" />
<path d="M 46.74 25.90 L 47.61 25.40 L 47.61 24.40 L 46.74 23.90 L 45.87 24.40 L 45.87 25.40 Z" />
<path d="M 49.20 25.90 L 50.07 25.40 L 50.07 24.40 L 49.20 23.90 L 48.33 24.40 L 48.33 25.40 Z" />
<path d="M 51.66 25.90 L 52.53 25.40 L 52.53 24.40 L 51.66 23.90 L 50.79 24.40 L 50.79 25.40 Z" />
<path d="M 56.58 25.90 L 57.45 25.40 L 57.45 24.40 L 56.58 23.90 L 55.71 24.40 L 55.71 25.40 Z" />
<path d="M 66.42 25.90 L 67.29 25.40 L 67.29 24.40 L 66.42 23.90 L 65.55 24.40 L 65.55 25.40 Z" />
<path d="M 68.88 25.90 L 69.75 25.40 L 69.75 24.40 L 68.88 23.90 L 68.01 24.40 L 68.01 25.40 Z" />
<path d="M 71.34 25.90 L 72.21 25.40 L 72.21 24.40 L 71.34 23.90 L 70.47 24.40 L 70.47 25.40 Z" />
<path d="M 8.61 28.04 L 9.48 27.54 L 9.48 26.54 L 8.61 26.04 L 7.74 26.54 L 7.74 27.54 Z" />
<path d="M 11.07 28.04 L 11.94 27.54 L 11.94 26.54 L 11.07 26.04 L 10.20 26.54 L 10.20 27.54 Z" />
<path d="M 13.53 28.04 L 14.40 27.54 L 14.40 26.54 L 13.53 26.04 L 12.66 26.54 L 12.66 27.54 Z" />
<path d="M 15.99 28.04 L 16.86 27.54 L 16.86 26.54 L 15.99 26.04 L 15.12 26.54 L 15.12 27.54 Z" />
<path d="M 45.51 28.04 L 46.38 27.54 L 46.38 26.54 L 45.51 26.04 L 44.64 26.54 L 44.64 27.54 Z" />
<path d="M 57.81 28.04 L 58.68 27.54 L 58.68 26.54 L 57.81 26.04 L 56.94 26.54 L 56.94 27.54 Z" />
<path d="M 62.73 28.04 L 63.60 27.54 L 63.60 26.54 L 62.73 26.04 L 61.86 26.54 L 61.86 27.54 Z" />
<path d="M 65.19 28.04 L 66.06 27.54 L 66.06 26.54 L 65.19 26.04 L 64.32 26.54 L 64.32 27.54 Z" />
<path d="M 2.46 30.17 L 3.33 29.67 L 3.33 28.67 L 2.46 28.17 L 1.59 28.67 L 1.59 29.67 Z" />
<path d="M 12.30 30.17 L 13.17 29.67 L 13.17 28.67 L 12.30 28.17 L 11.43 28.67 L 11.43 29.67 Z" />
<path d="M 54.12 30.17 L 54.99 29.67 L 54.99 28.67 L 54.12 28.17 L 53.25 28.67 L 53.25 29.67 Z" />
<path d="M 56.58 30.17 L 57.45 29.67 L 57.45 28.67 L 56.58 28.17 L 55.71 28.67 L 55.71 29.67 Z" />
<path d="M 59.04 30.17 L 59.91 29.67 L 59.91 28.67 L 59.04 28.17 L 58.17 28.67 L 58.17 29.67 Z" />
<path d="M 66.42 30.17 L 67.29 29.67 L 67.29 28.67 L 66.42 28.17 L 65.55 28.67 L 65.55 29.67 Z" />
<path d="M 1.23 32.31 L 2.10 31.81 L 2.10 30.81 L 1.23 30.31 L 0.36 30.81 L 0.36 31.81 Z" />
<path d="M 20.91 32.31 L 21.78 31.81 L 21.78 30.81 L 20.91 30.31 L 20.04 30.81 L 20.04 31.81 Z" />
<path d="M 47.97 32.31 L 48.84 31.81 L 48.84 30.81 L 47.97 30.31 L 47.10 30.81 L 47.10 31.81 Z" />
<path d="M 50.43 32.31 L 51.30 31.81 L 51.30 30.81 L 50.43 30.31 L 49.56 30.81 L 49.56 31.81 Z" />
<path d="M 65.19 32.31 L 66.06 31.81 L 66.06 30.81 L 65.19 30.31 L 64.32 30.81 L 64.32 31.81 Z" />
<path d="M 12.30 34.44 L 13.17 33.94 L 13.17 32.94 L 12.30 32.44 L 11.43 32.94 L 11.43 33.94 Z" />
<path d="M 17.22 34.44 L 18.09 33.94 L 18.09 32.94 L 17.22 32.44 L 16.35 32.94 L 16.35 33.94 Z" />
<path d="M 19.68 34.44 L 20.55 33.94 L 20.55 32.94 L 19.68 32.44 L 18.81 32.94 L 18.81 33.94 Z" />
<path d="M 22.14 34.44 L 23.01 33.94 L 23.01 32.94 L 22.14 32.44 L 21.27 32.94 L 21.27 33.94 Z" />
<path d="M 56.58 34.44 L 57.45 33.94 L 57.45 32.94 L 56.58 32.44 L 55.71 32.94 L 55.71 33.94 Z" />
<path d="M 71.34 34.44 L 72.21 33.94 L 72.21 32.94 L 71.34 32.44 L 70.47 32.94 L 70.47 33.94 Z" />
<path d="M 1.23 36.57 L 2.10 36.07 L 2.10 35.07 L 1.23 34.57 L 0.36 35.07 L 0.36 36.07 Z" />
<path d="M 3.69 36.57 L 4.56 36.07 L 4.56 35.07 L 3.69 34.57 L 2.82 35.07 L 2.82 36.07 Z" />
<path d="M 6.15 36.57 L 7.02 36.07 L 7.02 35.07 L 6.15 34.57 L 5.28 35.07 L 5.28 36.07 Z" />
<path d="M 20.91 36.57 L 21.78 36.07 L 21.78 35.07 L 20.91 34.57 L 20.04 35.07 L 20.04 36.07 Z" />
<path d="M 50.43 36.57 L 51.30 36.07 L 51.30 35.07 L 50.43 34.57 L 49.56 35.07 L 49.56 36.07 Z" />
<path d="M 65.19 36.57 L 66.06 36.07 L 66.06 35.07 L 65.19 34.57 L 64.32 35.07 L 64.32 36.07 Z" />
<path d="M 67.65 36.57 L 68.52 36.07 L 68.52 35.07 L 67.65 34.57 L 66.78 35.07 L 66.78 36.07 Z" />
<path d="M 72.57 36.57 L 73.44 36.07 L 73.44 35.07 L 72.57 34.57 L 71.70 35.07 L 71.70 36.07 Z" />
<path d="M 4.92 38.71 L 5.79 38.21 L 5.79 37.21 L 4.92 36.71 L 4.05 37.21 L 4.05 38.21 Z" />
<path d="M 7.38 38.71 L 8.25 38.21 L 8.25 37.21 L 7.38 36.71 L 6.51 37.21 L 6.51 38.21 Z" />
<path d="M 51.66 38.71 L 52.53 38.21 L 52.53 37.21 L 51.66 36.71 L 50.79 37.21 L 50.79 38.21 Z" />
<path d="M 61.50 38.71 L 62.37 38.21 L 62.37 37.21 L 61.50 36.71 L 60.63 37.21 L 60.63 38.21 Z" />
<path d="M 68.88 38.71 L 69.75 38.21 L 69.75 37.21 L 68.88 36.71 L 68.01 37.21 L 68.01 38.21 Z" />
<path d="M 15.99 40.84 L 16.86 40.34 L 16.86 39.34 L 15.99 38.84 L 15.12 39.34 L 15.12 40.34 Z" />
<path d="M 20.91 40.84 L 21.78 40.34 L 21.78 39.34 L 20.91 38.84 L 20.04 39.34 L 20.04 40.34 Z" />
<path d="M 23.37 40.84 L 24.24 40.34 L 24.24 39.34 L 23.37 38.84 L 22.50 39.34 L 22.50 40.34 Z" />
<path d="M 50.43 40.84 L 51.30 40.34 L 51.30 39.34 L 50.43 38.84 L 49.56 39.34 L 49.56 40.34 Z" />
<path d="M 57.81 40.84 L 58.68 40.34 L 58.68 39.34 L 57.81 38.84 L 56.94 39.34 L 56.94 40.34 Z" />
<path d="M 62.73 40.84 L 63.60 40.34 L 63.60 39.34 L 62.73 38.84 L 61.86 39.34 L 61.86 40.34 Z" />
<path d="M 72.57 40.84 L 73.44 40.34 L 73.44 39.34 L 72.57 38.84 L 71.70 39.34 L 71.70 40.34 Z" />
<path d="M 2.46 42.98 L 3.33 42.48 L 3.33 41.48 L 2.46 40.98 L 1.59 41.48 L 1.59 42.48 Z" />
<path d="M 7.38 42.98 L 8.25 42.48 L 8.25 41.48 L 7.38 40.98 L 6.51 41.48 L 6.51 42.48 Z" />
<path d="M 12.30 42.98 L 13.17 42.48 L 13.17 41.48 L 12.30 40.98 L 11.43 41.48 L 11.43 42.48 Z" />
<path d="M 22.14 42.98 L 23.01 42.48 L 23.01 41.48 L 22.14 40.98 L 21.27 41.48 L 21.27 42.48 Z" />
<path d="M 46.74 42.98 L 47.61 42.48 L 47.61 41.48 L 46.74 40.98 L 45.87 41.48 L 45.87 42.48 Z" />
<path d="M 54.12 42.98 L 54.99 42.48 L 54.99 41.48 L 54.12 40.98 L 53.25 41.48 L 53.25 42.48 Z" />
<path d="M 56.58 42.98 L 57.45 42.48 L 57.45 41.48 L 56.58 40.98 L 55.71 41.48 L 55.71 42.48 Z" />
<path d="M 59.04 42.98 L 59.91 42.48 L 59.91 41.48 L 59.04 40.98 L 58.17 41.48 L 58.17 42.48 Z" />
<path d="M 66.42 42.98 L 67.29 42.48 L 67.29 41.48 L 66.42 40.98 L 65.55 41.48 L 65.55 42.48 Z" />
<path d="M 68.88 42.98 L 69.75 42.48 L 69.75 41.48 L 68.88 40.98 L 68.01 41.48 L 68.01 42.48 Z" />
<path d="M 6.15 45.11 L 7.02 44.61 L 7.02 43.61 L 6.15 43.11 L 5.28 43.61 L 5.28 44.61 Z" />
<path d="M 18.45 45.11 L 19.32 44.61 L 19.32 43.61 L 18.45 43.11 L 17.58 43.61 L 17.58 44.61 Z" />
<path d="M 20.91 45.11 L 21.78 44.61 L 21.78 43.61 L 20.91 43.11 L 20.04 43.61 L 20.04 44.61 Z" />
<path d="M 47.97 45.11 L 48.84 44.61 L 48.84 43.61 L 47.97 43.11 L 47.10 43.61 L 47.10 44.61 Z" />
<path d="M 50.43 45.11 L 51.30 44.61 L 51.30 43.61 L 50.43 43.11 L 49.56 43.61 L 49.56 44.61 Z" />
<path d="M 52.89 45.11 L 53.76 44.61 L 53.76 43.61 L 52.89 43.11 L 52.02 43.61 L 52.02 44.61 Z" />
<path d="M 65.19 45.11 L 66.06 44.61 L 66.06 43.61 L 65.19 43.11 L 64.32 43.61 L 64.32 44.61 Z" />
<path d="M 70.11 45.11 L 70.98 44.61 L 70.98 43.61 L 70.11 43.11 L 69.24 43.61 L 69.24 44.61 Z" />
<path d="M 46.74 47.24 L 47.61 46.74 L 47.61 45.74 L 46.74 45.24 L 45.87 45.74 L 45.87 46.74 Z" />
<path d="M 49.20 47.24 L 50.07 46.74 L 50.07 45.74 L 49.20 45.24 L 48.33 45.74 L 48.33 46.74 Z" />
<path d="M 61.50 47.24 L 62.37 46.74 L 62.37 45.74 L 61.50 45.24 L 60.63 45.74 L 60.63 46.74 Z" />
<path d="M 1.23 49.38 L 2.10 48.88 L 2.10 47.88 L 1.23 47.38 L 0.36 47.88 L 0.36 48.88 Z" />
<path d="M 6.15 49.38 L 7.02 48.88 L 7.02 47.88 L 6.15 47.38 L 5.28 47.88 L 5.28 48.88 Z" />
<path d="M 11.07 49.38 L 11.94 48.88 L 11.94 47.88 L 11.07 47.38 L 10.20 47.88 L 10.20 48.88 Z" />
<path d="M 13.53 49.38 L 14.40 48.88 L 14.40 47.88 L 13.53 47.38 L 12.66 47.88 L 12.66 48.88 Z" />
<path d="M 20.91 49.38 L 21.78 48.88 L 21.78 47.88 L 20.91 47.38 L 20.04 47.88 L 20.04 48.88 Z" />
<path d="M 25.83 49.38 L 26.70 48.88 L 26.70 47.88 L 25.83 47.38 L 24.96 47.88 L 24.96 48.88 Z" />
<path d="M 30.75 49.38 L 31.62 48.88 L 31.62 47.88 L 30.75 47.38 L 29.88 47.88 L 29.88 48.88 Z" />
<path d="M 43.05 49.38 L 43.92 48.88 L 43.92 47.88 L 43.05 47.38 L 42.18 47.88 L 42.18 48.88 Z" />
<path d="M 52.89 49.38 L 53.76 48.88 L 53.76 47.88 L 52.89 47.38 L 52.02 47.88 L 52.02 48.88 Z" />
<path d="M 57.81 49.38 L 58.68 48.88 L 58.68 47.88 L 57.81 47.38 L 56.94 47.88 L 56.94 48.88 Z" />
<path d="M 62.73 49.38 L 63.60 48.88 L 63.60 47.88 L 62.73 47.38 L 61.86 47.88 L 61.86 48.88 Z" />
<path d="M 72.57 49.38 L 73.44 48.88 L 73.44 47.88 L 72.57 47.38 L 71.70 47.88 L 71.70 48.88 Z" />
<path d="M 2.46 51.51 L 3.33 51.01 L 3.33 50.01 L 2.46 49.51 L 1.59 50.01 L 1.59 51.01 Z" />
<path d="M 12.30 51.51 L 13.17 51.01 L 13.17 50.01 L 12.30 49.51 L 11.43 50.01 L 11.43 51.01 Z" />
<path d="M 14.76 51.51 L 15.63 51.01 L 15.63 50.01 L 14.76 49.51 L 13.89 50.01 L 13.89 51.01 Z" />
<path d="M 17.22 51.51 L 18.09 51.01 L 18.09 50.01 L 17.22 49.51 L 16.35 50.01 L 16.35 51.01 Z" />
<path d="M 19.68 51.51 L 20.55 51.01 L 20.55 50.01 L 19.68 49.51 L 18.81 50.01 L 18.81 51.01 Z" />
<path d="M 27.06 51.51 L 27.93 51.01 L 27.93 50.01 L 27.06 49.51 L 26.19 50.01 L 26.19 51.01 Z" />
<path d="M 31.98 51.51 L 32.85 51.01 L 32.85 50.01 L 31.98 49.51 L 31.11 50.01 L 31.11 51.01 Z" />
<path d="M 36.90 51.51 L 37.77 51.01 L 37.77 50.01 L 36.90 49.51 L 36.03 50.01 L 36.03 51.01 Z" />
<path d="M 44.28 51.51 L 45.15 51.01 L 45.15 50.01 L 44.28 49.51 L 43.41 50.01 L 43.41 51.01 Z" />
<path d="M 46.74 51.51 L 47.61 51.01 L 47.61 50.01 L 46.74 49.51 L 45.87 50.01 L 45.87 51.01 Z" />
<path d="M 51.66 51.51 L 52.53 51.01 L 52.53 50.01 L 51.66 49.51 L 50.79 50.01 L 50.79 51.01 Z" />
<path d="M 56.58 51.51 L 57.45 51.01 L 57.45 50.01 L 56.58 49.51 L 55.71 50.01 L 55.71 51.01 Z" />
<path d="M 66.42 51.51 L 67.29 51.01 L 67.29 50.01 L 66.42 49.51 L 65.55 50.01 L 65.55 51.01 Z" />
<path d="M 71.34 51.51 L 72.21 51.01 L 72.21 50.01 L 71.34 49.51 L 70.47 50.01 L 70.47 51.01 Z" />
<path d="M 3.69 53.65 L 4.56 53.15 L 4.56 52.15 L 3.69 51.65 L 2.82 52.15 L 2.82 53.15 Z" />
<path d="M 6.15 53.65 L 7.02 53.15 L 7.02 52.15 L 6.15 51.65 L 5.28 52.15 L 5.28 53.15 Z" />
<path d="M 11.07 53.65 L 11.94 53.15 L 11.94 52.15 L 11.07 51.65 L 10.20 52.15 L 10.20 53.15 Z" />
<path d="M 38.13 53.65 L 39.00 53.15 L 39.00 52.15 L 38.13 51.65 L 37.26 52.15 L 37.26 53.15 Z" />
<path d="M 43.05 53.65 L 43.92 53.15 L 43.92 52.15 L 43.05 51.65 L 42.18 52.15 L 42.18 53.15 Z" />
<path d="M 47.97 53.65 L 48.84 53.15 L 48.84 52.15 L 47.97 51.65 L 47.10 52.15 L 47.10 53.15 Z" />
<path d="M 50.43 53.65 L 51.30 53.15 L 51.30 52.15 L 50.43 51.65 L 49.56 52.15 L 49.56 53.15 Z" />
<path d="M 55.35 53.65 L 56.22 53.15 L 56.22 52.15 L 55.35 51.65 L 54.48 52.15 L 54.48 53.15 Z" />
<path d="M 62.73 53.65 L 63.60 53.15 L 63.60 52.15 L 62.73 51.65 L 61.86 52.15 L 61.86 53.15 Z" />
<path d="M 65.19 53.65 L 66.06 53.15 L 66.06 52.15 L 65.19 51.65 L 64.32 52.15 L 64.32 53.15 Z" />
<path d="M 67.65 53.65 L 68.52 53.15 L 68.52 52.15 L 67.65 51.65 L 66.78 52.15 L 66.78 53.15 Z" />
<path d="M 70.11 53.65 L 70.98 53.15 L 70.98 52.15 L 70.11 51.65 L 69.24 52.15 L 69.24 53.15 Z" />
<path d="M 72.57 53.65 L 73.44 53.15 L 73.44 52.15 L 72.57 51.65 L 71.70 52.15 L 71.70 53.15 Z" />
<path d="M 14.76 55.78 L 15.63 55.28 L 15.63 54.28 L 14.76 53.78 L 13.89 54.28 L 13.89 55.28 Z" />
<path d="M 17.22 55.78 L 18.09 55.28 L 18.09 54.28 L 17.22 53.78 L 16.35 54.28 L 16.35 55.28 Z" />
<path d="M 19.68 55.78 L 20.55 55.28 L 20.55 54.28 L 19.68 53.78 L 18.81 54.28 L 18.81 55.28 Z" />
<path d="M 27.06 55.78 L 27.93 55.28 L 27.93 54.28 L 27.06 53.78 L 26.19 54.28 L 26.19 55.28 Z" />
<path d="M 29.52 55.78 L 30.39 55.28 L 30.39 54.28 L 29.52 53.78 L 28.65 54.28 L 28.65 55.28 Z" />
<path d="M 31.98 55.78 L 32.85 55.28 L 32.85 54.28 L 31.98 53.78 L 31.11 54.28 L 31.11 55.28 Z" />
<path d="M 34.44 55.78 L 35.31 55.28 L 35.31 54.28 L 34.44 53.78 L 33.57 54.28 L 33.57 55.28 Z" />
<path d="M 36.90 55.78 L 37.77 55.28 L 37.77 54.28 L 36.90 53.78 L 36.03 54.28 L 36.03 55.28 Z" />
<path d="M 39.36 55.78 L 40.23 55.28 L 40.23 54.28 L 39.36 53.78 L 38.49 54.28 L 38.49 55.28 Z" />
<path d="M 41.82 55.78 L 42.69 55.28 L 42.69 54.28 L 41.82 53.78 L 40.95 54.28 L 40.95 55.28 Z" />
<path d="M 44.28 55.78 L 45.15 55.28 L 45.15 54.28 L 44.28 53.78 L 43.41 54.28 L 43.41 55.28 Z" />
<path d="M 46.74 55.78 L 47.61 55.28 L 47.61 54.28 L 46.74 53.78 L 45.87 54.28 L 45.87 55.28 Z" />
<path d="M 49.20 55.78 L 50.07 55.28 L 50.07 54.28 L 49.20 53.78 L 48.33 54.28 L 48.33 55.28 Z" />
<path d="M 51.66 55.78 L 52.53 55.28 L 52.53 54.28 L 51.66 53.78 L 50.79 54.28 L 50.79 55.28 Z" />
<path d="M 54.12 55.78 L 54.99 55.28 L 54.99 54.28 L 54.12 53.78 L 53.25 54.28 L 53.25 55.28 Z" />
<path d="M 63.96 55.78 L 64.83 55.28 L 64.83 54.28 L 63.96 53.78 L 63.09 54.28 L 63.09 55.28 Z" />
<path d="M 68.88 55.78 L 69.75 55.28 L 69.75 54.28 L 68.88 53.78 L 68.01 54.28 L 68.01 55.28 Z" />
<path d="M 6.15 57.91 L 7.02 57.41 L 7.02 56.41 L 6.15 55.91 L 5.28 56.41 L 5.28 57.41 Z" />
<path d="M 8.61 57.91 L 9.48 57.41 L 9.48 56.41 L 8.61 55.91 L 7.74 56.41 L 7.74 57.41 Z" />
<path d="M 11.07 57.91 L 11.94 57.41 L 11.94 56.41 L 11.07 55.91 L 10.20 56.41 L 10.20 57.41 Z" />
<path d="M 15.99 57.91 L 16.86 57.41 L 16.86 56.41 L 15.99 55.91 L 15.12 56.41 L 15.12 57.41 Z" />
<path d="M 23.37 57.91 L 24.24 57.41 L 24.24 56.41 L 23.37 55.91 L 22.50 56.41 L 22.50 57.41 Z" />
<path d="M 25.83 57.91 L 26.70 57.41 L 26.70 56.41 L 25.83 55.91 L 24.96 56.41 L 24.96 57.41 Z" />
<path d="M 28.29 57.91 L 29.16 57.41 L 29.16 56.41 L 28.29 55.91 L 27.42 56.41 L 27.42 57.41 Z" />
<path d="M 38.13 57.91 L 39.00 57.41 L 39.00 56.41 L 38.13 55.91 L 37.26 56.41 L 37.26 57.41 Z" />
<path d="M 43.05 57.91 L 43.92 57.41 L 43.92 56.41 L 43.05 55.91 L 42.18 56.41 L 42.18 57.41 Z" />
<path d="M 47.97 57.91 L 48.84 57.41 L 48.84 56.41 L 47.97 55.91 L 47.10 56.41 L 47.10 57.41 Z" />
<path d="M 50.43 57.91 L 51.30 57.41 L 51.30 56.41 L 50.43 55.91 L 49.56 56.41 L 49.56 57.41 Z" />
<path d="M 62.73 57.91 L 63.60 57.41 L 63.60 56.41 L 62.73 55.91 L 61.86 56.41 L 61.86 57.41 Z" />
<path d="M 65.19 57.91 L 66.06 57.41 L 66.06 56.41 L 65.19 55.91 L 64.32 56.41 L 64.32 57.41 Z" />
<path d="M 67.65 57.91 L 68.52 57.41 L 68.52 56.41 L 67.65 55.91 L 66.78 56.41 L 66.78 57.41 Z" />
<path d="M 2.46 60.05 L 3.33 59.55 L 3.33 58.55 L 2.46 58.05 L 1.59 58.55 L 1.59 59.55 Z" />
<path d="M 4.92 60.05 L 5.79 59.55 L 5.79 58.55 L 4.92 58.05 L 4.05 58.55 L 4.05 59.55 Z" />
<path d="M 9.84 60.05 L 10.71 59.55 L 10.71 58.55 L 9.84 58.05 L 8.97 58.55 L 8.97 59.55 Z" />
<path d="M 12.30 60.05 L 13.17 59.55 L 13.17 58.55 L 12.30 58.05 L 11.43 58.55 L 11.43 59.55 Z" />
<path d="M 14.76 60.05 L 15.63 59.55 L 15.63 58.55 L 14.76 58.05 L 13.89 58.55 L 13.89 59.55 Z" />
<path d="M 19.68 60.05 L 20.55 59.55 L 20.55 58.55 L 19.68 58.05 L 18.81 58.55 L 18.81 59.55 Z" />
<path d="M 22.14 60.05 L 23.01 59.55 L 23.01 58.55 L 22.14 58.05 L 21.27 58.55 L 21.27 59.55 Z" />
<path d="M 24.60 60.05 L 25.47 59.55 L 25.47 58.55 L 24.60 58.05 L 23.73 58.55 L 23.73 59.55 Z" />
<path d="M 31.98 60.05 L 32.85 59.55 L 32.85 58.55 L 31.98 58.05 L 31.11 58.55 L 31.11 59.55 Z" />
<path d="M 44.28 60.05 L 45.15 59.55 L 45.15 58.55 L 44.28 58.05 L 43.41 58.55 L 43.41 59.55 Z" />
<path d="M 46.74 60.05 L 47.61 59.55 L 47.61 58.55 L 46.74 58.05 L 45.87 58.55 L 45.87 59.55 Z" />
<path d="M 51.66 60.05 L 52.53 59.55 L 52.53 58.55 L 51.66 58.05 L 50.79 58.55 L 50.79 59.55 Z" />
<path d="M 59.04 60.05 L 59.91 59.55 L 59.91 58.55 L 59.04 58.05 L 58.17 58.55 L 58.17 59.55 Z" />
<path d="M 63.96 60.05 L 64.83 59.55 L 64.83 58.55 L 63.96 58.05 L 63.09 58.55 L 63.09 59.55 Z" />
<path d="M 68.88 60.05 L 69.75 59.55 L 69.75 58.55 L 68.88 58.05 L 68.01 58.55 L 68.01 59.55 Z" />
<path d="M 71.34 60.05 L 72.21 59.55 L 72.21 58.55 L 71.34 58.05 L 70.47 58.55 L 70.47 59.55 Z" />
<path d="M 13.53 62.18 L 14.40 61.68 L 14.40 60.68 L 13.53 60.18 L 12.66 60.68 L 12.66 61.68 Z" />
<path d="M 18.45 62.18 L 19.32 61.68 L 19.32 60.68 L 18.45 60.18 L 17.58 60.68 L 17.58 61.68 Z" />
<path d="M 20.91 62.18 L 21.78 61.68 L 21.78 60.68 L 20.91 60.18 L 20.04 60.68 L 20.04 61.68 Z" />
<path d="M 25.83 62.18 L 26.70 61.68 L 26.70 60.68 L 25.83 60.18 L 24.96 60.68 L 24.96 61.68 Z" />
<path d="M 28.29 62.18 L 29.16 61.68 L 29.16 60.68 L 28.29 60.18 L 27.42 60.68 L 27.42 61.68 Z" />
<path d="M 30.75 62.18 L 31.62 61.68 L 31.62 60.68 L 30.75 60.18 L 29.88 60.68 L 29.88 61.68 Z" />
<path d="M 35.67 62.18 L 36.54 61.68 L 36.54 60.68 L 35.67 60.18 L 34.80 60.68 L 34.80 61.68 Z" />
<path d="M 40.59 62.18 L 41.46 61.68 L 41.46 60.68 L 40.59 60.18 L 39.72 60.68 L 39.72 61.68 Z" />
<path d="M 47.97 62.18 L 48.84 61.68 L 48.84 60.68 L 47.97 60.18 L 47.10 60.68 L 47.10 61.68 Z" />
<path d="M 52.89 62.18 L 53.76 61.68 L 53.76 60.68 L 52.89 60.18 L 52.02 60.68 L 52.02 61.68 Z" />
<path d="M 55.35 62.18 L 56.22 61.68 L 56.22 60.68 L 55.35 60.18 L 54.48 60.68 L 54.48 61.68 Z" />
<path d="M 57.81 62.18 L 58.68 61.68 L 58.68 60.68 L 57.81 60.18 L 56.94 60.68 L 56.94 61.68 Z" />
<path d="M 65.19 62.18 L 66.06 61.68 L 66.06 60.68 L 65.19 60.18 L 64.32 60.68 L 64.32 61.68 Z" />
<path d="M 67.65 62.18 L 68.52 61.68 L 68.52 60.68 L 67.65 60.18 L 66.78 60.68 L 66.78 61.68 Z" />
<path d="M 2.46 64.32 L 3.33 63.82 L 3.33 62.82 L 2.46 62.32 L 1.59 62.82 L 1.59 63.82 Z" />
<path d="M 4.92 64.32 L 5.79 63.82 L 5.79 62.82 L 4.92 62.32 L 4.05 62.82 L 4.05 63.82 Z" />
<path d="M 7.38 64.32 L 8.25 63.82 L 8.25 62.82 L 7.38 62.32 L 6.51 62.82 L 6.51 63.82 Z" />
<path d="M 17.22 64.32 L 18.09 63.82 L 18.09 62.82 L 17.22 62.32 L 16.35 62.82 L 16.35 63.82 Z" />
<path d="M 19.68 64.32 L 20.55 63.82 L 20.55 62.82 L 19.68 62.32 L 18.81 62.82 L 18.81 63.82 Z" />
<path d="M 24.60 64.32 L 25.47 63.82 L 25.47 62.82 L 24.60 62.32 L 23.73 62.82 L 23.73 63.82 Z" />
<path d="M 27.06 64.32 L 27.93 63.82 L 27.93 62.82 L 27.06 62.32 L 26.19 62.82 L 26.19 63.82 Z" />
<path d="M 29.52 64.32 L 30.39 63.82 L 30.39 62.82 L 29.52 62.32 L 28.65 62.82 L 28.65 63.82 Z" />
<path d="M 31.98 64.32 L 32.85 63.82 L 32.85 62.82 L 31.98 62.32 L 31.11 62.82 L 31.11 63.82 Z" />
<path d="M 41.82 64.32 L 42.69 63.82 L 42.69 62.82 L 41.82 62.32 L 40.95 62.82 L 40.95 63.82 Z" />
<path d="M 51.66 64.32 L 52.53 63.82 L 52.53 62.82 L 51.66 62.32 L 50.79 62.82 L 50.79 63.82 Z" />
<path d="M 54.12 64.32 L 54.99 63.82 L 54.99 62.82 L 54.12 62.32 L 53.25 62.82 L 53.25 63.82 Z" />
<path d="M 56.58 64.32 L 57.45 63.82 L 57.45 62.82 L 56.58 62.32 L 55.71 62.82 L 55.71 63.82 Z" />
<path d="M 59.04 64.32 L 59.91 63.82 L 59.91 62.82 L 59.04 62.32 L 58.17 62.82 L 58.17 63.82 Z" />
<path d="M 63.96 64.32 L 64.83 63.82 L 64.83 62.82 L 63.96 62.32 L 63.09 62.82 L 63.09 63.82 Z" />
<path d="M 66.42 64.32 L 67.29 63.82 L 67.29 62.82 L 66.42 62.32 L 65.55 62.82 L 65.55 63.82 Z" />
<path d="M 68.88 64.32 L 69.75 63.82 L 69.75 62.82 L 68.88 62.32 L 68.01 62.82 L 68.01 63.82 Z" />
<path d="M 71.34 64.32 L 72.21 63.82 L 72.21 62.82 L 71.34 62.32 L 70.47 62.82 L 70.47 63.82 Z" />
<path d="M 1.23 66.45 L 2.10 65.95 L 2.10 64.95 L 1.23 64.45 L 0.36 64.95 L 0.36 65.95 Z" />
<path d="M 6.15 66.45 L 7.02 65.95 L 7.02 64.95 L 6.15 64.45 L 5.28 64.95 L 5.28 65.95 Z" />
<path d="M 8.61 66.45 L 9.48 65.95 L 9.48 64.95 L 8.61 64.45 L 7.74 64.95 L 7.74 65.95 Z" />
<path d="M 11.07 66.45 L 11.94 65.95 L 11.94 64.95 L 11.07 64.45 L 10.20 64.95 L 10.20 65.95 Z" />
<path d="M 13.53 66.45 L 14.40 65.95 L 14.40 64.95 L 13.53 64.45 L 12.66 64.95 L 12.66 65.95 Z" />
<path d="M 18.45 66.45 L 19.32 65.95 L 19.32 64.95 L 18.45 64.45 L 17.58 64.95 L 17.58 65.95 Z" />
<path d="M 23.37 66.45 L 24.24 65.95 L 24.24 64.95 L 23.37 64.45 L 22.50 64.95 L 22.50 65.95 Z" />
<path d="M 25.83 66.45 L 26.70 65.95 L 26.70 64.95 L 25.83 64.45 L 24.96 64.95 L 24.96 65.95 Z" />
<path d="M 28.29 66.45 L 29.16 65.95 L 29.16 64.95 L 28.29 64.45 L 27.42 64.95 L 27.42 65.95 Z" />
<path d="M 30.75 66.45 L 31.62 65.95 L 31.62 64.95 L 30.75 64.45 L 29.88 64.95 L 29.88 65.95 Z" />
<path d="M 33.21 66.45 L 34.08 65.95 L 34.08 64.95 L 33.21 64.45 L 32.34 64.95 L 32.34 65.95 Z" />
<path d="M 35.67 66.45 L 36.54 65.95 L 36.54 64.95 L 35.67 64.45 L 34.80 64.95 L 34.80 65.95 Z" />
<path d="M 47.97 66.45 L 48.84 65.95 L 48.84 64.95 L 47.97 64.45 L 47.10 64.95 L 47.10 65.95 Z" />
<path d="M 52.89 66.45 L 53.76 65.95 L 53.76 64.95 L 52.89 64.45 L 52.02 64.95 L 52.02 65.95 Z" />
<path d="M 55.35 66.45 L 56.22 65.95 L 56.22 64.95 L 55.35 64.45 L 54.48 64.95 L 54.48 65.95 Z" />
<path d="M 60.27 66.45 L 61.14 65.95 L 61.14 64.95 L 60.27 64.45 L 59.40 64.95 L 59.40 65.95 Z" />
<path d="M 62.73 66.45 L 63.60 65.95 L 63.60 64.95 L 62.73 64.45 L 61.86 64.95 L 61.86 65.95 Z" />
<path d="M 65.19 66.45 L 66.06 65.95 L 66.06 64.95 L 65.19 64.45 L 64.32 64.95 L 64.32 65.95 Z" />
<path d="M 72.57 66.45 L 73.44 65.95 L 73.44 64.95 L 72.57 64.45 L 71.70 64.95 L 71.70 65.95 Z" />
<path d="M 7.38 68.58 L 8.25 68.08 L 8.25 67.08 L 7.38 66.58 L 6.51 67.08 L 6.51 68.08 Z" />
<path d="M 14.76 68.58 L 15.63 68.08 L 15.63 67.08 L 14.76 66.58 L 13.89 67.08 L 13.89 68.08 Z" />
<path d="M 17.22 68.58 L 18.09 68.08 L 18.09 67.08 L 17.22 66.58 L 16.35 67.08 L 16.35 68.08 Z" />
<path d="M 22.14 68.58 L 23.01 68.08 L 23.01 67.08 L 22.14 66.58 L 21.27 67.08 L 21.27 68.08 Z" />
<path d="M 24.60 68.58 L 25.47 68.08 L 25.47 67.08 L 24.60 66.58 L 23.73 67.08 L 23.73 68.08 Z" />
<path d="M 27.06 68.58 L 27.93 68.08 L 27.93 67.08 L 27.06 66.58 L 26.19 67.08 L 26.19 68.08 Z" />
<path d="M 29.52 68.58 L 30.39 68.08 L 30.39 67.08 L 29.52 66.58 L 28.65 67.08 L 28.65 68.08 Z" />
<path d="M 31.98 68.58 L 32.85 68.08 L 32.85 67.08 L 31.98 66.58 L 31.11 67.08 L 31.11 68.08 Z" />
<path d="M 36.90 68.58 L 37.77 68.08 L 37.77 67.08 L 36.90 66.58 L 36.03 67.08 L 36.03 68.08 Z" />
<path d="M 39.36 68.58 L 40.23 68.08 L 40.23 67.08 L 39.36 66.58 L 38.49 67.08 L 38.49 68.08 Z" />
<path d="M 44.28 68.58 L 45.15 68.08 L 45.15 67.08 L 44.28 66.58 L 43.41 67.08 L 43.41 68.08 Z" />
<path d="M 46.74 68.58 L 47.61 68.08 L 47.61 67.08 L 46.74 66.58 L 45.87 67.08 L 45.87 68.08 Z" />
<path d="M 51.66 68.58 L 52.53 68.08 L 52.53 67.08 L 51.66 66.58 L 50.79 67.08 L 50.79 68.08 Z" />
<path d="M 56.58 68.58 L 57.45 68.08 L 57.45 67.08 L 56.58 66.58 L 55.71 67.08 L 55.71 68.08 Z" />
<path d="M 63.96 68.58 L 64.83 68.08 L 64.83 67.08 L 63.96 66.58 L 63.09 67.08 L 63.09 68.08 Z" />
<path d="M 66.42 68.58 L 67.29 68.08 L 67.29 67.08 L 66.42 66.58 L 65.55 67.08 L 65.55 68.08 Z" />
<path d="M 68.88 68.58 L 69.75 68.08 L 69.75 67.08 L 68.88 66.58 L 68.01 67.08 L 68.01 68.08 Z" />
<path d="M 6.15 70.72 L 7.02 70.22 L 7.02 69.22 L 6.15 68.72 L 5.28 69.22 L 5.28 70.22 Z" />
<path d="M 11.07 70.72 L 11.94 70.22 L 11.94 69.22 L 11.07 68.72 L 10.20 69.22 L 10.20 70.22 Z" />
<path d="M 13.53 70.72 L 14.40 70.22 L 14.40 69.22 L 13.53 68.72 L 12.66 69.22 L 12.66 70.22 Z" />
<path d="M 30.75 70.72 L 31.62 70.22 L 31.62 69.22 L 30.75 68.72 L 29.88 69.22 L 29.88 70.22 Z" />
<path d="M 33.21 70.72 L 34.08 70.22 L 34.08 69.22 L 33.21 68.72 L 32.34 69.22 L 32.34 70.22 Z" />
<path d="M 35.67 70.72 L 36.54 70.22 L 36.54 69.22 L 35.67 68.72 L 34.80 69.22 L 34.80 70.22 Z" />
<path d="M 38.13 70.72 L 39.00 70.22 L 39.00 69.22 L 38.13 68.72 L 37.26 69.22 L 37.26 70.22 Z" />
<path d="M 43.05 70.72 L 43.92 70.22 L 43.92 69.22 L 43.05 68.72 L 42.18 69.22 L 42.18 70.22 Z" />
<path d="M 45.51 70.72 L 46.38 70.22 L 46.38 69.22 L 45.51 68.72 L 44.64 69.22 L 44.64 70.22 Z" />
<path d="M 52.89 70.72 L 53.76 70.22 L 53.76 69.22 L 52.89 68.72 L 52.02 69.22 L 52.02 70.22 Z" />
<path d="M 65.19 70.72 L 66.06 70.22 L 66.06 69.22 L 65.19 68.72 L 64.32 69.22 L 64.32 70.22 Z" />
<circle cx="35.76" cy="35.60" r="10.85" />
<circle cx="35.76" cy="35.60" r="8.97" fill="#FFFFFF" />
<circle cx="35.76" cy="35.60" r="7.10" />
<circle cx="35.76" cy="35.60" r="5.22" fill="#FFFFFF" />
<circle cx="35.76" cy="35.60" r="3.31" />
<circle cx="35.76" cy="35.60" r="1.43" fill="#FFFFFF" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

View File

@ -0,0 +1,33 @@
7D 02 08 9C
10 10 0A 00
2C C9 B2 48
81 18 90 00
2C 0A 0A CC
E8 82 C8 F0
80 60 90 00
0A 24 89 F0
EE 02 06 00
01 B0 14 60
BC 15 8C 0C
38 A0 3A 38
1E 00 21 60
88 00 07 20
80 80 18 20
0B 80 02 08
E0 80 08 34
60 00 08 90
02 C0 09 44
A8 80 27 30
21 80 1C 28
00 00 30 80
AC A8 45 44
8F 2A 6A 28
68 01 5A 7C
07 3F FC 50
3A 71 58 70
DD C8 69 58
05 BA 97 30
E3 78 8F 78
BD 7E 16 E4
26 FB 6A 70
2C 0F 64 20

View File

@ -38,6 +38,7 @@ static void test_large(int index, int debug) {
int ret; int ret;
struct item { struct item {
int option_1; int option_1;
int option_2;
char *pattern; char *pattern;
int length; int length;
char* primary; char* primary;
@ -47,14 +48,38 @@ static void test_large(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { -1, "1", 132, "", 0, 33, 30 }, // 138 according to ISO/IEC 16023:2000 TODO: investigate (see also test_fuzz) /* 0*/ { -1, -1, "1", 138, "", 0, 33, 30 }, // Mode 4 (138 agrees with ISO/IEC 16023:2000)
/* 1*/ { -1, "1", 133, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 1*/ { -1, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { -1, "A", 93, "", 0, 33, 30 }, /* 2*/ { -1, -1, "A", 93, "", 0, 33, 30 },
/* 3*/ { -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 3*/ { -1, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 4*/ { -1, "\001", 91, "", 0, 33, 30 }, /* 4*/ { -1, -1, "\001", 91, "", 0, 33, 30 },
/* 5*/ { -1, "\001", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 5*/ { -1, -1, "\001", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { -1, "\200", 91, "", 0, 33, 30 }, /* 6*/ { -1, -1, "\200", 91, "", 0, 33, 30 },
/* 7*/ { -1, "\200", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 7*/ { -1, -1, "\200", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 8*/ { 2, -1, "1", 126, "123456789123123", 0, 33, 30 },
/* 9*/ { 2, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 10*/ { 2, -1, "A", 84, "123456789123123", 0, 33, 30 },
/* 11*/ { 2, -1, "A", 85, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 12*/ { 2, 96, "1", 109, "123456789123123", 0, 33, 30 },
/* 13*/ { 2, 96, "1", 110, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 14*/ { 3, -1, "1", 126, "ABCDEF123123", 0, 33, 30 },
/* 15*/ { 3, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 16*/ { 3, -1, "A", 84, "ABCDEF123123", 0, 33, 30 },
/* 17*/ { 3, -1, "A", 85, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 18*/ { 3, 96, "1", 109, "ABCDEF123123", 0, 33, 30 },
/* 19*/ { 3, 96, "1", 110, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 20*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30 }, // Mode 2
/* 21*/ { 0, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 22*/ { 0, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, // Mode 3
/* 23*/ { 0, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 24*/ { 5, -1, "1", 113, "", 0, 33, 30 }, // Extra EEC
/* 25*/ { 5, -1, "1", 114, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 26*/ { 5, -1, "A", 77, "", 0, 33, 30 },
/* 27*/ { 5, -1, "A", 78, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 28*/ { 6, -1, "1", 138, "", 0, 33, 30 },
/* 29*/ { 6, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 30*/ { 6, -1, "A", 93, "", 0, 33, 30 },
/* 31*/ { 6, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
@ -70,7 +95,7 @@ static void test_large(int index, int debug) {
testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf));
int length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, -1, -1, -1 /*output_options*/, data_buf, data[i].length, debug); int length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
strcpy(symbol->primary, data[i].primary); strcpy(symbol->primary, data[i].primary);
ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
@ -87,6 +112,97 @@ static void test_large(int index, int debug) {
testFinish(); testFinish();
} }
static void test_input(int index, int generate, int debug) {
testStart("");
int ret;
struct item {
int input_mode;
int eci;
int option_1;
int option_2;
char *data;
int length;
char *primary;
int ret;
int expected_width;
char *expected;
char *comment;
};
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "", 0, 30, "(144) 04 01 21 21 21 21 21 21 21 21 08 0E 19 2B 20 0C 24 06 32 1C 21 21 21 21 21 21 21 21", "" },
/* 1*/ { UNICODE_MODE, -1, 2, -1, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "" },
/* 2*/ { UNICODE_MODE, -1, 2, -1, "A", -1, "A123456", ZINT_ERROR_INVALID_DATA, 0, "Error 555: Non-numeric postcode in Primary Message", "" },
/* 3*/ { UNICODE_MODE, -1, 2, -1, "A", -1, "1123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", "1-digit postcode" },
/* 4*/ { UNICODE_MODE, -1, 2, -1, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", "9-digit postcode" },
/* 5*/ { UNICODE_MODE, -1, 2, -1, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "10-digit postcode" },
/* 6*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "1123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", "1-digit postcode" },
/* 7*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", "9-digit postcode" },
/* 8*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "10-digit postcode" },
/* 9*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "0-digit postcode" },
/* 10*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "12345678123456", 0, 30, "(144) 22 13 21 31 0B 00 32 1E 20 1C 04 14 07 30 10 07 08 28 1D 09 01 21 21 21 21 21 21 21", "8-digit postcode" },
/* 11*/ { UNICODE_MODE, -1, 3, -1, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "" },
/* 12*/ { UNICODE_MODE, -1, 3, -1, "A", -1, "A123456", 0, 30, "(144) 03 08 08 08 08 18 30 1E 20 1C 22 35 1C 0F 02 1A 26 04 10 31 01 21 21 21 21 21 21 21", "1-alphanumeric postcode" },
/* 13*/ { UNICODE_MODE, -1, 3, -1, "A", -1, "1123456", 0, 30, "(144) 03 08 08 08 08 18 3C 1E 20 1C 13 37 07 2C 26 2D 18 29 3F 2C 01 21 21 21 21 21 21 21", "1-digit postcode" },
/* 14*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "A123456", 0, 30, "(144) 03 08 08 08 08 18 30 1E 20 1C 22 35 1C 0F 02 1A 26 04 10 31 01 21 21 21 21 21 21 21", "1-alphanumeric postcode" },
/* 15*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "ABCDEF123456", 0, 30, "(144) 23 11 01 31 20 10 30 1E 20 1C 3C 1D 22 03 19 15 0F 20 0F 2A 01 21 21 21 21 21 21 21", "6-alphanumeric postcode" },
/* 16*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "ABCDEFG123456", 0, 30, "(144) 23 11 01 31 20 10 30 1E 20 1C 3C 1D 22 03 19 15 0F 20 0F 2A 01 21 21 21 21 21 21 21", "7-alphanumeric postcode truncated" },
/* 17*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "ABCDE123456", 0, 30, "(144) 03 18 01 31 20 10 30 1E 20 1C 0F 38 38 1A 39 10 2F 37 22 12 01 21 21 21 21 21 21 21", "5-alphanumeric postcode" },
/* 18*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "AAAAAA 840001", 0, 30, "(144) 13 10 10 10 10 10 00 12 07 00 17 36 2E 38 04 29 16 0D 27 16 01 21 21 21 21 21 21 21", "6-alphanumeric postcode with padding" },
/* 19*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "AAAAA A840001", 0, 30, "(144) 03 18 10 10 10 10 00 12 07 00 19 07 29 31 26 01 23 2C 2E 07 01 21 21 21 21 21 21 21", "7-alphanumeric with embedded padding truncated" },
/* 20*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "AA\015AAA840001", ZINT_ERROR_INVALID_DATA, 0, "Error 556: Invalid characters in postcode in Primary Message", "Alphanumeric postcode with CR" },
/* 21*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "A#%-/A840001", 0, 30, "(144) 13 30 1B 1B 39 18 00 12 07 00 3F 1E 25 07 2A 1E 14 3C 28 2D 01 21 21 21 21 21 21 21", "Alphanumeric postcode with non-control Code A chars" },
/* 22*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "1A23456", ZINT_ERROR_INVALID_DATA, 0, "Error 552: Non-numeric country code or service class in Primary Message", "Non-numeric country code" },
/* 23*/ { UNICODE_MODE, -1, -1, -1, "A", -1, "12345678912345A", ZINT_ERROR_INVALID_DATA, 0, "Error 552: Non-numeric country code or service class in Primary Message", "Non-numeric service class" },
/* 24*/ { UNICODE_MODE, -1, 0, -1, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", "Auto-determine mode 2" },
/* 25*/ { UNICODE_MODE, -1, 0, -1, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 554: Primary Message empty", "Auto-determine mode 2/3 requires primary message" },
/* 26*/ { UNICODE_MODE, -1, 0, -1, "A", -1, "A23456123456", 0, 30, "(144) 23 1D 0D 3D 2C 1C 30 1E 20 1C 24 35 30 31 2A 0D 17 14 16 3D 01 21 21 21 21 21 21 21", "Auto-determine mode 3" },
/* 27*/ { UNICODE_MODE, -1, -1, 100, "A", -1, "123456123456", 0, 30, "(144) 02 10 22 07 00 20 31 1E 20 1C 0E 29 13 1B 0D 26 36 25 3B 22 3B 2A 29 3B 28 1E 30 31", "SCM prefix version" },
/* 28*/ { UNICODE_MODE, -1, -1, 101, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 557: Invalid SCM prefix version", "SCM prefix version" },
/* 29*/ { UNICODE_MODE, 3, -1, -1, "A", -1, "", 0, 30, "(144) 04 1B 03 01 21 21 21 21 21 21 2F 14 23 21 05 24 27 00 24 0C 21 21 21 21 21 21 21 21", "" },
/* 30*/ { UNICODE_MODE, 32, -1, -1, "A", -1, "", 0, 30, "(144) 04 1B 20 20 01 21 21 21 21 21 3D 15 0F 30 0D 22 24 35 22 06 21 21 21 21 21 21 21 21", "" },
/* 31*/ { UNICODE_MODE, 1024, -1, -1, "A", -1, "", 0, 30, "(144) 04 1B 30 10 00 01 21 21 21 21 11 2F 15 10 1D 29 06 35 14 2B 21 21 21 21 21 21 21 21", "" },
/* 32*/ { UNICODE_MODE, 32768, -1, -1, "A", -1, "", 0, 30, "(144) 04 1B 38 08 00 00 01 21 21 21 10 30 3A 04 26 23 0E 21 3D 0F 21 21 21 21 21 21 21 21", "" },
/* 33*/ { UNICODE_MODE, -1, 1, -1, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Invalid MaxiCode Mode", "" },
};
int data_size = sizeof(data) / sizeof(struct item);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
strcpy(symbol->primary, data[i].primary);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
printf(" /*%3d*/ { %s, %d, %d, %d, \"%s\", %d, \"%s\", %s, %d, \"%s\", \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2,
testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, data[i].primary,
testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment);
} else {
if (ret < 5) {
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
}
assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_encode(int index, int generate, int debug) { static void test_encode(int index, int generate, int debug) {
testStart(""); testStart("");
@ -95,7 +211,9 @@ static void test_encode(int index, int generate, int debug) {
struct item { struct item {
int input_mode; int input_mode;
int option_1; int option_1;
int option_2;
char *data; char *data;
int length;
char* primary; char* primary;
int ret; int ret;
@ -105,7 +223,7 @@ static void test_encode(int index, int generate, int debug) {
char *expected; char *expected;
}; };
struct item data[] = { struct item data[] = {
/* 0*/ { -1, -1, "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...", "", 0, 33, 30, "ISO/IEC 16023:2000 Figure 2", /* 0*/ { -1, -1, -1, "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...", -1, "", 0, 33, 30, "ISO/IEC 16023:2000 Figure 2, same",
"011111010000001000001000100111" "011111010000001000001000100111"
"000100000001000000001010000000" "000100000001000000001010000000"
"001011001100100110110010010010" "001011001100100110110010010010"
@ -140,7 +258,7 @@ static void test_encode(int index, int generate, int debug) {
"001001101111101101101010011100" "001001101111101101101010011100"
"001011000000111101100100001000" "001011000000111101100100001000"
}, },
/* 1*/ { -1, 4, "MaxiCode (19 chars)", "", 0, 33, 30, "ISO/IEC 16023:2000 Figure H1 **NOT SAME** TODO: investigate", /* 1*/ { -1, 4, -1, "MaxiCode (19 chars)", -1, "", 0, 33, 30, "ISO/IEC 16023:2000 Figure H1 **NOT SAME** different encodation (figure uses '3 Shift A' among other differences)",
"001101011111011100000010101111" "001101011111011100000010101111"
"101100010001001100010000001100" "101100010001001100010000001100"
"101100001010001111001001111101" "101100001010001111001001111101"
@ -175,6 +293,251 @@ static void test_encode(int index, int generate, int debug) {
"010110010110001110100000010100" "010110010110001110100000010100"
"010011110011000001010111100111" "010011110011000001010111100111"
}, },
/* 2*/ { DATA_MODE | ESCAPE_MODE, 2, 96, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "152382802840001", 0, 33, 30, "ISO/IEC 16023:2000 Figure B2 **NOT SAME** uses different encodation (figure uses Latch B/Latch A instead of Shift B for '>\\R', and precedes PAD chars with Latch B)",
"110101110110111110111111101111"
"010101010111000011011000010010"
"110110110001001010101010010011"
"111000101010101111111111111100"
"001111000010110010011000000011"
"001001110010101010100000000000"
"111011111110111111101111111110"
"100110000011001001110000001010"
"010001100010101010101001110001"
"110111100011010000011011111100"
"001100110011110000001110101001"
"101110101000000001011111011000"
"101010000000000000010110111100"
"111101100000000000011011100010"
"101010010000000000000110011101"
"001000010000000000011100011110"
"010011001000000000001000001010"
"000000101000000000001010000010"
"000100111100000000001110101010"
"000010101100000000001000110010"
"100000111010000000011101100011"
"101000100000000000110110100000"
"001000001110100101100110100101"
"011001110010101001100000001000"
"000010100010110001010101011010"
"100111000011111000001001011000"
"110010001001010010101100011101"
"001001110101110100011001110010"
"011111010011101100111101010011"
"111111101111101010101101111000"
"101001110101110111010111000011"
"010110101101000001111000100110"
"110110100000010000001011110011"
},
/* 3*/ { -1, 3, -1, "CEN", -1, "B1050056999", 0, 33, 30, "ISO/IEC 16023:2000 B.1 Example (primary only given, data arbitrary); verified manually against BWIP and tec-it",
"000000010101010101010101010111"
"001011000000000000000000000010"
"111001101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000001"
"101010101010101010101010101010"
"010101010101010101010101010100"
"000000000000000000000000000010"
"101010101010101010101010101000"
"010101010111100000100101010110"
"000000000001110000010100000010"
"101010101000000011010010101010"
"010101111100000000100001010110"
"000000001100000000011000000010"
"101010100100000000011110101001"
"010101011000000000000001010110"
"000000101000000000001000000001"
"101010110000000000001010101010"
"010101010000000000011101010101"
"000000101000000000011100000000"
"101010111100000000001010101001"
"010101011110000000011101010110"
"000000001110000001111000000011"
"101010101011011001000110101010"
"010101010101010101011100100010"
"000000000000000000000011011100"
"101010101010101010101001110100"
"111011101110000110101011010110"
"100001011111111101000011100111"
"110100001000001101100010100110"
"110110111111011110000011011111"
"010010001001110010000101000010"
"010001011010000011010010011100"
},
/* 4*/ { UNICODE_MODE | ESCAPE_MODE, -1, -1, "Comité Européen de Normalisation\034rue de Stassart 36\034B-1050 BRUXELLES\034TEL +3225196811", -1, "", 0, 33, 30, "ISO/IEC 16023:2000 Example F.5 **NOT SAME** uses different encodation (2 Shift A among other things)",
"010010100010110000000100001111"
"001010001100110110111110100110"
"001010011100101010011100100000"
"000000100010000000001000000110"
"111101100000011100110011110001"
"011110001011100010100111010010"
"101010000100001101101000101001"
"110010101110100100001000000000"
"000110101100100000110010111110"
"111101111111111000110110100000"
"100000111001111010010010000011"
"011100111100000000101100011010"
"100001101110000000101111111101"
"110011000100000000111100001010"
"000110010000000000010110001010"
"101010010000000000001000011100"
"011000001000000000001000000010"
"001001010000000000001101000000"
"000000010000000000010100101000"
"101111110100000000011110001100"
"100000000010000000011010110011"
"101001010010000001011100001010"
"001101000010001011110111101010"
"111111001010000001100100100000"
"001000001101010101010010111001"
"111001000000000000001010100000"
"010001101010101010101010110001"
"011011000011100001011001101100"
"101100000001111010000001100011"
"110001001100011100110111011010"
"011110010010101101110100000100"
"001011110011100001001001101100"
"000010111011111010110011000011"
},
/* 5*/ { -1, -1, -1, "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", -1, "", 0, 33, 30, "Numeric compaction, verified manually against BWIPP and tec-it",
"010111101101010111101101010111"
"111011110110111011110110111010"
"001111111101001111111101001100"
"101101010111101101010111101100"
"111110111001111110111001111100"
"111111000111111111000111111110"
"110101011110110101011110110110"
"011011101111011011101111011000"
"110100111111110100111111110101"
"010111101111111100110111010100"
"111001111011011110011111101100"
"000111111110000000111011110000"
"011110100110000000000111010101"
"101111001000000000110101101110"
"111111110100000000000011010001"
"010111111000000000001110110110"
"111001101000000000001011111001"
"000111010000000000001011111100"
"011110011000000000011011010101"
"101111000100000000010001101100"
"111111100110000000100111010010"
"010101110100000001010110110110"
"101110011010101111111011111011"
"110001110111110101111011111110"
"111011010101111111110000111011"
"111101101110110101010001001000"
"111111010011111010101111110011"
"000101011000111100010001000010"
"011110001101100001011010110010"
"101110000100010011000001001000"
"100000001010110100100110001100"
"111010101011001101111001011010"
"011110011111000011101011111011"
},
/* 6*/ { -1, 5, -1, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\037\237\240\242\243\244\245\246\247\251\255\256\266\225\226\227\230\231\232\233\234\235\236", 51, "", 0, 33, 30, "Mode 5 set E; single difference from BWIPP - Zint uses Latch B at end before padding instead of Latch A",
"000000000000000000101010101011"
"100101010111111111000000001000"
"110010011100100111001001110001"
"010101010101011010101010101000"
"010110101010001101010110101000"
"100011011000110101100011011000"
"010101010101111111111111111110"
"010111111111000000001010101010"
"011100100111001001110010011101"
"010101011011110000001011111100"
"000000001111110010010011010100"
"101010100110000010001011100000"
"010101110010000000001101010100"
"000000111000000000001000000010"
"101010110100000000001110101011"
"010101010000000000001001010100"
"000000001000000000001000000001"
"101010100000000000001010101010"
"010101100000000000001001010100"
"000000000000000000000000000000"
"101010100100000000011110101010"
"101100110100000001110101100110"
"011100010010110101110111010011"
"110011100010110001001000101010"
"110001101111100011111110101000"
"111110010101110100010110100000"
"110001110000111101111111000011"
"111001000100001011001011011110"
"101010110110100001110011010011"
"100100100001001100000001100000"
"010101001001000001111101011111"
"110110111000001000001101100100"
"100100010010000000010001010111"
},
/* 7*/ { -1, 6, -1, "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\241\250\253\257\260\264\267\270\273\277\212\213\214\215\216\217\220\221\222\223\224", -1, "", 0, 33, 30, "Mode 6 set D; single difference from BWIPP as above - Zint uses Latch B at end before padding instead of Latch A",
"000000000000000000101010101011"
"100101010111111111000000001000"
"110010011100100111001001110001"
"010101010101010110101010101000"
"101010100000000001010110101000"
"110110001101100001100011011000"
"010101010101010111111111111111"
"010101011111111100000000101000"
"001001110010011100100111001001"
"010111110111110000000011111100"
"000011011011110010011101101000"
"101011101110000001000100110100"
"010101110000000000000001010100"
"000000101000000000000000000010"
"101010110100000000000110101010"
"010101010000000000001001010100"
"000000001000000000001000000011"
"101010100000000000001010101000"
"010101101100000000001001010110"
"000000101000000000001000000010"
"101010010110000000011010101001"
"010101011100000000111101010100"
"000000001110110111011000000011"
"101010100110110001100110101010"
"010101010101010101011101101100"
"000000000000000000001000010000"
"101010101010101010100110000001"
"101000111111101000101010110100"
"010100110011011001101100111001"
"100101010011111101011110000010"
"111101110110111101001001010101"
"011110000010110111001011110110"
"001110010110111101101011110010"
},
/* 8*/ { -1, 6, -1, "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\252\254\261\262\263\265\271\272\274\275\276\200\201\202\203\204\205\206\207\210\211", -1, "", 0, 33, 30, "Mode 6 set C; single difference from BWIPP as above - Zint uses Latch B at end before padding instead of Latch A",
"000000000000000000101010101011"
"100101010111111111000000001000"
"110010011100100111001001110001"
"010101010101010110101010101000"
"101010100000000001010110101000"
"110110001101100001100011011000"
"010101010101010111111111111111"
"010101011111111100000000101000"
"001001110010011100100111001001"
"010111111111110000000111111100"
"000011010111110010010001101000"
"101011101010000001001100110100"
"010101100000000000000101010100"
"000000011000000000000100000010"
"101010110100000000000010101010"
"010101010000000000001001010100"
"000000001000000000001000000011"
"101010100000000000001010101000"
"010101110000000000001001010110"
"000000111100000000001100000010"
"101010110000000000010110101001"
"010101010100000000101101010100"
"000000001010110101011000000011"
"101010100010110001010110101010"
"010101010101010101011101101100"
"000000000000000000001000010000"
"101010101010101010100110000001"
"101000111111101000101010110100"
"010100110011011001101100111001"
"100101010011111101011110000010"
"111101110110111101001001010101"
"011110000010110111001011110110"
"001110010110111101101011110010"
},
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
@ -187,16 +550,16 @@ static void test_encode(int index, int generate, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
int length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, data[i].input_mode, -1 /*eci*/, data[i].option_1, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); int length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
strcpy(symbol->primary, data[i].primary); strcpy(symbol->primary, data[i].primary);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) { if (generate) {
printf(" /*%3d*/ { %s, %d, \"%s\", \"%s\", %s, %d, %d, \"%s\",\n", printf(" /*%3d*/ { %s, %d, %d, \"%s\", %d, \"%s\", %s, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_1, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].primary, i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment); data[i].primary, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n"); testUtilModulesDump(symbol, " ", "\n");
printf(" },\n"); printf(" },\n");
} else { } else {
@ -204,11 +567,9 @@ static void test_encode(int index, int generate, int debug) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
if (ret == 0) { int width, row;
int width, row; ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
}
} }
} }
@ -236,7 +597,7 @@ static void test_best_supported_set(int index, int generate, int debug) {
char *expected; char *expected;
}; };
struct item data[] = { struct item data[] = {
/* 0*/ { "am.//ab,\034TA# z\015!", 0, 100, 100, 0, 33, 30, "TODO: Better data and verify expected", /* 0*/ { "am.//ab,\034TA# z\015!", 0, 100, 100, 0, 33, 30, "Different encodation than BWIPP, same number of codewords",
"111010000101111000111101010111" "111010000101111000111101010111"
"111110000000010100111000000000" "111110000000010100111000000000"
"110000101100110100111010101011" "110000101100110100111010101011"
@ -322,17 +683,18 @@ static void test_fuzz(int index, int debug) {
int ret; int ret;
struct item { struct item {
int eci;
char *data; char *data;
int length; int length;
int ret; int ret;
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { "\223\223\223\223\223\200\000\060\060\020\122\104\060\343\000\000\040\104\104\104\104\177\377\040\000\324\336\000\000\000\000\104\060\060\060\060\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\060\104\104\000\000\000\040\104\104\104\104\177\377\377\377\324\336\000\000\000\000\104\377\104\001\104\104\104\104\104\104\233\233\060\060\060\060\060\060\060\060\060\325\074", 107, ZINT_ERROR_TOO_LONG }, // Original OSS-Fuzz triggering data /* 0*/ { -1, "\223\223\223\223\223\200\000\060\060\020\122\104\060\343\000\000\040\104\104\104\104\177\377\040\000\324\336\000\000\000\000\104\060\060\060\060\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\060\104\104\000\000\000\040\104\104\104\104\177\377\377\377\324\336\000\000\000\000\104\377\104\001\104\104\104\104\104\104\233\233\060\060\060\060\060\060\060\060\060\325\074", 107, ZINT_ERROR_TOO_LONG }, // Original OSS-Fuzz triggering data
/* 1*/ { "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789", -1, ZINT_ERROR_TOO_LONG }, // Add 6 lowercase a's so 6 SHIFTS inserted so 6 + 138 (max input len) = 144 and numbers come at end of buffer /* 1*/ { -1, "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789", -1, ZINT_ERROR_TOO_LONG }, // Add 6 lowercase a's so 6 SHIFTS inserted so 6 + 138 (max input len) = 144 and numbers come at end of buffer
/* 2*/ { "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789A", -1, ZINT_ERROR_TOO_LONG }, /* 2*/ { -1, "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789A", -1, ZINT_ERROR_TOO_LONG },
/* 3*/ { "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", -1, ZINT_ERROR_TOO_LONG }, // First 6 chars ignored for number compaction so max numeric digits appears to be 135 not 138 (for mode 4 anyway) TODO: investigate further /* 3*/ { -1, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", -1, ZINT_ERROR_TOO_LONG },
/* 4*/ { "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345", -1, 0 }, /* 4*/ { 32768, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", -1, ZINT_ERROR_TOO_LONG },
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = sizeof(data) / sizeof(struct item);
@ -343,13 +705,7 @@ static void test_fuzz(int index, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_MAXICODE; int length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
symbol->debug |= debug;
int length = data[i].length;
if (length == -1) {
length = strlen(data[i].data);
}
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
@ -360,13 +716,88 @@ static void test_fuzz(int index, int debug) {
testFinish(); testFinish();
} }
#include <time.h>
#define TEST_PERF_ITERATIONS 1000
// Not a real test, just performance indicator
static void test_perf(int index, int debug) {
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
return;
}
int ret;
struct item {
int symbology;
int input_mode;
int option_1;
int option_2;
char *data;
char *primary;
int ret;
int expected_rows;
int expected_width;
char *comment;
};
struct item data[] = {
/* 0*/ { BARCODE_MAXICODE, UNICODE_MODE | ESCAPE_MODE, -1, -1,
"1Z34567890\\GUPSN\\G102562\\G034\\G\\G1/1\\G\\GY\\G2201 Second St\\GFt Myers\\GFL\\R\\E",
"339010000840001", 0, 33, 30, "Mode 2" },
};
int data_size = ARRAY_SIZE(data);
clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer;
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
diff_encode = diff_buffer = 0;
for (int j = 0; j < TEST_PERF_ITERATIONS; j++) {
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
int length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
strcpy(symbol->primary, data[i].primary);
start = clock();
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
diff_encode += clock() - start;
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
start = clock();
ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/);
diff_buffer += clock() - start;
assert_zero(ret, "i:%d ZBarcode_Buffer ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
ZBarcode_Delete(symbol);
}
printf("%s: diff_encode %gms, diff_buffer %gms\n", data[i].comment, diff_encode * 1000.0 / CLOCKS_PER_SEC, diff_buffer * 1000.0 / CLOCKS_PER_SEC);
total_encode += diff_encode;
total_buffer += diff_buffer;
}
if (index != -1) {
printf("totals: encode %gms, buffer %gms\n", total_encode * 1000.0 / CLOCKS_PER_SEC, total_buffer * 1000.0 / CLOCKS_PER_SEC);
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_large", test_large, 1, 0, 1 }, { "test_large", test_large, 1, 0, 1 },
{ "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_best_supported_set", test_best_supported_set, 1, 1, 1 }, { "test_best_supported_set", test_best_supported_set, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
{ "test_perf", test_perf, 1, 0, 1 },
}; };
testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testRun(argc, argv, funcs, ARRAY_SIZE(funcs));

View File

@ -63,6 +63,7 @@ static void test_print(int index, int generate, int debug) {
/* 1*/ { BARCODE_QRCODE, 2, 1, -1, "1234567890", "qr_v1_m" }, /* 1*/ { BARCODE_QRCODE, 2, 1, -1, "1234567890", "qr_v1_m" },
/* 2*/ { BARCODE_DOTCODE, -1, -1, 5, "2741", "dotcode_aim_fig7" }, /* 2*/ { BARCODE_DOTCODE, -1, -1, 5, "2741", "dotcode_aim_fig7" },
/* 3*/ { BARCODE_ULTRA, -1, -1, -1, "A", "ultracode_a" }, /* 3*/ { BARCODE_ULTRA, -1, -1, -1, "A", "ultracode_a" },
/* 4*/ { BARCODE_MAXICODE, -1, -1, -1, "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...", "maxicode_fig_2" },
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = sizeof(data) / sizeof(struct item);

View File

@ -55,7 +55,7 @@ extern "C" {
struct zint_vector_circle { struct zint_vector_circle {
float x, y, diameter; float x, y, diameter;
int colour; int colour; /* Non-zero for draw with background colour */
struct zint_vector_circle *next; /* Pointer to next circle */ struct zint_vector_circle *next; /* Pointer to next circle */
}; };

View File

@ -436,6 +436,7 @@ static char help_message[] = "zint tcl(stub,obj) dll\n"
" -secure integer: EC Level (PDF417, QR)\n" " -secure integer: EC Level (PDF417, QR)\n"
" -mode: Structured primary data mode (Maxicode, Composite)\n" " -mode: Structured primary data mode (Maxicode, Composite)\n"
" -primary text: Structured primary data (Maxicode, Composite)\n" " -primary text: Structured primary data (Maxicode, Composite)\n"
" -scmvv: Prefix secondary message with [)>\\R01\\Gvv (vv 00..99) (MaxiCode)\n"
" -dotty bool: use dots instead of boxes for matrix codes\n" " -dotty bool: use dots instead of boxes for matrix codes\n"
" -dotsize number: radius ratio of dots from 0.01 to 1.0\n" " -dotsize number: radius ratio of dots from 0.01 to 1.0\n"
" -scale double: Scale the image to this factor\n" " -scale double: Scale the image to this factor\n"
@ -634,13 +635,13 @@ static int Encode(Tcl_Interp *interp, int objc,
"-gssep", "-height", "-init", "-mode", "-nobackground", "-notext", "-gssep", "-height", "-init", "-mode", "-nobackground", "-notext",
"-primary", "-rotate", "-rows", "-scale", "-secure", "-smalltext", "-primary", "-rotate", "-rows", "-scale", "-secure", "-smalltext",
"-square", "-to", "-vers", "-whitesp", "-fullmultibyte", "-square", "-to", "-vers", "-whitesp", "-fullmultibyte",
"-separator", "-mask", NULL}; "-separator", "-mask", "-scmvv", NULL};
enum iOption { enum iOption {
iAddonGap, iBarcode, iBG, iBind, iBold, iBorder, iBox, iCols, iAddonGap, iBarcode, iBG, iBind, iBold, iBorder, iBox, iCols,
iDMRE, iDotSize, iDotty, iECI, iFG, iFormat, iGSSep, iHeight, iDMRE, iDotSize, iDotty, iECI, iFG, iFormat, iGSSep, iHeight,
iInit, iMode, iNoBackground, iNoText, iPrimary, iRotate, iRows, iInit, iMode, iNoBackground, iNoText, iPrimary, iRotate, iRows,
iScale, iSecure, iSmallText, iSquare, iTo, iVers, iScale, iSecure, iSmallText, iSquare, iTo, iVers,
iWhiteSp, iFullMultiByte, iSeparator, iMask iWhiteSp, iFullMultiByte, iSeparator, iMask, iSCMvv
}; };
int optionIndex; int optionIndex;
int intValue; int intValue;
@ -706,14 +707,8 @@ static int Encode(Tcl_Interp *interp, int objc,
case iVers: case iVers:
case iWhiteSp: case iWhiteSp:
case iSeparator: case iSeparator:
/* >> Int */
if (TCL_OK != Tcl_GetIntFromObj(interp, objv[optionPos+1],
&intValue))
{
fError = 1;
}
break;
case iMask: case iMask:
case iSCMvv:
/* >> Int */ /* >> Int */
if (TCL_OK != Tcl_GetIntFromObj(interp, objv[optionPos+1], if (TCL_OK != Tcl_GetIntFromObj(interp, objv[optionPos+1],
&intValue)) &intValue))
@ -890,6 +885,15 @@ static int Encode(Tcl_Interp *interp, int objc,
Mask = intValue + 1; Mask = intValue + 1;
} }
break; break;
case iSCMvv:
if (intValue < 0 || intValue > 99) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("SCM version out of range", -1));
fError = 1;
} else {
hSymbol->option_2 = intValue + 1;
}
break;
case iCols: case iCols:
case iVers: case iVers:
/* >> Int in Option 2 */ /* >> Int in Option 2 */

View File

@ -47,7 +47,7 @@ stacked: A stacked symbol consists of multiple linear symbols placed one above
error correction data. Examples include PDF417. error correction data. Examples include PDF417.
matrix: A matrix symbol is one based on a (usually square) grid of elements. matrix: A matrix symbol is one based on a (usually square) grid of elements.
Examples include Data Matrix, but Maxicode and DotCode are also Examples include Data Matrix, but MaxiCode and DotCode are also
considered matrix symbologies. considered matrix symbologies.
X-dimension: The X-dimension of a symbol is the size (usually the width) of the X-dimension: The X-dimension of a symbol is the size (usually the width) of the
@ -216,8 +216,8 @@ Escape Character | ASCII Equivalent | Interpretation
\f | 0x0C | Form Feed \f | 0x0C | Form Feed
\r | 0x0D | Carriage Return \r | 0x0D | Carriage Return
\e | 0x1B | Escape \e | 0x1B | Escape
\G | 0x1D | Group Selector \G | 0x1D | Group Separator
\R | 0x1E | Record Selector \R | 0x1E | Record Separator
\\ | 0x5C | Backslash \\ | 0x5C | Backslash
\xNN | 0xNN | Any other 8-bit character \xNN | 0xNN | Any other 8-bit character
| | where NN is hexadecimal | | where NN is hexadecimal
@ -293,7 +293,7 @@ Numeric Value | Barcode Name
53 | Pharmacode Two-Track 53 | Pharmacode Two-Track
55 | PDF417 55 | PDF417
56 | Compact PDF417 56 | Compact PDF417
57 | Maxicode 57 | MaxiCode
58 | QR Code 58 | QR Code
60 | Code 128 (Subset B) 60 | Code 128 (Subset B)
63 | Australia Post Standard Customer 63 | Australia Post Standard Customer
@ -425,7 +425,7 @@ vector files so that...
zint --bg=ff0000 --fg=ffffff00 ... zint --bg=ff0000 --fg=ffffff00 ...
will give different results for PNG and SVG. Experimentation is advised! will give different results for PNG and SVG. Experimentation is advised!
Also note that these options don't work properly with Maxicode yet. Also note that these options don't work properly with MaxiCode yet.
In addition the --nobackground option will simply remove the background from In addition the --nobackground option will simply remove the background from
PNG, GIF, SVG, EMF and EPS files. PNG, GIF, SVG, EMF and EPS files.
@ -1090,7 +1090,7 @@ Value |
53 | BARCODE_PHARMA_TWO | Pharmacode Two-Track 53 | BARCODE_PHARMA_TWO | Pharmacode Two-Track
55 | BARCODE_PDF417 | PDF417 55 | BARCODE_PDF417 | PDF417
56* | BARCODE_PDF417COMP | Compact PDF417 (Truncated PDF417) 56* | BARCODE_PDF417COMP | Compact PDF417 (Truncated PDF417)
57 | BARCODE_MAXICODE | Maxicode 57 | BARCODE_MAXICODE | MaxiCode
58 | BARCODE_QRCODE | QR Code 58 | BARCODE_QRCODE | QR Code
60 | BARCODE_CODE128B | Code 128 (Subset B) 60 | BARCODE_CODE128B | Code 128 (Subset B)
63 | BARCODE_AUSPOST | Australia Post Standard Customer 63 | BARCODE_AUSPOST | Australia Post Standard Customer
@ -1286,7 +1286,7 @@ The version parts are separated by hundreds. For instance, version "2.9.1" is
returned as "20901". returned as "20901".
[1] This value is ignored for Australia Post 4-State Barcodes, POSTNET, PLANET, [1] This value is ignored for Australia Post 4-State Barcodes, POSTNET, PLANET,
USPS Intelligent Mail, RM4SCC, PDF417, Data Matrix, Maxicode, QR Code, GS1 USPS Intelligent Mail, RM4SCC, PDF417, Data Matrix, MaxiCode, QR Code, GS1
DataBar Stacked, PDF417 and MicroPDF417 - all of which have a fixed height. DataBar Stacked, PDF417 and MicroPDF417 - all of which have a fixed height.
[2] This value is ignored for Code 16k and Codablock-F. Special considerations [2] This value is ignored for Code 16k and Codablock-F. Special considerations
@ -2288,12 +2288,12 @@ The following example creates a symbol from data saved as an ISO-8859-2 file:
zint -o upnqr.png -b 143 --border=5 --scale=3 --binary -i ./upn.txt zint -o upnqr.png -b 143 --border=5 --scale=3 --binary -i ./upn.txt
6.6.6 Maxicode (ISO 16023) 6.6.6 MaxiCode (ISO 16023)
-------------------------- --------------------------
Developed by UPS the Maxicode symbology employs a grid of hexagons surrounding Developed by UPS the MaxiCode symbology employs a grid of hexagons surrounding
a 'bulls-eye' finder pattern. This symbology is designed for the identification a 'bulls-eye' finder pattern. This symbology is designed for the identification
of parcels. Maxicode symbols can be encoded in one of five modes. In modes 2 of parcels. MaxiCode symbols can be encoded in one of five modes. In modes 2
and 3 Maxicode symbols are composed of two parts named the primary and and 3 MaxiCode symbols are composed of two parts named the primary and
secondary messages. The primary message consists of a structured data field secondary messages. The primary message consists of a structured data field
which includes various data about the package being sent and the secondary which includes various data about the package being sent and the secondary
message usually consists of address data in a data structure. The format of the message usually consists of address data in a data structure. The format of the
@ -2304,8 +2304,9 @@ Characters | Meaning
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
1 - 9 | Postcode data which can consist of up to 9 digits (for mode 2) 1 - 9 | Postcode data which can consist of up to 9 digits (for mode 2)
| or up to 6 alphanumeric characters (for mode 3). Remaining | or up to 6 alphanumeric characters (for mode 3). Remaining
| unused characters should be filled with the SPACE character | unused characters can be filled with the SPACE character
| (ASCII 32). | (ASCII 32) or omitted (if omitted adjust the following
| character positions).
10 - 12 | Three digit country code according to ISO 3166. 10 - 12 | Three digit country code according to ISO 3166.
13 - 15 | Three digit service code. This depends on your parcel courier. 13 - 15 | Three digit service code. This depends on your parcel courier.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
@ -2313,36 +2314,48 @@ Characters | Meaning
The primary message can be set at the command prompt using the --primary= The primary message can be set at the command prompt using the --primary=
switch. The secondary message uses the normal data entry method. For example: switch. The secondary message uses the normal data entry method. For example:
zint -o test.eps -b 57 --primary='999999999840012' -d 'Secondary Message Here' zint -o test.eps -b 57 --primary="999999999840012" -d "Secondary Message Here"
When using the API the primary message must be placed in the symbol->primary When using the API the primary message must be placed in the symbol->primary
string. The secondary is entered in the same way as described in section 5.2. string. The secondary is entered in the same way as described in section 5.2.
When either of these modes is selected Zint will analyse the primary message When either of these modes is selected Zint will analyse the primary message
and select either mode 2 or mode 3 as appropriate. and select either mode 2 or mode 3 as appropriate.
Modes 4 to 6 can be accessed using the --mode= switch or by setting option_1. As a convenience the secondary message for modes 2 and 3 can be set to be
Modes 4 to 6 do not require a primary message. For example: prefixed by the ISO 15434 Format "01" (transportation) sequence "[)>\R01\Gvv",
where "vv" is a 2-digit version, by using the --scmvv= switch or by setting
option_2 = vv + 1. For example to use the common version "96" (ASC MH10/SC 8):
zint -o test.eps -b 57 --mode=4 -d 'A MaxiCode Message in Mode 4' zint -b 57 --primary="152382802840001" --scmvv=96 --esc \
-d "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G1 MAIN ST\GTOWN\GNY\R\E"
will prefix "[)>\R01\G96" to the secondary message. ("\R", "\G" and "\E" are the
escape sequences for Record Separator, Group Separator and End of Transmission
respectively - see section 4.1.)
Modes 4 to 6 can be accessed using the --mode= switch or by setting option_1.
Modes 4 to 6 do not have a primary message. For example:
zint -o test.eps -b 57 --mode=4 -d "A MaxiCode Message in Mode 4"
Mode 6 is reserved for the maintenance of scanner hardware and should not be Mode 6 is reserved for the maintenance of scanner hardware and should not be
used to encode user data. used to encode user data.
This symbology uses Latin-1 character encoding by default but also supports the This symbology uses Latin-1 character encoding by default but also supports the
ECI encoding mechanism. The maximum length of text which can be placed in a ECI encoding mechanism. The maximum length of text which can be placed in a
Maxicode symbol depends on the type of characters used in the text. MaxiCode symbol depends on the type of characters used in the text.
Example maximum data lengths are given in the table below: Example maximum data lengths are given in the table below:
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Mode | Maximum Data Lenth | Maximum Data Length | Number of Error Mode | Maximum Data Length | Maximum Data Length | Number of Error
| for Capital Letters | for Numeric Digits | Correction Codewords | for Capital Letters | for Numeric Digits | Correction Codewords
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
2* | 84 | 126 | 50 2* | 84 | 126 | 50
3* | 84 | 126 | 50 3* | 84 | 126 | 50
4 | 93 | 135 | 50 4 | 93 | 138 | 50
5 | 77 | 110 | 66 5 | 77 | 113 | 66
6 | 93 | 135 | 50 6 | 93 | 138 | 50
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
* - secondary only * - secondary only
@ -2999,7 +3012,7 @@ international standards:
> ISO/IEC 16022:2006 Information technology - Automatic identification and data > ISO/IEC 16022:2006 Information technology - Automatic identification and data
capture techniques - Data Matrix ECC200 bar code symbology specification capture techniques - Data Matrix ECC200 bar code symbology specification
> ISO/IEC 16023:2000 Information technology - International symbology > ISO/IEC 16023:2000 Information technology - International symbology
specification Maxicode specification MaxiCode
> ISO/IEC 16388:2007 Information technology - Automatic identification and data > ISO/IEC 16388:2007 Information technology - Automatic identification and data
capture techniques - Code 39 bar code symbology specification capture techniques - Code 39 bar code symbology specification
> ISO/IEC 18004:2015 Information technology - Automatic identification and data > ISO/IEC 18004:2015 Information technology - Automatic identification and data

View File

@ -44,7 +44,7 @@ static void types(void) {
" 2: Standard 2of5 53: Pharma Two-Track 97: Micro QR Code\n" " 2: Standard 2of5 53: Pharma Two-Track 97: Micro QR Code\n"
" 3: Interleaved 2of5 55: PDF417 98: HIBC Code 128\n" " 3: Interleaved 2of5 55: PDF417 98: HIBC Code 128\n"
" 4: IATA 2of5 56: Compact PDF417 99: HIBC Code 39\n" " 4: IATA 2of5 56: Compact PDF417 99: HIBC Code 39\n"
" 6: Data Logic 57: Maxicode 102: HIBC Data Matrix\n" " 6: Data Logic 57: MaxiCode 102: HIBC Data Matrix\n"
" 7: Industrial 2of5 58: QR Code 104: HIBC QR Code\n" " 7: Industrial 2of5 58: QR Code 104: HIBC QR Code\n"
" 8: Code 39 60: Code 128-B 106: HIBC PDF417\n" " 8: Code 39 60: Code 128-B 106: HIBC PDF417\n"
" 9: Extended Code 39 63: AP Standard Customer 108: HIBC MicroPDF417\n" " 9: Extended Code 39 63: AP Standard Customer 108: HIBC MicroPDF417\n"
@ -126,15 +126,16 @@ static void usage(void) {
" --init Create reader initialisation/programming symbol\n" " --init Create reader initialisation/programming symbol\n"
" --mask=NUMBER Set masking pattern to use (QR/Han Xin)\n" " --mask=NUMBER Set masking pattern to use (QR/Han Xin)\n"
" --mirror Use batch data to determine filename\n" " --mirror Use batch data to determine filename\n"
" --mode=NUMBER Set encoding mode (Maxicode/Composite)\n" " --mode=NUMBER Set encoding mode (MaxiCode/Composite)\n"
" --nobackground Remove background (PNG/SVG/EPS only)\n" " --nobackground Remove background (PNG/SVG/EPS only)\n"
" --notext Remove human readable text\n" " --notext Remove human readable text\n"
" -o, --output=FILE Send output to FILE. Default is out.png\n" " -o, --output=FILE Send output to FILE. Default is out.png\n"
" --primary=STRING Set structured primary message (Maxicode/Composite)\n" " --primary=STRING Set structured primary message (MaxiCode/Composite)\n"
" -r, --reverse Reverse colours (white on black)\n" " -r, --reverse Reverse colours (white on black)\n"
" --rotate=NUMBER Rotate symbol by NUMBER degrees\n" " --rotate=NUMBER Rotate symbol by NUMBER degrees\n"
" --rows=NUMBER Set number of rows (Codablock-F)\n" " --rows=NUMBER Set number of rows (Codablock-F)\n"
" --scale=NUMBER Adjust size of X-dimension\n" " --scale=NUMBER Adjust size of X-dimension\n"
" --scmvv=NUMBER Prefix SCM with [)>\\R01\\Gvv (vv is NUMBER) (MaxiCode)\n"
" --secure=NUMBER Set error correction level (ECC)\n" " --secure=NUMBER Set error correction level (ECC)\n"
" --separator=NUMBER Set height of row separator bars (stacked symbologies)\n" " --separator=NUMBER Set height of row separator bars (stacked symbologies)\n"
" --small Use small text\n" " --small Use small text\n"
@ -272,7 +273,7 @@ static void set_extension(char *file, char *filetype) {
file[251] = '\0'; file[251] = '\0';
} }
strcat(file, "."); strcat(file, ".");
strcat(file, filetype); strncat(file, filetype, 3);
} }
static char *raster_filetypes[] = { static char *raster_filetypes[] = {
@ -308,7 +309,7 @@ static int batch_process(struct zint_symbol *symbol, char *filename, int mirror_
if (symbol->outfile[0] == '\0') { if (symbol->outfile[0] == '\0') {
strcpy(format_string, "~~~~~."); strcpy(format_string, "~~~~~.");
strcat(format_string, filetype); strncat(format_string, filetype, 3);
} else { } else {
strcpy(format_string, symbol->outfile); strcpy(format_string, symbol->outfile);
set_extension(format_string, filetype); set_extension(format_string, filetype);
@ -438,7 +439,7 @@ static int batch_process(struct zint_symbol *symbol, char *filename, int mirror_
output_file[o] = '.'; output_file[o] = '.';
output_file[o + 1] = '\0'; output_file[o + 1] = '\0';
strcat(output_file, filetype); strncat(output_file, filetype, 3);
} }
strcpy(symbol->outfile, output_file); strcpy(symbol->outfile, output_file);
@ -487,6 +488,7 @@ int main(int argc, char **argv) {
int fullmultibyte = 0; int fullmultibyte = 0;
int mask = 0; int mask = 0;
int separator = 0; int separator = 0;
int scmvv = -1;
int addon_gap = 0; int addon_gap = 0;
char filetype[4] = {0}; char filetype[4] = {0};
int i; int i;
@ -551,6 +553,7 @@ int main(int argc, char **argv) {
{"rotate", 1, 0, 0}, {"rotate", 1, 0, 0},
{"rows", 1, 0, 0}, {"rows", 1, 0, 0},
{"scale", 1, 0, 0}, {"scale", 1, 0, 0},
{"scmvv", 1, 0, 0},
{"secure", 1, 0, 0}, {"secure", 1, 0, 0},
{"separator", 1, 0, 0}, {"separator", 1, 0, 0},
{"small", 0, 0, 0}, {"small", 0, 0, 0},
@ -646,6 +649,22 @@ int main(int argc, char **argv) {
my_symbol->scale = 1.0f; my_symbol->scale = 1.0f;
} }
} }
if (!strcmp(long_options[option_index].name, "scmvv")) {
error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) {
fprintf(stderr, "Error 149: Invalid Structured Carrier Message version value\n");
exit(1);
}
scmvv = atoi(optarg);
if (scmvv < 0 || scmvv > 99) {
/* Version 00-99 only */
fprintf(stderr, "Warning 150: Invalid version (vv) for Structured Carrier Message, ignoring\n");
fflush(stderr);
scmvv = -1;
} else {
my_symbol->option_2 = scmvv + 1;
}
}
if (!strcmp(long_options[option_index].name, "separator")) { if (!strcmp(long_options[option_index].name, "separator")) {
error_number = validator(NESET, optarg); error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) { if (error_number == ZINT_ERROR_INVALID_DATA) {

View File

@ -35,22 +35,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="lblMaxiPrimary">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>P&amp;rimary Message:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtMaxiPrimary</cstring>
</property>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="cmbMaxiMode"> <widget class="QComboBox" name="cmbMaxiMode">
<property name="sizePolicy"> <property name="sizePolicy">
@ -84,6 +68,30 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="lblMaxiPrimary">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>P&amp;rimary Message:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtMaxiPrimary</cstring>
</property>
<property name="toolTip">
<string>Format &quot;PPPPPPPPPCCCSSS&quot; where
P is postcode of up to 9 digits for Mode 2 or
6 alphanumerics for Mode 3 (will truncate) and
C is 3-digit country code
S is 3-digit service class
(ignored if disabled)</string>
</property>
</widget>
</item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="txtMaxiPrimary"> <widget class="QLineEdit" name="txtMaxiPrimary">
<property name="enabled"> <property name="enabled">
@ -100,6 +108,63 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkMaxiSCMVV">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Enable S&amp;CM Prefix</string>
</property>
<property name="toolTip">
<string>Prefix Secondary Carrier Message with &quot;[)&gt;\R01\Gvv&quot;
where &quot;vv&quot; is version given below
(ignored if disabled)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblMaxiSCMVV">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>SCM Pre&amp;fix Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>spnMaxiSCMVV</cstring>
</property>
<property name="toolTip">
<string>Version &quot;vv&quot; to place at end of SCM prefix (default 96)
(ignored if disabled)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spnMaxiSCMVV">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>99</number>
</property>
<property name="value">
<number>96</number>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@ -96,7 +96,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags fl)
"Japanese Postal Barcode", "Japanese Postal Barcode",
"Korean Postal Barcode", "Korean Postal Barcode",
"LOGMARS", "LOGMARS",
"Maxicode (ISO 16023)", "MaxiCode (ISO 16023)",
"MicroPDF417 (ISO 24728) (and HIBC)", "MicroPDF417 (ISO 24728) (and HIBC)",
"Micro QR Code", "Micro QR Code",
"MSI Plessey", "MSI Plessey",
@ -881,10 +881,13 @@ void MainWindow::change_options()
return; return;
m_optionWidget=uiload.load(&file); m_optionWidget=uiload.load(&file);
file.close(); file.close();
tabMain->insertTab(1,m_optionWidget,tr("Maxicod&e")); tabMain->insertTab(1,m_optionWidget,tr("MaxiCod&e"));
connect(m_optionWidget->findChild<QObject*>("cmbMaxiMode"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(m_optionWidget->findChild<QObject*>("cmbMaxiMode"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbMaxiMode"), SIGNAL(currentIndexChanged( int )), SLOT(maxi_primary())); connect(m_optionWidget->findChild<QObject*>("cmbMaxiMode"), SIGNAL(currentIndexChanged( int )), SLOT(maxi_primary()));
connect(m_optionWidget->findChild<QObject*>("txtMaxiPrimary"), SIGNAL(textChanged( const QString& )), SLOT(update_preview())); connect(m_optionWidget->findChild<QObject*>("txtMaxiPrimary"), SIGNAL(textChanged( const QString& )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("chkMaxiSCMVV"), SIGNAL(stateChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("chkMaxiSCMVV"), SIGNAL(stateChanged( int )), SLOT(maxi_primary()));
connect(m_optionWidget->findChild<QObject*>("spnMaxiSCMVV"), SIGNAL(valueChanged( int )), SLOT(update_preview()));
} }
if (symbology == BARCODE_CHANNEL) if (symbology == BARCODE_CHANNEL)
@ -1078,12 +1081,19 @@ void MainWindow::maxi_primary()
{ {
if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_MAXICODE) if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_MAXICODE)
return; return;
QCheckBox *chkMaxiSCMVV = m_optionWidget->findChild<QCheckBox*>("chkMaxiSCMVV");
if(m_optionWidget->findChild<QComboBox*>("cmbMaxiMode")->currentIndex() == 0) { if(m_optionWidget->findChild<QComboBox*>("cmbMaxiMode")->currentIndex() == 0) {
m_optionWidget->findChild<QLabel*>("lblMaxiPrimary")->setEnabled(true); m_optionWidget->findChild<QLabel*>("lblMaxiPrimary")->setEnabled(true);
m_optionWidget->findChild<QLineEdit*>("txtMaxiPrimary")->setEnabled(true); m_optionWidget->findChild<QLineEdit*>("txtMaxiPrimary")->setEnabled(true);
chkMaxiSCMVV->setEnabled(true);
m_optionWidget->findChild<QLabel*>("lblMaxiSCMVV")->setEnabled(chkMaxiSCMVV->isChecked());
m_optionWidget->findChild<QSpinBox*>("spnMaxiSCMVV")->setEnabled(chkMaxiSCMVV->isChecked());
} else { } else {
m_optionWidget->findChild<QLabel*>("lblMaxiPrimary")->setEnabled(false); m_optionWidget->findChild<QLabel*>("lblMaxiPrimary")->setEnabled(false);
m_optionWidget->findChild<QLineEdit*>("txtMaxiPrimary")->setEnabled(false); m_optionWidget->findChild<QLineEdit*>("txtMaxiPrimary")->setEnabled(false);
chkMaxiSCMVV->setEnabled(false);
m_optionWidget->findChild<QLabel*>("lblMaxiSCMVV")->setEnabled(false);
m_optionWidget->findChild<QSpinBox*>("spnMaxiSCMVV")->setEnabled(false);
} }
} }
@ -1142,7 +1152,7 @@ void MainWindow::update_preview()
} else { } else {
m_bc.bc.setText(txtData->text()); m_bc.bc.setText(txtData->text());
} }
m_bc.bc.setSecurityLevel(0); m_bc.bc.setOption1(-1);
m_bc.bc.setOption2(0); m_bc.bc.setOption2(0);
m_bc.bc.setOption3(0); m_bc.bc.setOption3(0);
chkData->setEnabled(true); chkData->setEnabled(true);
@ -1254,7 +1264,7 @@ void MainWindow::update_preview()
case BARCODE_PDF417: case BARCODE_PDF417:
m_bc.bc.setOption2(m_optionWidget->findChild<QComboBox*>("cmbPDFCols")->currentIndex()); m_bc.bc.setOption2(m_optionWidget->findChild<QComboBox*>("cmbPDFCols")->currentIndex());
m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbPDFECC")->currentIndex()-1); m_bc.bc.setOption1(m_optionWidget->findChild<QComboBox*>("cmbPDFECC")->currentIndex() - 1);
if(m_optionWidget->findChild<QRadioButton*>("radPDFStand")->isChecked()) if(m_optionWidget->findChild<QRadioButton*>("radPDFStand")->isChecked())
m_bc.bc.setSymbol(BARCODE_PDF417); m_bc.bc.setSymbol(BARCODE_PDF417);
@ -1286,7 +1296,7 @@ void MainWindow::update_preview()
m_bc.bc.setOption2(m_optionWidget->findChild<QComboBox*>("cmbAztecSize")->currentIndex() + 1); m_bc.bc.setOption2(m_optionWidget->findChild<QComboBox*>("cmbAztecSize")->currentIndex() + 1);
if(m_optionWidget->findChild<QRadioButton*>("radAztecECC")->isChecked()) if(m_optionWidget->findChild<QRadioButton*>("radAztecECC")->isChecked())
m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbAztecECC")->currentIndex() + 1); m_bc.bc.setOption1(m_optionWidget->findChild<QComboBox*>("cmbAztecECC")->currentIndex() + 1);
set_gs1_mode(m_optionWidget->findChild<QRadioButton*>("radAztecGS1")->isChecked()); set_gs1_mode(m_optionWidget->findChild<QRadioButton*>("radAztecGS1")->isChecked());
if(m_optionWidget->findChild<QRadioButton*>("radAztecHIBC")->isChecked()) if(m_optionWidget->findChild<QRadioButton*>("radAztecHIBC")->isChecked())
@ -1362,7 +1372,7 @@ void MainWindow::update_preview()
// Height selection uses option 1 in zint_symbol // Height selection uses option 1 in zint_symbol
item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfHeight")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfHeight")->currentIndex();
if (item_val) { if (item_val) {
m_bc.bc.setSecurityLevel(item_val); m_bc.bc.setOption1(item_val);
} }
// Row separator height selection uses option 3 in zint_symbol // Row separator height selection uses option 3 in zint_symbol
item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfRowSepHeight")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfRowSepHeight")->currentIndex();
@ -1372,7 +1382,6 @@ void MainWindow::update_preview()
break; break;
case BARCODE_DATAMATRIX: case BARCODE_DATAMATRIX:
m_bc.bc.setSecurityLevel(1);
if(m_optionWidget->findChild<QRadioButton*>("radDM200HIBC")->isChecked()) if(m_optionWidget->findChild<QRadioButton*>("radDM200HIBC")->isChecked())
m_bc.bc.setSymbol(BARCODE_HIBC_DM); m_bc.bc.setSymbol(BARCODE_HIBC_DM);
else else
@ -1425,7 +1434,7 @@ void MainWindow::update_preview()
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbQRECC")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbQRECC")->currentIndex();
if (item_val) { if (item_val) {
m_bc.bc.setSecurityLevel(item_val); m_bc.bc.setOption1(item_val);
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbQRMask")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbQRMask")->currentIndex();
if (item_val) { if (item_val) {
@ -1444,7 +1453,7 @@ void MainWindow::update_preview()
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbMQRECC")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbMQRECC")->currentIndex();
if (item_val) { if (item_val) {
m_bc.bc.setSecurityLevel(item_val); m_bc.bc.setOption1(item_val);
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbMQRMask")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbMQRMask")->currentIndex();
if (item_val) { if (item_val) {
@ -1466,7 +1475,7 @@ void MainWindow::update_preview()
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbRMQRECC")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbRMQRECC")->currentIndex();
if (item_val) { if (item_val) {
m_bc.bc.setSecurityLevel(item_val * 2); // Levels 2 (M) and 4 (H) only m_bc.bc.setOption1(item_val * 2); // Levels 2 (M) and 4 (H) only
} }
if (m_optionWidget->findChild<QCheckBox*>("chkRMQRFullMultibyte")->isChecked()) { if (m_optionWidget->findChild<QCheckBox*>("chkRMQRFullMultibyte")->isChecked()) {
m_bc.bc.setOption3(ZINT_FULL_MULTIBYTE); m_bc.bc.setOption3(ZINT_FULL_MULTIBYTE);
@ -1481,7 +1490,7 @@ void MainWindow::update_preview()
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbGridECC")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbGridECC")->currentIndex();
if (item_val) { if (item_val) {
m_bc.bc.setSecurityLevel(item_val); m_bc.bc.setOption1(item_val);
} }
if (m_optionWidget->findChild<QCheckBox*>("chkGridFullMultibyte")->isChecked()) { if (m_optionWidget->findChild<QCheckBox*>("chkGridFullMultibyte")->isChecked()) {
m_bc.bc.setOption3(ZINT_FULL_MULTIBYTE); m_bc.bc.setOption3(ZINT_FULL_MULTIBYTE);
@ -1492,11 +1501,15 @@ void MainWindow::update_preview()
m_bc.bc.setSymbol(BARCODE_MAXICODE); m_bc.bc.setSymbol(BARCODE_MAXICODE);
if(m_optionWidget->findChild<QComboBox*>("cmbMaxiMode")->currentIndex() == 0) if(m_optionWidget->findChild<QComboBox*>("cmbMaxiMode")->currentIndex() == 0)
{ {
m_bc.bc.setSecurityLevel(2); m_bc.bc.setOption1(0); /* Auto-determine mode 2 or 3 from primary message (checks that it isn't empty) */
m_bc.bc.setPrimaryMessage(m_optionWidget->findChild<QLineEdit*>("txtMaxiPrimary")->text()); m_bc.bc.setPrimaryMessage(m_optionWidget->findChild<QLineEdit*>("txtMaxiPrimary")->text());
QCheckBox *chkMaxiSCMVV = m_optionWidget->findChild<QCheckBox*>("chkMaxiSCMVV");
if (chkMaxiSCMVV->isEnabled() && chkMaxiSCMVV->isChecked()) {
m_bc.bc.setOption2(m_optionWidget->findChild<QSpinBox*>("spnMaxiSCMVV")->value() + 1);
}
} }
else else
m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbMaxiMode")->currentIndex() + 3); m_bc.bc.setOption1(m_optionWidget->findChild<QComboBox*>("cmbMaxiMode")->currentIndex() + 3);
break; break;
case BARCODE_CHANNEL: case BARCODE_CHANNEL:
@ -1531,7 +1544,7 @@ void MainWindow::update_preview()
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbHXECC")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbHXECC")->currentIndex();
if (item_val) { if (item_val) {
m_bc.bc.setSecurityLevel(item_val); m_bc.bc.setOption1(item_val);
} }
item_val = m_optionWidget->findChild<QComboBox*>("cmbHXMask")->currentIndex(); item_val = m_optionWidget->findChild<QComboBox*>("cmbHXMask")->currentIndex();
if (item_val) { if (item_val) {
@ -1545,7 +1558,7 @@ void MainWindow::update_preview()
case BARCODE_ULTRA: case BARCODE_ULTRA:
m_bc.bc.setSymbol(BARCODE_ULTRA); m_bc.bc.setSymbol(BARCODE_ULTRA);
if(m_optionWidget->findChild<QRadioButton*>("radUltraEcc")->isChecked()) if(m_optionWidget->findChild<QRadioButton*>("radUltraEcc")->isChecked())
m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbUltraEcc")->currentIndex() + 1); m_bc.bc.setOption1(m_optionWidget->findChild<QComboBox*>("cmbUltraEcc")->currentIndex() + 1);
set_gs1_mode(m_optionWidget->findChild<QRadioButton*>("radUltraGS1")->isChecked()); set_gs1_mode(m_optionWidget->findChild<QRadioButton*>("radUltraGS1")->isChecked());
break; break;
@ -1568,7 +1581,7 @@ void MainWindow::update_preview()
chkRInit->setEnabled(m_bc.bc.supportsReaderInit() && (m_bc.bc.inputMode() & 0x07) != GS1_MODE); chkRInit->setEnabled(m_bc.bc.supportsReaderInit() && (m_bc.bc.inputMode() & 0x07) != GS1_MODE);
if (!grpComposite->isHidden() && chkComposite->isChecked()) if (!grpComposite->isHidden() && chkComposite->isChecked())
m_bc.bc.setSecurityLevel(cmbCompType->currentIndex()); m_bc.bc.setOption1(cmbCompType->currentIndex());
if (!chkAutoHeight->isEnabled() || chkAutoHeight->isChecked()) { if (!chkAutoHeight->isEnabled() || chkAutoHeight->isChecked()) {
m_bc.bc.setHeight(0); m_bc.bc.setHeight(0);
@ -1832,6 +1845,20 @@ void MainWindow::set_lineedit_from_setting(QSettings &settings, const QString &s
} }
} }
/* Helper to return value of spin box, checking for NULL */
int MainWindow::get_spinbox_val(const QString &child) {
QSpinBox *spinBox = m_optionWidget->findChild<QSpinBox*>(child);
return spinBox ? spinBox->value() : 0;
}
/* Helper to set spin box from settings, checking for NULL */
void MainWindow::set_spinbox_from_setting(QSettings &settings, const QString &setting, const QString &child, int default_val) {
QSpinBox *spinBox = m_optionWidget->findChild<QSpinBox*>(child);
if (spinBox) {
spinBox->setValue(settings.value(setting, default_val).toInt());
}
}
/* Save settings for an individual symbol */ /* Save settings for an individual symbol */
void MainWindow::save_sub_settings(QSettings &settings, int symbology) { void MainWindow::save_sub_settings(QSettings &settings, int symbology) {
@ -2001,6 +2028,8 @@ void MainWindow::save_sub_settings(QSettings &settings, int symbology) {
case BARCODE_MAXICODE: case BARCODE_MAXICODE:
settings.setValue("studio/bc/maxicode/mode", get_combobox_index("cmbMaxiMode")); settings.setValue("studio/bc/maxicode/mode", get_combobox_index("cmbMaxiMode"));
settings.setValue("studio/bc/maxicode/primary_message", get_lineedit_val("txtMaxiPrimary")); settings.setValue("studio/bc/maxicode/primary_message", get_lineedit_val("txtMaxiPrimary"));
settings.setValue("studio/bc/maxicode/chk_scm_vv", get_checkbox_val("chkMaxiSCMVV"));
settings.setValue("studio/bc/maxicode/spn_scm_vv", get_spinbox_val("spnMaxiSCMVV"));
break; break;
case BARCODE_CODEONE: case BARCODE_CODEONE:
@ -2227,6 +2256,8 @@ void MainWindow::load_sub_settings(QSettings &settings, int symbology) {
case BARCODE_MAXICODE: case BARCODE_MAXICODE:
set_combobox_from_setting(settings, "studio/bc/maxicode/mode", "cmbMaxiMode", 1); set_combobox_from_setting(settings, "studio/bc/maxicode/mode", "cmbMaxiMode", 1);
set_lineedit_from_setting(settings, "studio/bc/maxicode/primary_message", "txtMaxiPrimary", "Primary Message Here!"); set_lineedit_from_setting(settings, "studio/bc/maxicode/primary_message", "txtMaxiPrimary", "Primary Message Here!");
set_checkbox_from_setting(settings, "studio/bc/maxicode/chk_scm_vv", "chkMaxiSCMVV");
set_spinbox_from_setting(settings, "studio/bc/maxicode/spn_scm_vv", "spnMaxiSCMVV", 96); /* 96 is ASC MH10/SC 8 */
break; break;
case BARCODE_CODEONE: case BARCODE_CODEONE:

View File

@ -146,6 +146,8 @@ protected:
void set_doublespinbox_from_setting(QSettings &settings, const QString &setting, const QString &child, float default_val = 0); void set_doublespinbox_from_setting(QSettings &settings, const QString &setting, const QString &child, float default_val = 0);
QString get_lineedit_val(const QString &child); QString get_lineedit_val(const QString &child);
void set_lineedit_from_setting(QSettings &settings, const QString &setting, const QString &child, const char *default_val = ""); void set_lineedit_from_setting(QSettings &settings, const QString &setting, const QString &child, const char *default_val = "");
int get_spinbox_val(const QString &child);
void set_spinbox_from_setting(QSettings &settings, const QString &setting, const QString &child, int default_val = 0);
void save_sub_settings(QSettings &settings, int symbology); void save_sub_settings(QSettings &settings, int symbology);
void load_sub_settings(QSettings &settings, int symbology); void load_sub_settings(QSettings &settings, int symbology);

View File

@ -36,7 +36,7 @@ namespace Zint {
m_borderType = 0; m_borderType = 0;
m_borderWidth = 0; m_borderWidth = 0;
m_fontSetting = 0; m_fontSetting = 0;
m_securityLevel = -1; m_option_1 = -1;
m_fgColor = Qt::black; m_fgColor = Qt::black;
m_bgColor = Qt::white; m_bgColor = Qt::white;
m_cmyk = false; m_cmyk = false;
@ -75,7 +75,7 @@ namespace Zint {
m_zintSymbol->height = m_height; m_zintSymbol->height = m_height;
m_zintSymbol->whitespace_width = m_whitespace; m_zintSymbol->whitespace_width = m_whitespace;
m_zintSymbol->border_width = m_borderWidth; m_zintSymbol->border_width = m_borderWidth;
m_zintSymbol->option_1 = m_securityLevel; m_zintSymbol->option_1 = m_option_1;
m_zintSymbol->input_mode = m_input_mode; m_zintSymbol->input_mode = m_input_mode;
m_zintSymbol->option_2 = m_option_2; m_zintSymbol->option_2 = m_option_2;
if (m_dotty) { if (m_dotty) {
@ -249,20 +249,12 @@ namespace Zint {
m_whitespace = whitespace; m_whitespace = whitespace;
} }
int QZint::securityLevel() const { int QZint::option1() const {
return m_securityLevel; return m_option_1;
} }
void QZint::setSecurityLevel(int securityLevel) { void QZint::setOption1(int option_1) {
m_securityLevel = securityLevel; m_option_1 = option_1;
}
int QZint::mode() const {
return m_securityLevel;
}
void QZint::setMode(int securityLevel) {
m_securityLevel = securityLevel;
} }
void QZint::setFontSetting(int fontSettingIndex) { void QZint::setFontSetting(int fontSettingIndex) {

View File

@ -78,11 +78,8 @@ public:
int borderWidth() const; int borderWidth() const;
void setBorderWidth(int boderWidth); void setBorderWidth(int boderWidth);
int securityLevel() const; int option1() const;
void setSecurityLevel(int securityLevel); void setOption1(int option_1);
int mode() const;
void setMode(int securityLevel);
void setWhitespace(int whitespace); void setWhitespace(int whitespace);
@ -140,7 +137,7 @@ private:
int m_borderWidth; int m_borderWidth;
int m_fontSetting; int m_fontSetting;
int m_option_2; int m_option_2;
int m_securityLevel; int m_option_1;
int m_input_mode; int m_input_mode;
QColor m_fgColor; QColor m_fgColor;
QColor m_bgColor; QColor m_bgColor;