UPC/EAN, ITF14: quiet zones, addongap; raster/vector: sync code, use double

This commit is contained in:
gitlost 2020-07-15 19:00:12 +01:00
parent e90c273165
commit 2a19b883a5
55 changed files with 2917 additions and 1351 deletions

View file

@ -30,14 +30,13 @@
*/
/* vim: set ts=4 sw=4 et : */
#include <string.h>
#include "common.h"
#include "output.h"
#define SSET "0123456789ABCDEF"
/* Check colour options are good. Note: using raster.c error nos 651-654 */
INTERNAL int check_colour_options(struct zint_symbol *symbol) {
INTERNAL int output_check_colour_options(struct zint_symbol *symbol) {
int error_number;
if (strlen(symbol->fgcolour) != 6) {
@ -68,32 +67,346 @@ INTERNAL int check_colour_options(struct zint_symbol *symbol) {
}
/* Return minimum quiet zones for each symbology */
static void quiet_zones(struct zint_symbol *symbol, int *left, int *right, int *top, int *bottom) {
static int quiet_zones(struct zint_symbol *symbol, int *left, int *right, int *top, int *bottom) {
int done = 0;
*left = *right = *top = *bottom = 0;
/* These always have quiet zones set (previously used whitespace_width) */
switch (symbol->symbology) {
case BARCODE_CODE16K:
/* BS EN 12323:2005 Section 4.5 c) */
/* BS EN 12323:2005 Section 4.5 (c) */
*left = 10;
*right = 1;
done = 1;
break;
case BARCODE_CODE49:
/* ANSI/AIM BC6-2000 Section 2.4 */
*left = 10;
*right = 1;
done = 1;
break;
case BARCODE_CODABLOCKF:
case BARCODE_HIBC_BLOCKF:
/* AIM ISS-X-24 Section 4.6.1 */
*left = 10;
*right = 10;
done = 1;
break;
case BARCODE_ITF14:
/* GS1 General Specifications 20.0 Section 5.3.2.2 */
*left = 10;
*right = 10;
done = 1;
break;
case BARCODE_EANX:
case BARCODE_EANX_CHK:
case BARCODE_EANX_CC:
case BARCODE_ISBNX:
/* GS1 General Specifications 20.0 Section 5.2.3.4 */
switch (ustrlen(symbol->text)) {
case 13: /* EAN-13 */
*left = 11;
*right = 7;
break;
case 16: /* EAN-13/ISBN + 2 digit addon */
case 19: /* EAN-13/ISBN + 5 digit addon */
*left = 11;
*right = 5;
break;
case 5: /* EAN-5 addon */
case 2: /* EAN-2 addon */
*left = 7;
*right = 5;
break;
default: /* EAN-8 (+/- 2/5 digit addon) */
*left = 7;
*right = 7;
break;
}
done = 1;
break;
case BARCODE_UPCA:
case BARCODE_UPCA_CHK:
case BARCODE_UPCA_CC:
/* GS1 General Specifications 20.0 Section 5.2.3.4 */
*left = 9;
if (ustrlen(symbol->text) > 12) { /* UPC-A + addon */
*right = 5;
} else {
*right = 9;
}
done = 1;
break;
case BARCODE_UPCE:
case BARCODE_UPCE_CHK:
case BARCODE_UPCE_CC:
/* GS1 General Specifications 20.0 Section 5.2.3.4 */
*left = 9;
if (ustrlen(symbol->text) > 8) { /* UPC-E + addon */
*right = 5;
} else {
*right = 7;
}
done = 1;
break;
/* TODO: others */
}
if (done) {
return done;
}
/* Only do others if flag set TODO: finish */
#if 0
if (!(symbol->output_options & BARCODE_QUIET_ZONES)) {
return done;
}
#else
return done;
#endif
switch (symbol->symbology) {
case BARCODE_CODE11:
/* TODO */
break;
case BARCODE_C25MATRIX:
case BARCODE_C25INTER:
case BARCODE_C25IATA:
case BARCODE_C25LOGIC:
case BARCODE_C25IND:
*left = *right = 10; // Probably this TODO: check
done = 1;
break;
case BARCODE_CODE39:
case BARCODE_EXCODE39:
case BARCODE_LOGMARS:
case BARCODE_PZN:
case BARCODE_VIN:
case BARCODE_HIBC_39:
case BARCODE_CODE32:
/* ISO/IEC 16388:2007 Section 4.4 (d) */
*left = *right = 10;
done = 1;
break;
case BARCODE_EAN128: /* GS1-128 */
case BARCODE_EAN128_CC:
case BARCODE_EAN14:
/* GS1 General Specifications 20.0 Section 5.4.4.2 */
*left = *right = 10;
done = 1;
break;
case BARCODE_CODABAR:
/* BS EN 798:1995 Section 4.4.1 (d) */
*left = *right = 10;
done = 1;
break;
case BARCODE_CODE128:
case BARCODE_CODE128B:
case BARCODE_HIBC_128:
case BARCODE_NVE18:
/* ISO/IEC 15417:2007 4.4.2 */
*left = *right = 10;
done = 1;
break;
case BARCODE_DPLEIT:
case BARCODE_DPIDENT:
/* TODO */
break;
case BARCODE_CODE93:
/* TODO */
break;
case BARCODE_FLAT:
/* TODO */
break;
case BARCODE_RSS14: /* GS1 Databar Omnidirectional */
case BARCODE_RSS_LTD: /* GS1 Databar Limited */
case BARCODE_RSS_EXP: /* GS1 Databar Expanded */
case BARCODE_RSS14STACK: /* GS1 DataBar Stacked */
case BARCODE_RSS14STACK_OMNI: /* GS1 DataBar Stacked Omnidirectional */
case BARCODE_RSS_EXPSTACK: /* GS1 Databar Expanded Stacked */
/* GS1 General Specifications 20.0 Section 5.5.1.1 - Quiet Zones: None required */
*left = *right = 0;
done = 1;
break;
case BARCODE_RSS14_CC:
case BARCODE_RSS_LTD_CC:
case BARCODE_RSS_EXP_CC:
case BARCODE_RSS14STACK_CC:
case BARCODE_RSS14_OMNI_CC:
case BARCODE_RSS_EXPSTACK_CC:
/* GS1 General Specifications 20.0 Sections 5.9.2.1 (CC-A) & 5.9.2.2 (CC-B) */
*left = *right = 1;
done = 1;
break;
case BARCODE_TELEPEN:
case BARCODE_TELEPEN_NUM:
/* TODO */
break;
case BARCODE_POSTNET:
case BARCODE_PLANET:
/* Archived DMM C840 (Dec 09, 2004) left/right 0.125" ~ 6X, top/bottom 0.04" ~ 2X */
*left = *right = 6; // TODO: Proper inch to X calc
*top = *bottom = 2; // TODO: Proper inch to X calc
done = 1;
break;
case BARCODE_MSI_PLESSEY:
/* TODO */
break;
case BARCODE_FIM:
/* TODO */
break;
case BARCODE_PHARMA:
case BARCODE_PHARMA_TWO:
/* TODO */
break;
case BARCODE_PDF417:
case BARCODE_PDF417TRUNC:
case BARCODE_HIBC_PDF:
/* ISO/IEC 15438:2015 Section 5.8.3 */
*left = *right = *top = *bottom = 2;
done = 1;
break;
case BARCODE_MICROPDF417:
case BARCODE_HIBC_MICPDF:
/* ISO/IEC 24728:2006 Section 5.8.3 */
*left = *right = *top = *bottom = 1;
done = 1;
break;
case BARCODE_MAXICODE:
/* ISO/IEC 16023:2000 Section 4.11.5 */
*left = *right = *top = *bottom = 1;
done = 1;
break;
case BARCODE_QRCODE:
case BARCODE_UPNQR:
case BARCODE_HIBC_QR:
/* ISO/IEC 18004:2015 Section 9.1 */
*left = *right = *top = *bottom = 4;
done = 1;
break;
case BARCODE_MICROQR:
/* ISO/IEC 18004:2015 Section 9.1 */
*left = *right = *top = *bottom = 2;
done = 1;
break;
case BARCODE_RMQR:
/* ISO/IEC JTC1/SC31N000 Section 6.3.10 */
*left = *right = *top = *bottom = 2;
done = 1;
break;
case BARCODE_AUSPOST:
case BARCODE_AUSREPLY:
case BARCODE_AUSROUTE:
case BARCODE_AUSREDIRECT:
/* Customer Barcode Technical Specifications (2012) left/right 6mm ~ 6X, top/bottom 2mm ~ 2X */
*left = *right = 6; // TODO: Proper mm to X calc
*top = *bottom = 2; // TODO: Proper mm to X calc
done = 1;
break;
case BARCODE_RM4SCC:
/* TODO */
break;
case BARCODE_DATAMATRIX:
case BARCODE_HIBC_DM:
/* ISO/IEC 16022:2006 Section 7.1 */
*left = *right = *top = *bottom = 1;
done = 1;
break;
case BARCODE_JAPANPOST:
/* TODO */
break;
case BARCODE_KOREAPOST:
/* TODO */
break;
case BARCODE_ONECODE:
/* USPS-B-3200 (2015) Section 2.3.2 left/right 0.125" ~ 6X, top/bottom 0.026" ~ 1X */
*left = *right = 6; // TODO: Proper inch to X calc
*top = *bottom = 1; // TODO: Proper inch to X calc
done = 1;
break;
case BARCODE_PLESSEY:
/* TODO */
break;
case BARCODE_KIX:
/* Handleiding KIX code brochure left/right/top/bottom 2mm ~ 2X */
*left = *right = *top = *bottom = 2; // TODO: Proper mm to X calc
done = 1;
break;
case BARCODE_AZTEC:
case BARCODE_HIBC_AZTEC:
case BARCODE_AZRUNE:
/* ISO/IEC 24778:2008 Section 4.1 (c) & Annex A.1 (Rune) - no quiet zone required */
done = 1;
break;
case BARCODE_DAFT:
/* TODO */
break;
case BARCODE_DOTCODE:
/* ISS DotCode Rev. 4.0 Section 4.1 (3) (c) */
*left = *right = *top = *bottom = 3;
done = 1;
break;
case BARCODE_HANXIN:
/* ISO/IEC DIS 20830:2019 Section 4.2.8 (also Section 6.2) */
*left = *right = *top = *bottom = 3;
done = 1;
break;
case BARCODE_MAILMARK:
/* User Guide left/right/top/bottom 2mm ~ 2X */
*left = *right = *top = *bottom = 2; // TODO: Proper mm to X calc
done = 1;
break;
case BARCODE_CHANNEL:
/* ANSI/AIM BC12-1998 Section 4.4 (c) */
*left = 1;
*right = 2;
done = 1;
break;
case BARCODE_CODEONE:
/* TODO */
break;
case BARCODE_GRIDMATRIX:
/* AIMD014 (v 1.63) Section 7.1 */
*left = *right = *top = *bottom = 6;
done = 1;
break;
case BARCODE_ULTRA:
/* AIMD/TSC15032-43 (v 0.99c) Section 9.2 */
*left = *right = *top = *bottom = 1;
done = 1;
break;
}
return done; /* For self-checking */
}
/* Set left (x), top (y), right and bottom offsets for whitespace */
INTERNAL void set_whitespace_offsets(struct zint_symbol *symbol, int *xoffset, int *yoffset, int *roffset, int *boffset) {
INTERNAL void output_set_whitespace_offsets(struct zint_symbol *symbol, int *xoffset, int *yoffset, int *roffset, int *boffset) {
int qz_left, qz_right, qz_top, qz_bottom;
quiet_zones(symbol, &qz_left, &qz_right, &qz_top, &qz_bottom);
@ -112,3 +425,163 @@ INTERNAL void set_whitespace_offsets(struct zint_symbol *symbol, int *xoffset, i
*boffset += symbol->border_width;
}
}
/* Set composite offset and main width excluding addon (for start of addon calc) and addon text, returning UPC/EAN type */
INTERNAL int output_process_upcean(struct zint_symbol *symbol, int *p_main_width, int *p_comp_offset, unsigned char addon[6], int *p_addon_gap) {
int main_width; /* Width of main linear symbol, excluding addon */
int comp_offset; /* Whitespace offset (if any) of main linear symbol due to having composite */
int upceanflag; /* UPC/EAN type flag */
int i, j, latch;
int text_length = ustrlen(symbol->text);
latch = 0;
j = 0;
/* Isolate add-on text */
for (i = 6; i < text_length && j < 5; i++) {
if (latch == 1) {
addon[j] = symbol->show_hrt ? symbol->text[i] : ' '; /* Use dummy space-filled addon if no hrt */
j++;
} else if (symbol->text[i] == '+') {
latch = 1;
}
}
addon[j] = '\0';
if (latch) {
if (symbol->symbology == BARCODE_UPCA || symbol->symbology == BARCODE_UPCA_CHK || symbol->symbology == BARCODE_UPCA_CC) {
*p_addon_gap = symbol->option_2 >= 9 && symbol->option_2 <= 12 ? symbol->option_2 : 9;
} else {
*p_addon_gap = symbol->option_2 >= 7 && symbol->option_2 <= 12 ? symbol->option_2 : 7;
}
}
/* Calculate composite offset */
comp_offset = 0;
if (is_composite(symbol->symbology)) {
while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
comp_offset++;
}
}
upceanflag = 0;
main_width = symbol->width;
if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CHK)
|| (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) {
switch (text_length) {
case 13: /* EAN-13 */
case 16: /* EAN-13 + EAN-2 */
case 19: /* EAN-13 + EAN-5 */
main_width = 95 + comp_offset; /* EAN-13 main symbol 95 modules wide */
upceanflag = 13;
break;
case 2:
/* EAN-2 can't have addon or be composite */
upceanflag = 2;
break;
case 5:
/* EAN-5 can't have addon or be composite */
upceanflag = 5;
break;
default:
main_width = 68 + comp_offset; /* EAN-8 main symbol 68 modules wide */
upceanflag = 8;
break;
}
} else if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CHK)
|| (symbol->symbology == BARCODE_UPCA_CC)) {
main_width = 95 + comp_offset; /* UPC-A main symbol 95 modules wide */
upceanflag = 12;
} else if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CHK)
|| (symbol->symbology == BARCODE_UPCE_CC)) {
main_width = 51 + comp_offset; /* UPC-E main symbol 51 modules wide */
upceanflag = 6;
}
*p_comp_offset = comp_offset;
*p_main_width = main_width;
return upceanflag;
}
/* Calculate large bar height i.e. linear bars */
INTERNAL double output_large_bar_height(struct zint_symbol *symbol) {
int i, large_bar_count, preset_height;
double large_bar_height;
large_bar_count = 0;
preset_height = 0;
for (i = 0; i < symbol->rows; i++) {
preset_height += symbol->row_height[i];
if (symbol->row_height[i] == 0) {
large_bar_count++;
}
}
if (large_bar_count) {
large_bar_height = (double) (symbol->height - preset_height) / large_bar_count;
} else {
large_bar_height = 0.0; /* Not used if large_bar_count zero */
}
return large_bar_height;
}
/* Split UPC/EAN add-on text into various constituents */
INTERNAL void output_upcean_split_text(int upceanflag, unsigned char text[],
unsigned char textpart1[5], unsigned char textpart2[7], unsigned char textpart3[7], unsigned char textpart4[2]) {
int i;
if (upceanflag == 6) { /* UPC-E */
textpart1[0] = text[0];
textpart1[1] = '\0';
for (i = 0; i < 6; i++) {
textpart2[i] = text[i + 1];
}
textpart2[6] = '\0';
textpart3[0] = text[7];
textpart3[1] = '\0';
} else if (upceanflag == 8) { /* EAN-8 */
for (i = 0; i < 4; i++) {
textpart1[i] = text[i];
}
textpart1[4] = '\0';
for (i = 0; i < 4; i++) {
textpart2[i] = text[i + 4];
}
textpart2[4] = '\0';
} else if (upceanflag == 12) { /* UPC-A */
textpart1[0] = text[0];
textpart1[1] = '\0';
for (i = 0; i < 5; i++) {
textpart2[i] = text[i + 1];
}
textpart2[5] = '\0';
for (i = 0; i < 5; i++) {
textpart3[i] = text[i + 6];
}
textpart3[5] = '\0';
textpart4[0] = text[11];
textpart4[1] = '\0';
} else if (upceanflag == 13) { /* EAN-13 */
textpart1[0] = text[0];
textpart1[1] = '\0';
for (i = 0; i < 6; i++) {
textpart2[i] = text[i + 1];
}
textpart2[6] = '\0';
for (i = 0; i < 6; i++) {
textpart3[i] = text[i + 7];
}
textpart3[6] = '\0';
}
}