From 9bae0b86f99a9b3afc1f8b9b9fa61d19dddd7394 Mon Sep 17 00:00:00 2001 From: gitlost Date: Mon, 20 Sep 2021 14:56:27 +0100 Subject: [PATCH] - raster.c: Need ceilf(symbol->height * si) to avoid heap-buffer-overflow; also avoid distributive multiplication with floats to lessen chances of platform variation (#204 ARM-Cortex crash) - raster.c: Don't allow for text if scale < 1.0 - raster.c: Cast some indexes to (size_t) to allow for large scale - vector.c: Check malloc()s and return ZINT_ERROR_MEMORY on fail - raster/vector.c: various var name changes & other code fiddling - library.c: Check that scale/height/whitespace/border are reasonable values: scale (0.01-100), height (0-500), whitespace_width/height (0-100), border_width (0-100) - CLI: allow both e.g. '-height' and '--height' (getopt_long_only()) - gif.c: fix GIF_ZLW_PAGE_SIZE -> GIF_LZW_PAGE_SIZE - GUI: allow whitespace/scale to 100 --- ChangeLog | 12 + backend/gif.c | 10 +- backend/library.c | 18 +- backend/output.c | 42 +- backend/output.h | 9 +- backend/raster.c | 800 ++++++++---------- .../data/gif/code16k_height0.5_wsp3_vwsp5.gif | Bin 0 -> 140 bytes .../data/gif/code16k_height1.5_wsp3_vwsp5.gif | Bin 0 -> 197 bytes .../tests/data/gif/itf14_height0.5_1.1.gif | Bin 0 -> 548 bytes .../data/gif/itf14_height0.5_box0_0.5.gif | Bin 0 -> 65 bytes .../gif/itf14_height61.8_bind4_wsp24_3.gif | Bin 17503 -> 17536 bytes backend/tests/test_gif.c | 4 + backend/tests/test_library.c | 311 ++++--- backend/tests/test_svg.c | 1 + backend/vector.c | 413 ++++----- docs/manual.txt | 2 + frontend/main.c | 13 +- frontend/tests/test_args.c | 41 +- frontend_qt/mainWindow.ui | 8 +- 19 files changed, 870 insertions(+), 814 deletions(-) create mode 100644 backend/tests/data/gif/code16k_height0.5_wsp3_vwsp5.gif create mode 100644 backend/tests/data/gif/code16k_height1.5_wsp3_vwsp5.gif create mode 100644 backend/tests/data/gif/itf14_height0.5_1.1.gif create mode 100644 backend/tests/data/gif/itf14_height0.5_box0_0.5.gif diff --git a/ChangeLog b/ChangeLog index 0334b33c..dbd2664c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ Version 2.10.0.9 (dev) not released yet ------------------------ - Add width to struct zint_vector_circle NOTE: backward incompatible drawing of MaxiCode finder (bullseye) +- Check that scale/height/whitespace/border are reasonable values + NOTE: will return error if values outside ranges +- raster.c: Bug fix for heap-buffer-overflow (#204 ARM-Cortex) + NOTE: may cause single-pixel changes to height depending on height/scale used Changes ------- @@ -12,6 +16,10 @@ Changes - CODE93: don't display check characters in HRT (as per standard Figure B1) unless option_2 = 1 or vers=1 - GUI: separate out MAXICODE Structured Carrier Message fields +- library.c: Check that scale/height/whitespace/border are reasonable values: + scale (0.01-100), height (0-500), whitespace_width/height (0-100), + border_width (0-100) +- CLI: allow both e.g. '-height' and '--height' (getopt_long_only()) Bugs ---- @@ -20,6 +28,10 @@ Bugs - vector.c: enforce minimum scale >= 0.1 and allow in GUI - Suppress some pedantic warnings, props codemonkey82 (#204) - gs1.c: Allow 0-length AI data if GS1NOCHECK_MODE, props codemonkey82 (#204) +- raster.c: Need ceilf(symbol->height * si) to avoid heap-buffer-overflow; + also avoid distributive multiplication with floats to lessen chances of + platform variation (#204 ARM-Cortex crash) +- raster.c: Don't allow for text if scale < 1.0 Version 2.10.0 2021-08-14 diff --git a/backend/gif.c b/backend/gif.c index 5cfbe891..d69b9437 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -41,8 +41,8 @@ #include #endif -/* Limit initial ZLW buffer size to this in expectation that compressed data will fit for typical scalings */ -#define GIF_ZLW_PAGE_SIZE 0x100000 /* Megabyte */ +/* Limit initial LZW buffer size to this in expectation that compressed data will fit for typical scalings */ +#define GIF_LZW_PAGE_SIZE 0x100000 /* Megabyte */ typedef struct s_statestruct { unsigned char *pOut; @@ -98,7 +98,7 @@ static int BufferNextByte(statestruct *pState) { } if (pState->OutPosCur >= pState->OutLength) { unsigned char *pOut; - pState->OutLength += GIF_ZLW_PAGE_SIZE; + pState->OutLength += GIF_LZW_PAGE_SIZE; /* Note pState->pOut not free()d by realloc() on failure */ if (!(pOut = (unsigned char *) realloc(pState->pOut, pState->OutLength))) { return 1; @@ -309,8 +309,8 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) /* Allow for overhead of 4 == code size + byte count + overflow byte + zero terminator */ unsigned int lzoutbufSize = bitmapSize + 4; - if (lzoutbufSize > GIF_ZLW_PAGE_SIZE) { - lzoutbufSize = GIF_ZLW_PAGE_SIZE; + if (lzoutbufSize > GIF_LZW_PAGE_SIZE) { + lzoutbufSize = GIF_LZW_PAGE_SIZE; } /* diff --git a/backend/library.c b/backend/library.c index e4389125..8c2d4464 100644 --- a/backend/library.c +++ b/backend/library.c @@ -1049,8 +1049,24 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int } } + if ((symbol->scale < 0.01f) || (symbol->scale > 100.0f)) { + return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "227: Scale out of range (0.01-100)"); + } if ((symbol->dot_size < 0.01f) || (symbol->dot_size > 20.0f)) { - return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "221: Invalid dot size"); + return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "221: Dot size out of range (0.01-20)"); + } + + if ((symbol->height < 0.0f) || (symbol->height > 500.0f)) { + return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "765: Height out of range (0-500)"); + } + if ((symbol->whitespace_width < 0) || (symbol->whitespace_width > 100)) { + return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "766: Whitespace width out of range (0-100)"); + } + if ((symbol->whitespace_height < 0) || (symbol->whitespace_height > 100)) { + return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "767: Whitespace height out of range (0-100)"); + } + if ((symbol->border_width < 0) || (symbol->border_width > 100)) { + return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "768: Border width out of range (0-100)"); } if ((symbol->input_mode & 0x07) > 2) { diff --git a/backend/output.c b/backend/output.c index 796d4781..80c44b09 100644 --- a/backend/output.c +++ b/backend/output.c @@ -69,7 +69,7 @@ INTERNAL int output_check_colour_options(struct zint_symbol *symbol) { } /* Return minimum quiet zones for each symbology */ -static int quiet_zones(struct zint_symbol *symbol, float *left, float *right, float *top, float *bottom) { +static int quiet_zones(const struct zint_symbol *symbol, float *left, float *right, float *top, float *bottom) { int done = 0; *left = *right = *top = *bottom = 0.0f; @@ -427,8 +427,9 @@ static int quiet_zones(struct zint_symbol *symbol, float *left, float *right, fl } /* Set left (x), top (y), right and bottom offsets for whitespace */ -INTERNAL void output_set_whitespace_offsets(struct zint_symbol *symbol, float *xoffset, float *yoffset, - float *roffset, float *boffset) { +INTERNAL void output_set_whitespace_offsets(const struct zint_symbol *symbol, + float *xoffset, float *yoffset, float *roffset, float *boffset, const float scaler, + int *xoffset_si, int *yoffset_si, int *roffset_si, int *boffset_si) { float qz_left, qz_right, qz_top, qz_bottom; quiet_zones(symbol, &qz_left, &qz_right, &qz_top, &qz_bottom); @@ -446,14 +447,29 @@ INTERNAL void output_set_whitespace_offsets(struct zint_symbol *symbol, float *x *yoffset += symbol->border_width; *boffset += symbol->border_width; } + + if (scaler) { + if (xoffset_si) { + *xoffset_si = (int) (*xoffset * scaler); + } + if (yoffset_si) { + *yoffset_si = (int) (*yoffset * scaler); + } + if (roffset_si) { + *roffset_si = (int) (*roffset * scaler); + } + if (boffset_si) { + *boffset_si = (int) (*boffset * scaler); + } + } } /* 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, +INTERNAL int output_process_upcean(const struct zint_symbol *symbol, int *p_main_width, int *p_comp_xoffset, 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 comp_xoffset; /* 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 = (int) ustrlen(symbol->text); @@ -480,10 +496,10 @@ INTERNAL int output_process_upcean(struct zint_symbol *symbol, int *p_main_width } /* Calculate composite offset */ - comp_offset = 0; + comp_xoffset = 0; if (is_composite(symbol->symbology)) { - while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { - comp_offset++; + while (!(module_is_set(symbol, symbol->rows - 1, comp_xoffset))) { + comp_xoffset++; } } @@ -495,7 +511,7 @@ INTERNAL int output_process_upcean(struct zint_symbol *symbol, int *p_main_width 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 */ + main_width = 95 + comp_xoffset; /* EAN-13 main symbol 95 modules wide */ upceanflag = 13; break; case 2: @@ -507,21 +523,21 @@ INTERNAL int output_process_upcean(struct zint_symbol *symbol, int *p_main_width upceanflag = 5; break; default: - main_width = 68 + comp_offset; /* EAN-8 main symbol 68 modules wide */ + main_width = 68 + comp_xoffset; /* 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 */ + main_width = 95 + comp_xoffset; /* 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 */ + main_width = 51 + comp_xoffset; /* UPC-E main symbol 51 modules wide */ upceanflag = 6; } - *p_comp_offset = comp_offset; + *p_comp_xoffset = comp_xoffset; *p_main_width = main_width; return upceanflag; diff --git a/backend/output.h b/backend/output.h index 8a626b13..fb76629e 100644 --- a/backend/output.h +++ b/backend/output.h @@ -1,7 +1,7 @@ /* output.h - Common routines for raster/vector libzint - the open source barcode library - Copyright (C) 2020 Robin Stuart + Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -38,9 +38,10 @@ extern "C" { #endif /* __cplusplus */ INTERNAL int output_check_colour_options(struct zint_symbol *symbol); -INTERNAL void output_set_whitespace_offsets(struct zint_symbol *symbol, float *xoffset, float *yoffset, - float *roffset, float *boffset); -INTERNAL int output_process_upcean(struct zint_symbol *symbol, int *p_main_width, int *p_comp_offset, +INTERNAL void output_set_whitespace_offsets(const struct zint_symbol *symbol, + float *xoffset, float *yoffset, float *roffset, float *boffset, const float scaler, + int *xoffset_si, int *yoffset_si, int *roffset_si, int *boffset_si); +INTERNAL int output_process_upcean(const struct zint_symbol *symbol, int *p_main_width, int *p_comp_xoffset, unsigned char addon[6], int *p_addon_gap); INTERNAL float output_large_bar_height(struct zint_symbol *symbol, int si); INTERNAL void output_upcean_split_text(int upceanflag, unsigned char text[], diff --git a/backend/raster.c b/backend/raster.c index 06a8fc0c..73dd415f 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -33,7 +33,6 @@ #include #include -#include #ifdef _MSC_VER #include @@ -62,37 +61,30 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) static const char ultra_colour[] = "0CBMRYGKW"; -static int buffer_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { +static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) { /* Place pixelbuffer into symbol */ int fgalpha, bgalpha; - unsigned char fg[3], bg[3]; - unsigned char white[3] = { 0xff, 0xff, 0xff }; - unsigned char cyan[3] = { 0, 0xff, 0xff }; - unsigned char blue[3] = { 0, 0, 0xff }; - unsigned char magenta[3] = { 0xff, 0, 0xff }; - unsigned char red[3] = { 0xff, 0, 0 }; - unsigned char yellow[3] = { 0xff, 0xff, 0 }; - unsigned char green[3] = { 0, 0xff, 0 }; - unsigned char black[3] = { 0, 0, 0 }; - unsigned char *map[91] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x00-0F */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10-1F */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x20-2F */ - bg, fg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0-9 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* :;<=>?@ */ - NULL, blue, cyan, NULL, NULL, NULL, green, NULL, NULL, NULL, black, NULL, magenta, /* A-M */ - NULL, NULL, NULL, NULL, red, NULL, NULL, NULL, NULL, white, NULL, yellow, NULL /* N-Z */ + unsigned char map[91][3] = { + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, /* 0x00-0F */ + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, /* 0x10-1F */ + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, /* 0x20-2F */ + {0} /*bg*/, {0} /*fg*/, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, /* 0-9 */ + {0}, {0}, {0}, {0}, {0}, {0}, {0}, /* :;<=>?@ */ + {0}, { 0, 0, 0xff } /*Blue*/, { 0, 0xff, 0xff } /*Cyan*/, {0}, {0}, {0}, { 0, 0xff, 0 } /*Green*/, /* A-G */ + {0}, {0}, {0}, { 0, 0, 0 } /*blacK*/, {0}, { 0xff, 0, 0xff } /*Magenta*/, {0}, /* H-N */ + {0}, {0}, {0}, { 0xff, 0, 0 } /*Red*/, {0}, {0}, {0}, {0}, /* O-V */ + { 0xff, 0xff, 0xff } /*White*/, {0}, { 0xff, 0xff, 0 } /*Yellow*/, {0} /* W-Z */ }; - int row, column; + int row; int plot_alpha = 0; unsigned char *bitmap; - fg[0] = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fg[1] = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fg[2] = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bg[0] = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bg[1] = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bg[2] = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + map[DEFAULT_INK][0] = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + map[DEFAULT_INK][1] = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + map[DEFAULT_INK][2] = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + map[DEFAULT_PAPER][0] = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + map[DEFAULT_PAPER][1] = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + map[DEFAULT_PAPER][2] = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); if (strlen(symbol->fgcolour) > 6) { fgalpha = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); @@ -132,8 +124,9 @@ static int buffer_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { } for (row = 0; row < symbol->bitmap_height; row++) { int p = row * symbol->bitmap_width; + int pe = p + symbol->bitmap_width; bitmap = symbol->bitmap + p * 3; - for (column = 0; column < symbol->bitmap_width; column++, p++, bitmap += 3) { + for (; p < pe; p++, bitmap += 3) { memcpy(bitmap, map[pixelbuf[p]], 3); symbol->alphamap[p] = pixelbuf[p] == DEFAULT_PAPER ? bgalpha : fgalpha; } @@ -141,9 +134,10 @@ static int buffer_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { } else { for (row = 0; row < symbol->bitmap_height; row++) { int r = row * symbol->bitmap_width; - unsigned char *pb = pixelbuf + r; + const unsigned char *pb = pixelbuf + r; + const unsigned char *pe = pb + symbol->bitmap_width; bitmap = symbol->bitmap + r * 3; - for (column = 0; column < symbol->bitmap_width; column++, pb++, bitmap += 3) { + for (; pb < pe; pb++, bitmap += 3) { memcpy(bitmap, map[*pb], 3); } } @@ -271,137 +265,129 @@ static void draw_pt(unsigned char *buf, const int buf_width, const int buf_heigh /* Draw a rectangle */ static void draw_bar(unsigned char *pixelbuf, const int xpos, const int xlen, const int ypos, const int ylen, const int image_width, const int image_height, const char fill) { - int i, j, png_ypos; + int y; + const int ye = ypos + ylen > image_height ? image_height : ypos + ylen; /* Defensive, should never happen */ - png_ypos = image_height - ypos - ylen; - /* This fudge is needed because EPS measures height from the bottom up but - PNG measures y position from the top down */ - - for (i = (xpos); i < (xpos + xlen); i++) { - for (j = (png_ypos); j < (png_ypos + ylen); j++) { - *(pixelbuf + (image_width * j) + i) = fill; - } + for (y = ypos; y < ye; y++) { + memset(pixelbuf + ((size_t) image_width * y) + xpos, fill, xlen); } } /* Put a letter into a position */ static void draw_letter(unsigned char *pixelbuf, const unsigned char letter, int xposn, const int yposn, const int textflags, const int image_width, const int image_height, const int si) { - int skip; - - skip = 0; + int glyph_no; + int x, y; + int max_x, max_y; + font_item *font_table; + int bold = 0; + unsigned glyph_mask; + int font_y; + int half_si; + int odd_si; + unsigned char *linePtr, *maxPtr; + int x_start = 0; if (letter < 33) { - skip = 1; + return; } if ((letter >= 127) && (letter < 161)) { - skip = 1; + return; } /* Following should never happen (ISBN check digit "X" not printed) */ if ((textflags & UPCEAN_TEXT) && (letter < '0' || letter > '9')) { - skip = 1; /* Not reached */ + return; /* Not reached */ } if (yposn < 0) { /* Allow xposn < 0, dealt with below */ - skip = 1; + return; } - if (skip == 0) { - int glyph_no; - int x, y; - int max_x, max_y; - font_item *font_table; - int bold = 0; - unsigned glyph_mask; - int font_y; - int half_si = si / 2; - int odd_si = si & 1; - unsigned char *linePtr, *maxPtr; - int x_start = 0; + half_si = si / 2; + odd_si = si & 1; - if (letter > 127) { - glyph_no = letter - 67; /* 161 - (127 - 33) */ + if (letter > 127) { + glyph_no = letter - 67; /* 161 - (127 - 33) */ + } else { + glyph_no = letter - 33; + } + + if (textflags & UPCEAN_TEXT) { /* Needs to be before SMALL_TEXT check */ + /* No bold for UPCEAN */ + if (textflags & SMALL_TEXT) { + font_table = upcean_small_font; + max_x = UPCEAN_SMALL_FONT_WIDTH; + max_y = UPCEAN_SMALL_FONT_HEIGHT; } else { - glyph_no = letter - 33; + font_table = upcean_font; + max_x = UPCEAN_FONT_WIDTH; + max_y = UPCEAN_FONT_HEIGHT; } + glyph_no = letter - '0'; + } else if (textflags & SMALL_TEXT) { // small font 5x9 + /* No bold for small */ + max_x = SMALL_FONT_WIDTH; + max_y = SMALL_FONT_HEIGHT; + font_table = small_font; + } else if (textflags & BOLD_TEXT) { // bold font -> regular font + 1 + max_x = NORMAL_FONT_WIDTH + 1; + max_y = NORMAL_FONT_HEIGHT; + font_table = ascii_font; + bold = 1; + } else { // regular font 7x14 + max_x = NORMAL_FONT_WIDTH; + max_y = NORMAL_FONT_HEIGHT; + font_table = ascii_font; + } + glyph_mask = ((unsigned) 1) << (max_x - 1); + font_y = glyph_no * max_y; - if (textflags & UPCEAN_TEXT) { /* Needs to be before SMALL_TEXT check */ - /* No bold for UPCEAN */ - if (textflags & SMALL_TEXT) { - font_table = upcean_small_font; - max_x = UPCEAN_SMALL_FONT_WIDTH; - max_y = UPCEAN_SMALL_FONT_HEIGHT; - } else { - font_table = upcean_font; - max_x = UPCEAN_FONT_WIDTH; - max_y = UPCEAN_FONT_HEIGHT; - } - glyph_no = letter - '0'; - } else if (textflags & SMALL_TEXT) { // small font 5x9 - /* No bold for small */ - max_x = SMALL_FONT_WIDTH; - max_y = SMALL_FONT_HEIGHT; - font_table = small_font; - } else if (textflags & BOLD_TEXT) { // bold font -> regular font + 1 - max_x = NORMAL_FONT_WIDTH + 1; - max_y = NORMAL_FONT_HEIGHT; - font_table = ascii_font; - bold = 1; - } else { // regular font 7x14 - max_x = NORMAL_FONT_WIDTH; - max_y = NORMAL_FONT_HEIGHT; - font_table = ascii_font; - } - glyph_mask = ((unsigned) 1) << (max_x - 1); - font_y = glyph_no * max_y; + if (xposn < 0) { + x_start = -xposn; + xposn = 0; + } - if (xposn < 0) { - x_start = -xposn; - xposn = 0; - } + if (yposn + max_y > image_height) { + max_y = image_height - yposn; + } - if (yposn + max_y > image_height) { - max_y = image_height - yposn; - } - - linePtr = pixelbuf + (yposn * image_width) + xposn; - for (y = 0; y < max_y; y++) { - int x_si, y_si; - unsigned char *pixelPtr = linePtr; /* Avoid warning */ - for (y_si = 0; y_si < half_si; y_si++) { - int extra_dot = 0; - pixelPtr = linePtr; - maxPtr = linePtr + image_width - xposn; - for (x = x_start; x < max_x && pixelPtr < maxPtr; x++) { - unsigned set = font_table[font_y + y] & (glyph_mask >> x); - for (x_si = 0; x_si < half_si && pixelPtr < maxPtr; x_si++) { - if (set) { - *pixelPtr = DEFAULT_INK; - extra_dot = bold; - } else if (extra_dot) { - *pixelPtr = DEFAULT_INK; - extra_dot = 0; - } - pixelPtr++; + linePtr = pixelbuf + ((size_t) yposn * image_width) + xposn; + for (y = 0; y < max_y; y++) { + int x_si, y_si; + unsigned char *pixelPtr = linePtr; /* Avoid warning */ + for (y_si = 0; y_si < half_si; y_si++) { + int extra_dot = 0; + pixelPtr = linePtr; + maxPtr = linePtr + image_width - xposn; + for (x = x_start; x < max_x && pixelPtr < maxPtr; x++) { + unsigned set = font_table[font_y + y] & (glyph_mask >> x); + for (x_si = 0; x_si < half_si && pixelPtr < maxPtr; x_si++) { + if (set) { + *pixelPtr = DEFAULT_INK; + extra_dot = bold; + } else if (extra_dot) { + *pixelPtr = DEFAULT_INK; + extra_dot = 0; } - if (pixelPtr < maxPtr && odd_si && (x & 1)) { - if (set) { - *pixelPtr = DEFAULT_INK; - } - pixelPtr++; + pixelPtr++; + } + if (pixelPtr < maxPtr && odd_si && (x & 1)) { + if (set) { + *pixelPtr = DEFAULT_INK; } + pixelPtr++; } - if (pixelPtr < maxPtr && extra_dot) { - *pixelPtr++ = DEFAULT_INK; - } - linePtr += image_width; } - if (odd_si && (y & 1)) { - memcpy(linePtr, linePtr - image_width, pixelPtr - (linePtr - image_width)); - linePtr += image_width; + if (pixelPtr < maxPtr && extra_dot) { + *pixelPtr++ = DEFAULT_INK; } + linePtr += image_width; + } + if (odd_si && (y & 1)) { + memcpy(linePtr, linePtr - image_width, pixelPtr - (linePtr - image_width)); + linePtr += image_width; } } } @@ -449,7 +435,7 @@ static void draw_string(unsigned char *pixbuf, const unsigned char input_string[ static void draw_circle(unsigned char *pixelbuf, const int image_width, const int image_height, const int x0, const int y0, const float radius, const char fill) { int x, y; - const int radius_i = (int) floorf(radius); + const int radius_i = (int) radius; const int radius_squared = radius_i * radius_i; for (y = -radius_i; y <= radius_i; y++) { @@ -508,14 +494,14 @@ static void draw_mp_circle(unsigned char *pixelbuf, const int image_width, const /* Draw central bullseye finder in Maxicode symbols */ static void draw_bullseye(unsigned char *pixelbuf, const int image_width, const int image_height, const int hex_width, const int hex_height, const int hx_start, const int hx_end, - const int hex_image_height, const int xoffset, const int yoffset, const float scaler) { + const int hex_image_height, const int xoffset_si, const int yoffset_si) { /* ISO/IEC 16023:2000 4.11.4 and 4.2.1.1 */ /* 14W right from leftmost centre = 14.5X */ - const int x = (int) floorf(14.5f * hex_width - hx_start + xoffset * scaler); + const int x = (int) (14.5f * hex_width - hx_start + xoffset_si); /* 16Y above bottom-most centre = halfway */ - const int y = (int) ceilf(hex_image_height / 2 + yoffset * scaler); + const int y = (int) ceilf(hex_image_height / 2 + yoffset_si); const int r1 = (int) ceilf(hex_height / 2.0f); /* Inner diameter is hex_height (V) */ /* Total finder diameter is 9X, so radial increment for 5 radii r2 to r6 is ((9X - r1) / 5) / 2 */ @@ -535,8 +521,8 @@ static void draw_bullseye(unsigned char *pixelbuf, const int image_width, const /* Put a hexagon into the pixel buffer */ static void draw_hexagon(unsigned char *pixelbuf, const int image_width, const int image_height, - unsigned char *scaled_hexagon, const int hex_width, const int hex_height, const int xposn, - const int yposn) { + const unsigned char *scaled_hexagon, const int hex_width, const int hex_height, + const int xposn, const int yposn) { int i, j; for (i = 0; i < hex_height; i++) { @@ -641,6 +627,35 @@ static void plot_hexagon(unsigned char *scaled_hexagon, const int hex_width, con } } } +/* Draw binding or box */ +static void draw_bind_box(const struct zint_symbol *symbol, unsigned char *pixelbuf, + const int xoffset_si, const int yoffset_si, const int symbol_height_si, const int dot_overspill_si, + const int image_width, const int image_height, const int si) { + if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) { + const int bwidth_si = symbol->border_width * si; + const int ybind_top = yoffset_si - bwidth_si; + const int ybind_bot = yoffset_si + symbol_height_si + dot_overspill_si; + /* Horizontal boundary bars */ + if ((symbol->output_options & BARCODE_BOX) + || (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF)) { + /* Box or not CodaBlockF */ + draw_bar(pixelbuf, 0, image_width, ybind_top, bwidth_si, image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 0, image_width, ybind_bot, bwidth_si, image_width, image_height, DEFAULT_INK); + } else { + /* CodaBlockF bind - does not extend over horizontal whitespace */ + const int width_si = symbol->width * si; + draw_bar(pixelbuf, xoffset_si, width_si, ybind_top, bwidth_si, image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, xoffset_si, width_si, ybind_bot, bwidth_si, image_width, image_height, DEFAULT_INK); + } + if (symbol->output_options & BARCODE_BOX) { + /* Vertical side bars */ + const int xbox_right = image_width - bwidth_si; + draw_bar(pixelbuf, 0, bwidth_si, yoffset_si, symbol_height_si, image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, xbox_right, bwidth_si, yoffset_si, symbol_height_si, image_width, image_height, + DEFAULT_INK); + } + } +} /* Plot a MaxiCode symbol with hexagons and bullseye */ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_angle, const int file_type) { @@ -650,12 +665,12 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang int error_number; float xoffset, yoffset, roffset, boffset; float scaler = symbol->scale; - int xoffset_scaled, yoffset_scaled; unsigned char *scaled_hexagon; int hex_width, hex_height; int hx_start, hy_start, hx_end, hy_end; int hex_image_width, hex_image_height; int yposn_offset; + int xoffset_si, yoffset_si, roffset_si, boffset_si; const float two_div_sqrt3 = 1.1547f; /* 2 / √3 */ const float sqrt3_div_two = 0.866f; /* √3 / 2 == 1.5 / √3 */ @@ -665,9 +680,8 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang } scaler *= 10.0f; - output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset); - xoffset_scaled = (int) floorf(xoffset * scaler); - yoffset_scaled = (int) floorf(yoffset * scaler); + output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset, scaler, + &xoffset_si, &yoffset_si, &roffset_si, &boffset_si); hex_width = (int) roundf(scaler); /* Short diameter, X in ISO/IEC 16023:2000 Figure 8 (same as W) */ hex_height = (int) roundf(scaler * two_div_sqrt3); /* Long diameter, V in Figure 8 */ @@ -685,12 +699,12 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang hex_image_width = 30 * hex_width - hx_start - hx_end; /* `yposn_offset` is vertical distance between rows, Y in Figure 8 */ /* TODO: replace following kludge with proper calc of hex_width/hex_height/yposn_offset as per J.4 Steps 1 to 7 */ - yposn_offset = (int) (scaler > 10.0f ? floorf(sqrt3_div_two * hex_width) : roundf(sqrt3_div_two * hex_width)); + yposn_offset = (int) (scaler > 10.0f ? (sqrt3_div_two * hex_width) : roundf(sqrt3_div_two * hex_width)); /* 32 rows drawn yposn_offset apart + final hexagon */ hex_image_height = 32 * yposn_offset + hex_height - hy_start - hy_end; - image_width = (int) ceilf(hex_image_width + (xoffset + roffset) * scaler); - image_height = (int) ceilf(hex_image_height + (yoffset + boffset) * scaler); + image_width = (int) ceilf(hex_image_width + xoffset_si + roffset_si); + image_height = (int) ceilf(hex_image_height + yoffset_si + boffset_si); if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) { strcpy(symbol->errtxt, "655: Insufficient memory for pixel buffer"); @@ -709,8 +723,8 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang for (row = 0; row < symbol->rows; row++) { const int odd_row = row & 1; /* Odd (reduced) row, even (full) row */ - const int yposn = row * yposn_offset + yoffset_scaled - hy_start; - const int xposn_offset = (odd_row ? hex_width / 2 : 0) + xoffset_scaled - hx_start; + const int yposn = row * yposn_offset + yoffset_si - hy_start; + const int xposn_offset = (odd_row ? hex_width / 2 : 0) + xoffset_si - hx_start; for (column = 0; column < symbol->width - odd_row; column++) { const int xposn = column * hex_width + xposn_offset; if (module_is_set(symbol, row, column)) { @@ -721,26 +735,10 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang } draw_bullseye(pixelbuf, image_width, image_height, hex_width, hex_height, hx_start, hx_end, hex_image_height, - xoffset, yoffset, scaler); + xoffset_si, yoffset_si); - if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) { - /* boundary bars */ - const int border_scaled = (int) floorf(symbol->border_width * scaler); - const int vwhitesp_scaled = (int) floorf(symbol->whitespace_height * scaler); - const int ybind_top = hex_image_height + border_scaled + vwhitesp_scaled; - draw_bar(pixelbuf, 0, image_width, vwhitesp_scaled, border_scaled, image_width, image_height, DEFAULT_INK); - draw_bar(pixelbuf, 0, image_width, ybind_top, border_scaled, image_width, image_height, DEFAULT_INK); - - if (symbol->output_options & BARCODE_BOX) { - /* side bars */ - const int whitesp_scaled = (int) floorf(symbol->whitespace_width * scaler); - const int xbox_right = hex_image_width + border_scaled + whitesp_scaled * 2; - const int ybox_top = border_scaled + vwhitesp_scaled; - const int ylen = image_height - (border_scaled + vwhitesp_scaled) * 2; - draw_bar(pixelbuf, 0, border_scaled, ybox_top, ylen, image_width, image_height, DEFAULT_INK); - draw_bar(pixelbuf, xbox_right, border_scaled, ybox_top, ylen, image_width, image_height, DEFAULT_INK); - } - } + draw_bind_box(symbol, pixelbuf, xoffset_si, yoffset_si, hex_image_height, 0 /*dot_overspill_si*/, + image_width, image_height, (int) scaler); error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, file_type); free(scaled_hexagon); @@ -758,39 +756,6 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang return error_number; } -/* Draw binding or box */ -static void draw_bind_box(struct zint_symbol *symbol, unsigned char *pixelbuf, const int xoffset, const int roffset, - const int textoffset, const int overspill_scaled, const int image_width, const int image_height, - const int si) { - if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) { - const int bwidth = symbol->border_width * si; - const int ybind_bottom = (textoffset + symbol->whitespace_height) * si; - const int ybind_top = (textoffset + symbol->whitespace_height + symbol->height) * si + overspill_scaled - + bwidth; - /* Horizontal boundary bars */ - if ((symbol->output_options & BARCODE_BOX) - || (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF)) { - /* Box or not CodaBlockF */ - const int xlen = (symbol->width + xoffset + roffset) * si + overspill_scaled; - draw_bar(pixelbuf, 0, xlen, ybind_bottom, bwidth, image_width, image_height, DEFAULT_INK); - draw_bar(pixelbuf, 0, xlen, ybind_top, bwidth, image_width, image_height, DEFAULT_INK); - } else { - /* CodaBlockF bind - does not extend over horizontal whitespace */ - const int xlen = symbol->width * si; - draw_bar(pixelbuf, xoffset * si, xlen, ybind_bottom, bwidth, image_width, image_height, DEFAULT_INK); - draw_bar(pixelbuf, xoffset * si, xlen, ybind_top, bwidth, image_width, image_height, DEFAULT_INK); - } - if (symbol->output_options & BARCODE_BOX) { - /* Vertical side bars */ - const int ylen = (symbol->height + symbol->border_width * 2) * si; - const int ybox = (textoffset + symbol->whitespace_height) * si; - const int xbox_right = (symbol->width + xoffset + roffset - symbol->border_width) * si + overspill_scaled; - draw_bar(pixelbuf, 0, bwidth, ybox, ylen, image_width, image_height, DEFAULT_INK); - draw_bar(pixelbuf, xbox_right, bwidth, ybox, ylen, image_width, image_height, DEFAULT_INK); - } - } -} - static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle, const int file_type) { float scaler = 2 * symbol->scale; unsigned char *scaled_pixelbuf; @@ -798,34 +763,38 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle, int scale_width, scale_height; int error_number = 0; float xoffset, yoffset, roffset, boffset; - float dot_offset_scaled; - float dot_radius_scaled; - int dot_radius_scaled_i; - int dot_overspill_scaled_i; + float dot_offset_s; + float dot_radius_s; + int dot_radius_si; + int dot_overspill_si; + int xoffset_si, yoffset_si, roffset_si, boffset_si; + int symbol_height_si; if (scaler < 2.0f) { scaler = 2.0f; } - dot_radius_scaled = (symbol->dot_size * scaler) / 2.0f; - dot_radius_scaled_i = (int) floorf(dot_radius_scaled); + symbol_height_si = (int) ceilf(symbol->height * scaler); + dot_radius_s = (symbol->dot_size * scaler) / 2.0f; + dot_radius_si = (int) dot_radius_s; - output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset); + output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset, scaler, + &xoffset_si, &yoffset_si, &roffset_si, &boffset_si); /* TODO: Revisit this overspill stuff, it's hacky */ if (symbol->dot_size < 1.0f) { - dot_overspill_scaled_i = 0; + dot_overspill_si = 0; /* Offset (1 - dot_size) / 2 + dot_radius == (1 - dot_size + dot_size) / 2 == 1 / 2 */ - dot_offset_scaled = scaler / 2.0f; + dot_offset_s = scaler / 2.0f; } else { /* Allow for exceeding 1X */ - dot_overspill_scaled_i = (int) ceilf((symbol->dot_size - 1.0f) * scaler); - dot_offset_scaled = dot_radius_scaled; + dot_overspill_si = (int) ceilf((symbol->dot_size - 1.0f) * scaler); + dot_offset_s = dot_radius_s; } - if (dot_overspill_scaled_i == 0) { - dot_overspill_scaled_i = 1; + if (dot_overspill_si == 0) { + dot_overspill_si = 1; } - scale_width = (int) floorf((symbol->width + xoffset + roffset) * scaler + dot_overspill_scaled_i); - scale_height = (int) floorf((symbol->height + yoffset + boffset) * scaler + dot_overspill_scaled_i); + scale_width = (int) (symbol->width * scaler + xoffset_si + roffset_si + dot_overspill_si); + scale_height = (int) (symbol_height_si + yoffset_si + boffset_si + dot_overspill_si); /* Apply scale options by creating another pixel buffer */ if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) { @@ -836,18 +805,18 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle, /* Plot the body of the symbol to the pixel buffer */ for (r = 0; r < symbol->rows; r++) { - int row_scaled = (int) floorf((r + yoffset) * scaler + dot_offset_scaled); + int row_si = (int) (r * scaler + yoffset_si + dot_offset_s); for (i = 0; i < symbol->width; i++) { if (module_is_set(symbol, r, i)) { draw_circle(scaled_pixelbuf, scale_width, scale_height, - (int) floorf((i + xoffset) * scaler + dot_offset_scaled), - row_scaled, dot_radius_scaled_i, DEFAULT_INK); + (int) (i * scaler + xoffset_si + dot_offset_s), + row_si, dot_radius_si, DEFAULT_INK); } } } - draw_bind_box(symbol, scaled_pixelbuf, xoffset, roffset, 0 /*textoffset*/, dot_overspill_scaled_i, - scale_width, scale_height, (int) floorf(scaler)); + draw_bind_box(symbol, scaled_pixelbuf, xoffset_si, yoffset_si, symbol_height_si, dot_overspill_si, + scale_width, scale_height, (int) scaler); error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, file_type); @@ -895,44 +864,37 @@ static void to_iso8859_1(const unsigned char source[], unsigned char preprocesse i++; } preprocessed[j] = '\0'; - - return; } static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angle, const int file_type) { int error_number; float large_bar_height; - int textdone = 0; int main_width; - int comp_offset = 0; + int comp_xoffset = 0; unsigned char addon[6]; int addon_gap = 0; - float addon_text_posn = 0.0f; + float addon_text_yposn = 0.0f; float xoffset, yoffset, roffset, boffset; float textoffset; - int default_text_posn; - float row_height, row_posn; + float yposn; int upceanflag = 0; int addon_latch = 0; unsigned char textpart1[5], textpart2[7], textpart3[7], textpart4[2]; - int textpos; int hide_text; int i, r; int text_height; /* Font pixel size (so whole integers) */ float text_gap; /* Gap between barcode and text */ + float guard_height; int textflags = 0; - int guardoffset = 0; + int xoffset_si, yoffset_si, roffset_si, boffset_si; + int comp_xoffset_si; + int symbol_height_si; int image_width, image_height; unsigned char *pixelbuf; - float next_yposn; - int latch; float scaler = symbol->scale; int si; int half_int_scaling; - int scale_width, scale_height; - unsigned char *scaled_pixelbuf; - int horiz, vert; /* Ignore scaling < 0.5 for raster as would drop modules */ if (scaler < 0.5f) { @@ -947,44 +909,41 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl } large_bar_height = output_large_bar_height(symbol, si /*Round to scale*/); + symbol_height_si = (int) ceilf(symbol->height * si); main_width = symbol->width; if (is_extendable(symbol->symbology)) { - upceanflag = output_process_upcean(symbol, &main_width, &comp_offset, addon, &addon_gap); + upceanflag = output_process_upcean(symbol, &main_width, &comp_xoffset, addon, &addon_gap); } - output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset); + output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset, si, + &xoffset_si, &yoffset_si, &roffset_si, &boffset_si); /* Note font sizes halved as in pixels */ if (upceanflag) { textflags = UPCEAN_TEXT | (symbol->output_options & SMALL_TEXT); /* Bold not available for UPC/EAN */ text_height = (UPCEAN_FONT_HEIGHT + 1) / 2; text_gap = 1.0f; + /* Guard bar height (none for EAN-2 and EAN-5) */ + guard_height = upceanflag != 2 && upceanflag != 5 ? 5.0f : 0.0f; /* TODO: use zint_symbol field */ } else { textflags = symbol->output_options & (SMALL_TEXT | BOLD_TEXT); text_height = textflags & SMALL_TEXT ? (SMALL_FONT_HEIGHT + 1) / 2 : (NORMAL_FONT_HEIGHT + 1) / 2; text_gap = 1.0f; + guard_height = 0.0f; } - hide_text = ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)); + hide_text = ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0) || scaler < 1.0f); if (hide_text) { - /* Need 5X from bottom for guard bars */ - textoffset = upceanflag && upceanflag != 2 && upceanflag != 5 ? 5 : 0; + textoffset = guard_height; } else { - if (upceanflag) { - textoffset = (text_height > 5 ? text_height : 5) + text_gap; /* Need at least 5X for guard bars */ - } else { - textoffset = text_height + text_gap; - } - } - if (upceanflag) { - guardoffset = textoffset - 5 + boffset; + textoffset = (text_height > guard_height ? text_height : guard_height) + text_gap; } - image_width = (symbol->width + xoffset + roffset) * si; - image_height = (symbol->height + textoffset + yoffset + boffset) * si; + image_width = symbol->width * si + xoffset_si + roffset_si; + image_height = symbol_height_si + textoffset * si + yoffset_si + boffset_si; if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) { strcpy(symbol->errtxt, "658: Insufficient memory for pixel buffer"); @@ -992,121 +951,104 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl } memset(pixelbuf, DEFAULT_PAPER, (size_t) image_width * image_height); - default_text_posn = image_height - (textoffset - text_gap + symbol->whitespace_height) * si; - - row_height = 0.0f; - row_posn = textoffset + boffset; /* Bottom up */ - next_yposn = textoffset + boffset; + yposn = yoffset; /* Plot the body of the symbol to the pixel buffer */ for (r = 0; r < symbol->rows; r++) { - float plot_yposn; - float plot_height; - int this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ - row_posn += row_height; - plot_yposn = next_yposn; - row_height = symbol->row_height[this_row] ? symbol->row_height[this_row] : large_bar_height; - next_yposn = row_posn + row_height; - plot_height = next_yposn - plot_yposn; - - plot_yposn *= si; - plot_height *= si; + int yposn_si = yposn * si; + float row_height = symbol->row_height[r] ? symbol->row_height[r] : large_bar_height; + int row_height_si = row_height * si; i = 0; if (symbol->symbology == BARCODE_ULTRA) { do { - int module_fill = module_colour_is_set(symbol, this_row, i); + int module_fill = module_colour_is_set(symbol, r, i); int block_width = 0; do { block_width++; } while ((i + block_width < symbol->width) - && module_colour_is_set(symbol, this_row, i + block_width) == module_fill); - + && module_colour_is_set(symbol, r, i + block_width) == module_fill); if (module_fill) { /* a colour block */ - draw_bar(pixelbuf, (i + xoffset) * si, block_width * si, plot_yposn, plot_height, image_width, - image_height, ultra_colour[module_fill]); + draw_bar(pixelbuf, i * si + xoffset_si, block_width * si, yposn_si, row_height_si, + image_width, image_height, ultra_colour[module_fill]); } i += block_width; } while (i < symbol->width); } else { do { - int module_fill = module_is_set(symbol, this_row, i); + float addon_row_height; + int module_fill = module_is_set(symbol, r, i); int block_width = 0; do { block_width++; } while ((i + block_width < symbol->width) - && module_is_set(symbol, this_row, i + block_width) == module_fill); + && module_is_set(symbol, r, i + block_width) == module_fill); - if (upceanflag && (addon_latch == 0) && (r == 0) && (i > main_width)) { - plot_height = row_height - (text_height + text_gap) + 5.0f; - plot_yposn = row_posn - 5.0f; - if (plot_yposn < 0.0f) { - plot_yposn = 0.0f; + if (upceanflag && (addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { + yposn_si += (text_height + text_gap) * si; + addon_text_yposn = yposn * si; + addon_row_height = row_height - (text_height + text_gap); + if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E add-ons don't descend */ + addon_row_height += guard_height; } - if (upceanflag == 12 || upceanflag == 6) { /* UPC-A/E add-ons don't descend */ - plot_height -= 5.0f; - plot_yposn += 5.0f; + if (addon_row_height < 0.5f) { + addon_row_height = 0.5f; } - if (plot_height < 0.5f) { - plot_height = 0.5f; - } - /* Need to invert composite position */ - addon_text_posn = is_composite(symbol->symbology) - ? image_height - (plot_yposn + plot_height + text_height + text_gap) * si - : yoffset * si; - plot_yposn *= si; - plot_height *= si; + row_height_si = addon_row_height * si; addon_latch = 1; } if (module_fill) { /* a bar */ - draw_bar(pixelbuf, (i + xoffset) * si, block_width * si, plot_yposn, plot_height, image_width, + draw_bar(pixelbuf, i * si + xoffset_si, block_width * si, yposn_si, row_height_si, image_width, image_height, DEFAULT_INK); } i += block_width; } while (i < symbol->width); } + yposn += row_height; } - xoffset += comp_offset; + comp_xoffset_si = xoffset_si + comp_xoffset * si; if (upceanflag) { /* Guard bar extension */ + int guard_yoffset_si = yoffset_si + symbol_height_si; + int guard_height_si = guard_height * si; if (upceanflag == 6) { /* UPC-E */ - draw_bar(pixelbuf, (0 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (2 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (46 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (48 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (50 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); + draw_bar(pixelbuf, 0 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 2 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 46 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 48 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 50 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); } else if (upceanflag == 8) { /* EAN-8 */ - draw_bar(pixelbuf, (0 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (2 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (32 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (34 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (64 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (66 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); + draw_bar(pixelbuf, 0 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 2 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 32 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 34 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 64 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 66 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); } else if (upceanflag == 12) { /* UPC-A */ - latch = 1; + int latch = 1; - i = 0 + comp_offset; + i = 0 + comp_xoffset; do { int module_fill = module_is_set(symbol, symbol->rows - 1, i); int block_width = 0; @@ -1116,21 +1058,21 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_fill); if (latch == 1) { /* a bar */ - draw_bar(pixelbuf, (i + xoffset - comp_offset) * si, block_width * si, guardoffset * si, 5 * si, - image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, i * si + xoffset_si, block_width * si, + guard_yoffset_si, guard_height_si, image_width, image_height, DEFAULT_INK); latch = 0; } else { /* a space */ latch = 1; } i += block_width; - } while (i < 11 + comp_offset); - draw_bar(pixelbuf, (46 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (48 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); + } while (i < 11 + comp_xoffset); + draw_bar(pixelbuf, 46 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 48 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); latch = 1; - i = 85 + comp_offset; + i = 85 + comp_xoffset; do { int module_fill = module_is_set(symbol, symbol->rows - 1, i); int block_width = 0; @@ -1140,35 +1082,46 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_fill); if (latch == 1) { /* a bar */ - draw_bar(pixelbuf, (i + xoffset - comp_offset) * si, block_width * si, guardoffset * si, 5 * si, - image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, i * si + xoffset_si, block_width * si, + guard_yoffset_si, guard_height_si, image_width, image_height, DEFAULT_INK); latch = 0; } else { /* a space */ latch = 1; } i += block_width; - } while (i < 96 + comp_offset); + } while (i < 96 + comp_xoffset); } else if (upceanflag == 13) { /* EAN-13 */ - draw_bar(pixelbuf, (0 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (2 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (46 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (48 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (92 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); - draw_bar(pixelbuf, (94 + xoffset) * si, 1 * si, guardoffset * si, 5 * si, image_width, image_height, - DEFAULT_INK); + draw_bar(pixelbuf, 0 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 2 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 46 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 48 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 92 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); + draw_bar(pixelbuf, 94 * si + comp_xoffset_si, 1 * si, guard_yoffset_si, guard_height_si, + image_width, image_height, DEFAULT_INK); } } + /* Add the text */ + if (!hide_text) { + int textdone = 0; + int text_xposn; + int text_yposn; + + text_yposn = yoffset_si + symbol_height_si + (int) (text_gap * si); /* Calculated to top of text */ + if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) { + text_yposn += symbol->border_width * si; + } if (upceanflag) { + /* Note font sizes halved as in pixels */ /* Halved again to get middle position that draw_string() expects */ @@ -1180,98 +1133,90 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl output_upcean_split_text(upceanflag, symbol->text, textpart1, textpart2, textpart3, textpart4); if (upceanflag == 6) { /* UPC-E */ - textpos = (-(5 + upcea_width_adj) + xoffset) * si; - draw_string(pixelbuf, textpart1, textpos, default_text_posn + upcea_height_adj, - textflags | SMALL_TEXT, image_width, image_height, si); - textpos = (24 + xoffset) * si; - draw_string(pixelbuf, textpart2, textpos, default_text_posn, textflags, image_width, image_height, - si); - textpos = (51 + 3 + upcea_width_adj + xoffset) * si; - draw_string(pixelbuf, textpart3, textpos, default_text_posn + upcea_height_adj, - textflags | SMALL_TEXT, image_width, image_height, si); + text_xposn = -(5 + upcea_width_adj) * si + comp_xoffset_si; + draw_string(pixelbuf, textpart1, text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT, + image_width, image_height, si); + text_xposn = 24 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart2, text_xposn, text_yposn, textflags, image_width, image_height, si); + text_xposn = (51 + 3 + upcea_width_adj) * si + comp_xoffset_si; + draw_string(pixelbuf, textpart3, text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT, + image_width, image_height, si); textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = (61 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (61 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; case 5: - textpos = (75 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (75 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; } } else if (upceanflag == 8) { /* EAN-8 */ - textpos = (17 + xoffset) * si; - draw_string(pixelbuf, textpart1, textpos, default_text_posn, textflags, image_width, image_height, - si); - textpos = (50 + xoffset) * si; - draw_string(pixelbuf, textpart2, textpos, default_text_posn, textflags, image_width, image_height, - si); + text_xposn = 17 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart1, text_xposn, text_yposn, textflags, image_width, image_height, si); + text_xposn = 50 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart2, text_xposn, text_yposn, textflags, image_width, image_height, si); textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = (77 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (77 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; case 5: - textpos = (91 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (91 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; } } else if (upceanflag == 12) { /* UPC-A */ - textpos = (-(5 + upcea_width_adj) + xoffset) * si; - draw_string(pixelbuf, textpart1, textpos, default_text_posn + upcea_height_adj, - textflags | SMALL_TEXT, image_width, image_height, si); - textpos = (27 + xoffset) * si; - draw_string(pixelbuf, textpart2, textpos, default_text_posn, textflags, image_width, image_height, - si); - textpos = (67 + xoffset) * si; - draw_string(pixelbuf, textpart3, textpos, default_text_posn, textflags, image_width, image_height, - si); - textpos = (95 + 5 + upcea_width_adj + xoffset) * si; - draw_string(pixelbuf, textpart4, textpos, default_text_posn + upcea_height_adj, - textflags | SMALL_TEXT, image_width, image_height, si); + text_xposn = (-(5 + upcea_width_adj)) * si + comp_xoffset_si; + draw_string(pixelbuf, textpart1, text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT, + image_width, image_height, si); + text_xposn = 27 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart2, text_xposn, text_yposn, textflags, image_width, image_height, si); + text_xposn = 67 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart3, text_xposn, text_yposn, textflags, image_width, image_height, si); + text_xposn = (95 + 5 + upcea_width_adj) * si + comp_xoffset_si; + draw_string(pixelbuf, textpart4, text_xposn, text_yposn + upcea_height_adj, textflags | SMALL_TEXT, + image_width, image_height, si); textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = (105 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (105 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; case 5: - textpos = (119 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (119 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; } } else if (upceanflag == 13) { /* EAN-13 */ - textpos = (-(5 + ean_width_adj) + xoffset) * si; - draw_string(pixelbuf, textpart1, textpos, default_text_posn, textflags, image_width, image_height, - si); - textpos = (24 + xoffset) * si; - draw_string(pixelbuf, textpart2, textpos, default_text_posn, textflags, image_width, image_height, - si); - textpos = (71 + xoffset) * si; - draw_string(pixelbuf, textpart3, textpos, default_text_posn, textflags, image_width, image_height, - si); + text_xposn = (-(5 + ean_width_adj)) * si + comp_xoffset_si; + draw_string(pixelbuf, textpart1, text_xposn, text_yposn, textflags, image_width, image_height, si); + text_xposn = 24 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart2, text_xposn, text_yposn, textflags, image_width, image_height, si); + text_xposn = 71 * si + comp_xoffset_si; + draw_string(pixelbuf, textpart3, text_xposn, text_yposn, textflags, image_width, image_height, si); textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = (105 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (105 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; case 5: - textpos = (119 + xoffset + addon_gap) * si; - draw_string(pixelbuf, addon, textpos, addon_text_posn, textflags, image_width, image_height, - si); + text_xposn = (119 + addon_gap) * si + comp_xoffset_si; + draw_string(pixelbuf, addon, text_xposn, addon_text_yposn, textflags, + image_width, image_height, si); break; } } @@ -1282,46 +1227,41 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl unsigned char local_text[sizeof(symbol->text)] = {0}; to_iso8859_1(symbol->text, local_text); /* Put the human readable text at the bottom */ - textpos = (main_width / 2 + xoffset) * si; - draw_string(pixelbuf, local_text, textpos, default_text_posn, textflags, image_width, image_height, - si); + text_xposn = (main_width / 2) * si + comp_xoffset_si; + draw_string(pixelbuf, local_text, text_xposn, text_yposn, textflags, image_width, image_height, si); } } - xoffset -= comp_offset; - - // Binding and boxes - if (symbol->output_options & BARCODE_BIND) { - if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { - float sep_height = 1.0f; - if (symbol->option_3 > 0 && symbol->option_3 <= 4) { - sep_height = symbol->option_3; - } - /* row binding */ - if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) { - for (r = 1; r < symbol->rows; r++) { - row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height; - draw_bar(pixelbuf, xoffset * si, symbol->width * si, - ((r * row_height) + textoffset + yoffset - sep_height / 2) * si, sep_height * si, - image_width, image_height, DEFAULT_INK); - } - } else { - for (r = 1; r < symbol->rows; r++) { - /* Avoid 11-module start and 13-module stop chars */ - row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height; - draw_bar(pixelbuf, (xoffset + 11) * si, (symbol->width - 24) * si, - ((r * row_height) + textoffset + yoffset - sep_height / 2) * si, sep_height * si, - image_width, image_height, DEFAULT_INK); - } - } + // Separator binding for stacked barcodes + if ((symbol->output_options & BARCODE_BIND) && (symbol->rows > 1) && is_stackable(symbol->symbology)) { + int sep_xoffset_si = xoffset_si; + int sep_width_si = symbol->width * si; + int sep_height_si, sep_yoffset_si; + float sep_height = 1.0f; + if (symbol->option_3 > 0 && symbol->option_3 <= 4) { + sep_height = symbol->option_3; + } + sep_height_si = (int) (sep_height * si); + sep_yoffset_si = yoffset_si - sep_height_si / 2; + if (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF) { + /* Avoid 11-module start and 13-module stop chars */ + sep_xoffset_si += 11 * si; + sep_width_si -= (11 + 13) * si; + } + for (r = 1; r < symbol->rows; r++) { + float row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height; + draw_bar(pixelbuf, sep_xoffset_si, sep_width_si, (r * row_height) * si + sep_yoffset_si, sep_height_si, + image_width, image_height, DEFAULT_INK); } } - draw_bind_box(symbol, pixelbuf, xoffset, roffset, textoffset, 0 /*overspill*/, image_width, image_height, si); + draw_bind_box(symbol, pixelbuf, xoffset_si, yoffset_si, symbol_height_si, 0 /*dot_overspill_si*/, + image_width, image_height, si); if (!half_int_scaling) { - scale_width = image_width * scaler; - scale_height = image_height * scaler; + unsigned char *scaled_pixelbuf; + int scale_width = (int) (image_width * scaler); + int scale_height = (int) (image_height * scaler); /* Apply scale options by creating another pixel buffer */ if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) { @@ -1331,11 +1271,11 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl } memset(scaled_pixelbuf, DEFAULT_PAPER, (size_t) scale_width * scale_height); - for (vert = 0; vert < scale_height; vert++) { - int vert_row = vert * scale_width; - int image_vert_row = ((int) (vert / scaler)) * image_width; - for (horiz = 0; horiz < scale_width; horiz++) { - *(scaled_pixelbuf + vert_row + horiz) = *(pixelbuf + image_vert_row + (int) (horiz / scaler)); + for (r = 0; r < scale_height; r++) { + int scaled_row = r * scale_width; + int image_row = ((int) (r / scaler)) * image_width; + for (i = 0; i < scale_width; i++) { + *(scaled_pixelbuf + scaled_row + i) = *(pixelbuf + image_row + (int) (i / scaler)); } } diff --git a/backend/tests/data/gif/code16k_height0.5_wsp3_vwsp5.gif b/backend/tests/data/gif/code16k_height0.5_wsp3_vwsp5.gif new file mode 100644 index 0000000000000000000000000000000000000000..96c45c6f5fda714ca2af1b4920140a096a56d61e GIT binary patch literal 140 zcmV;70CWFGNk%v~VXgog0Pp|+|Ns90001li0002402%-Q0&9eismtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~ei#S}hs2`sh)gP%%%<}RjY_A~s`ZMsda~TE u_iOr!$K)oXj83c9?6&(|{K@C^y8VvN>-YS={|^`_I7nD%c!)?-002AAnM#EK literal 0 HcmV?d00001 diff --git a/backend/tests/data/gif/code16k_height1.5_wsp3_vwsp5.gif b/backend/tests/data/gif/code16k_height1.5_wsp3_vwsp5.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed50d31feb20069c68a91f1ea89ebded880a7df8 GIT binary patch literal 197 zcmV;$06PCiNk%v~VXgoi0Pp|+|Ns90001li0002402}}S0;GhGsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~ei#S}hs2`sh)gP%%%<}RjY_A~s`ZMsdWwjk z!Fw2Xh2w8v3`U;;T=v>5PPEf*bsQX5n@!oi{}0FqI7nE?BuIDnR=1G2h-U=%xOODD z*GNeu>8RkyiD?)rI!anJ4;(@dyAW^yUW|_`wJW#Qvd)vqo`n) literal 0 HcmV?d00001 diff --git a/backend/tests/data/gif/itf14_height0.5_1.1.gif b/backend/tests/data/gif/itf14_height0.5_1.1.gif new file mode 100644 index 0000000000000000000000000000000000000000..3696cac9e9c92f5aa1e7483bf86c38a254eb91e3 GIT binary patch literal 548 zcmV+<0^9vZNk%v~VQT>>0Pq0-00030|Nkri0001M0Vn_f0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpZahs2`sh)gP%%%<}RjY_A~s`ZM^YPVc& z;0q3m$AQDwa0ZakWyLy?R=3}AM4desoAvUxee9Md2q?EO$oH4WW=NPAwiw9x*oOzU z7nnB*M>xn>Nd{_}5lSjrcuMEzXnF~m>baR|%6ZqPxu<9=T8r9<>#B--``H8#;UlF`~qY6f0W1h%uwajsF}wdi)47q{xvZOPUN>=@_wQ zcqCb3#Rn0qR*+(?I*Bu<&VYqp(z5lbr!1Le9{Hr?GbYfYYj!$)3bhnaH7xaa%!-wVwY--#S|&lrD5BC-BcE>-n|{w(zR;$tXn&sTDZ5uxh$}e!(yO($4yo>wb#td mV~?NiJ-hnjK^>>G3D$9D_wlE`x8L&S`u+U-`vb>V002AhrW))3 literal 0 HcmV?d00001 diff --git a/backend/tests/data/gif/itf14_height0.5_box0_0.5.gif b/backend/tests/data/gif/itf14_height0.5_box0_0.5.gif new file mode 100644 index 0000000000000000000000000000000000000000..460984634034c026980ad7826268b28ea1e5bda4 GIT binary patch literal 65 zcmZ?wbh9u|oXx<<@PUEh|Ns9C3=BFz%m5N$U{Yx5XIypcqFBt8lgIszRHbp(iXXKU Seld56SzeY{7)KBTgEat|pA{bf literal 0 HcmV?d00001 diff --git a/backend/tests/data/gif/itf14_height61.8_bind4_wsp24_3.gif b/backend/tests/data/gif/itf14_height61.8_bind4_wsp24_3.gif index f8bfb1eefcc49ee2d274c557b088e3f2d65a0f59..91154bdf6a4daa1535dbbf3920061b76ee2c390d 100644 GIT binary patch delta 1188 zcmV;V1Y7&xhyj3!0UJk2MmRTN!UWR+@Bsh-00960|11Ci006=S)3F$N=5?O#hXO<%RV8m&g}pdY{RVb8VfhHEJT0<*S0D**#ZA94cDHt62K1t zzX)SL8ege8uIIXUw0h#adRsdQAi)Q#OQWsFn64jtt`GZ2)Tb7!?Py)JJHG?Gyi2?#P&~iav%?#_ z#%nsNU_m}Xyu1VZ%XmD&Up&3*ySJl!$M4O;lmGk2Z#>K+`^p!=%V&qnH_FUgd@6rP ze9kAl&HMaURD8q-e9G^9%pX0j_k7U{{m+Ly&X0T)WIV}(1jsAB(u2ItuY1iSJ=d4I z)%Ob46TQFp`><5~(^LJ>ll{_*J=;$_(bGiN$33<~JI+h+N=H5 z=RMHBz1_>b;d}bmQ%~5d{n+b$ut$IW*^hnVFMi_>KHwMr;b(rPPrl02J>^@z-YLkCYl!BzKBKRG-v>V9pT5bDOvBT?$lE^T>%NWr3&N~^wY$FX?=|cb zKJS12--rI)TmH=FzS$pt>ZJY&0Kc&hzxCt)wCq1W^6Px|FaO^=f7%!S?1xRmK4iV| zga7rX|DJb$)3ZPKm%h>aJ^J%J{JVeK8%E75yZY~cp4&eG#1GI@z-J4-HchqBWs8y5 zGVqeVQY^#yXVcZfU6i*o=77yG@wz=rr_k{4 z{OoS2XJVZ=XTx5*mqvO%bvr9mGbODlF(YdUA>C`OCqr3you0gLZrghe+VV{P~y~?QE~mmnpNvou3ddXMOl!jOr~O&QXQ+b zDA=^g*ed1omf=vZb?x58n^$iwxn$4wRa+Kt*rRCw4jYGh;0UJk2MmRTN!UWO*@Bsh-00960|11Ci006=S(y<$KJ|`&x0$=yF zU;i~=2ex1jHenaGVIMYPC$?fQHe)xoV?Q=zN48{7HnX-qD**#1d0CU>KOqCpIh~UT zKrMfnSH!JA4cDHt62K1tzsL?2HD5_OsE4|}ReIuFdRsdQAi)QvOXH(`x~RYUtFQWx zSo&sRdKG9oE*DIvw|b1hy01ezSAc*T1bePyg0PPO9Nu{S%lM+5+8`?R-#vP(O%k9&DM`zC*UyR&=2up7{|w|k^}ySk?Vyd(0wS38p| zJGrB~w(Gkk@H@HJv%R~!z!y5IU_n0NySAhH%NRVn|2wyfyRk!j!SBtyGyB00JjPr5 z#23NEXNSc%%EtS9D(HL2$GgXy{8#jQzNdS{kNo0xcgTCLNKE&@s>EHe6x4f&XzVAP^=1aWe_x$TW z{_W3x?OT29t9>}&zVT;1Qw03)Pk$8$KlJbae(M*%>mUE;C;z@b|IiP=$_q_L=d-={ zQ$PBLx%IdH`aggBGe6^Zf7A;<_NRmMZ~yg&e){kKm%l#&#D_$^?gUN-I8C)HW{WAC zJdL|Ru`|K!B+IRRRQP*Y$)0n4lYT-MfBM74UO7*8M9O+yysk`pGox#1M|q2S!^9yr z$K9G=^?QEb{|5{d93(6>JVZ>KnagWSiBrR?W2{?ww2Y%%gLK@KRYXly zU1e=`eT9vcomJBO3iUJvy^Yl69d&^a9=`J(Gp70crOU-#?oCFfou;m~zQ)ehf8OS{ zvORVN$5aOY4v#h`P9J{mWIq!x|2`jwXLi5u&ez}P@Av-)7?2#gQ^m~DvxiKcI)=>< zE-YAz;4W|wDb5p^QR7CA9X);oNrc77h?&eZ!kF;gN`wRPr6dU|CbWl>PL_O$GUQI4 zJ$?QJ8g$RhcGBvhl(#IY(Udfgf7&z|bzqpA7Y())npNvou3f!mCCaj#(o;FBI#ubi z9@?;M&nkq97TVIUb?x58n^!L@VxJiLE!hyNroTI=HUxZ817UTT`symoEb?B;l`UV! zoH@v2T$AB2M*KN&W5a_height = data[i].height; + } + if (data[i].whitespace_width) { + symbol->whitespace_width = data[i].whitespace_width; + } + if (data[i].whitespace_height) { + symbol->whitespace_height = data[i].whitespace_height; + } + if (data[i].border_width) { + symbol->border_width = data[i].border_width; + } + if (data[i].scale != -1) { + symbol->scale = data[i].scale; + } if (data[i].dot_size != -1) { symbol->dot_size = data[i].dot_size; } diff --git a/backend/tests/test_svg.c b/backend/tests/test_svg.c index 506bcfe0..683f20a7 100644 --- a/backend/tests/test_svg.c +++ b/backend/tests/test_svg.c @@ -138,6 +138,7 @@ static void test_print(int index, int generate, int debug) { int text_length; if (index != -1 && i != index) continue; + if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i); // ZINT_DEBUG_TEST_PRINT 16 symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); diff --git a/backend/vector.c b/backend/vector.c index f7035863..624fb7ba 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -30,7 +30,6 @@ */ /* vim: set ts=4 sw=4 et : */ -#include #include #ifdef _MSC_VER @@ -45,11 +44,15 @@ INTERNAL int ps_plot(struct zint_symbol *symbol); INTERNAL int svg_plot(struct zint_symbol *symbol); INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle); -static struct zint_vector_rect *vector_plot_create_rect(float x, float y, float width, float height) { +static struct zint_vector_rect *vector_plot_create_rect(struct zint_symbol *symbol, + const float x, const float y, const float width, const float height) { struct zint_vector_rect *rect; rect = (struct zint_vector_rect *) malloc(sizeof(struct zint_vector_rect)); - if (!rect) return NULL; + if (!rect) { + strcpy(symbol->errtxt, "691: Insufficient memory for vector rectangle"); + return NULL; + } rect->next = NULL; rect->x = x; @@ -61,23 +64,25 @@ static struct zint_vector_rect *vector_plot_create_rect(float x, float y, float return rect; } -static int vector_plot_add_rect(struct zint_symbol *symbol, struct zint_vector_rect *rect, +static void vector_plot_add_rect(struct zint_symbol *symbol, struct zint_vector_rect *rect, struct zint_vector_rect **last_rect) { - if (!rect) return 0; if (*last_rect) (*last_rect)->next = rect; else symbol->vector->rectangles = rect; // first rectangle *last_rect = rect; - return 1; } -static struct zint_vector_hexagon *vector_plot_create_hexagon(float x, float y, float diameter) { +static struct zint_vector_hexagon *vector_plot_create_hexagon(struct zint_symbol *symbol, + const float x, const float y, const float diameter) { struct zint_vector_hexagon *hexagon; hexagon = (struct zint_vector_hexagon *) malloc(sizeof(struct zint_vector_hexagon)); - if (!hexagon) return NULL; + if (!hexagon) { + strcpy(symbol->errtxt, "692: Insufficient memory for vector hexagon"); + return NULL; + } hexagon->next = NULL; hexagon->x = x; hexagon->y = y; @@ -87,24 +92,26 @@ static struct zint_vector_hexagon *vector_plot_create_hexagon(float x, float y, return hexagon; } -static int vector_plot_add_hexagon(struct zint_symbol *symbol, struct zint_vector_hexagon *hexagon, +static void vector_plot_add_hexagon(struct zint_symbol *symbol, struct zint_vector_hexagon *hexagon, struct zint_vector_hexagon **last_hexagon) { - if (!hexagon) return 0; if (*last_hexagon) (*last_hexagon)->next = hexagon; else symbol->vector->hexagons = hexagon; // first hexagon *last_hexagon = hexagon; - return 1; } -static struct zint_vector_circle *vector_plot_create_circle(float x, float y, float diameter, float width, - int colour) { +static struct zint_vector_circle *vector_plot_create_circle(struct zint_symbol *symbol, + const float x, const float y, const float diameter, const float width, + const int colour) { struct zint_vector_circle *circle; circle = (struct zint_vector_circle *) malloc(sizeof(struct zint_vector_circle)); - if (!circle) return NULL; + if (!circle) { + strcpy(symbol->errtxt, "693: Insufficient memory for vector circle"); + return NULL; + } circle->next = NULL; circle->x = x; circle->y = y; @@ -115,25 +122,26 @@ static struct zint_vector_circle *vector_plot_create_circle(float x, float y, fl return circle; } -static int vector_plot_add_circle(struct zint_symbol *symbol, struct zint_vector_circle *circle, +static void vector_plot_add_circle(struct zint_symbol *symbol, struct zint_vector_circle *circle, struct zint_vector_circle **last_circle) { - if (!circle) return 0; if (*last_circle) (*last_circle)->next = circle; else symbol->vector->circles = circle; // first circle *last_circle = circle; - return 1; } -static int vector_plot_add_string(struct zint_symbol *symbol, - unsigned char *text, float x, float y, float fsize, float width, int halign, - struct zint_vector_string **last_string) { +static int vector_plot_add_string(struct zint_symbol *symbol, const unsigned char *text, + const float x, const float y, const float fsize, const float width, const int halign, + struct zint_vector_string **last_string) { struct zint_vector_string *string; string = (struct zint_vector_string *) malloc(sizeof(struct zint_vector_string)); - if (!string) return 0; + if (!string) { + strcpy(symbol->errtxt, "694: Insufficient memory for vector string"); + return 0; + } string->next = NULL; string->x = x; string->y = y; @@ -142,8 +150,12 @@ static int vector_plot_add_string(struct zint_symbol *symbol, string->length = (int) ustrlen(text); string->rotation = 0; string->halign = halign; - string->text = (unsigned char *) malloc(ustrlen(text) + 1); - if (!string->text) { free(string); return 0; } + string->text = (unsigned char *) malloc(string->length + 1); + if (!string->text) { + free(string); + strcpy(symbol->errtxt, "695: Insufficient memory for vector string text"); + return 0; + } ustrcpy(string->text, text); if (*last_string) @@ -201,7 +213,7 @@ INTERNAL void vector_free(struct zint_symbol *symbol) { } } -static void vector_scale(struct zint_symbol *symbol, int file_type) { +static void vector_scale(struct zint_symbol *symbol, const int file_type) { struct zint_vector_rect *rect; struct zint_vector_hexagon *hex; struct zint_vector_circle *circle; @@ -254,10 +266,9 @@ static void vector_scale(struct zint_symbol *symbol, int file_type) { string->fsize *= scale; string = string->next; } - return; } -static void vector_rotate(struct zint_symbol *symbol, int rotate_angle) { +static void vector_rotate(struct zint_symbol *symbol, const int rotate_angle) { // Rotates the image struct zint_vector_rect *rect; struct zint_vector_hexagon *hex; @@ -355,8 +366,6 @@ static void vector_rotate(struct zint_symbol *symbol, int rotate_angle) { symbol->vector->height = symbol->vector->width; symbol->vector->width = temp; } - - return; } static void vector_reduce_rectangles(struct zint_symbol *symbol) { @@ -382,45 +391,39 @@ static void vector_reduce_rectangles(struct zint_symbol *symbol) { rect = rect->next; } - - return; } INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type) { int error_number; float large_bar_height; - int textdone = 0; int main_width; - int comp_offset = 0; + int comp_xoffset = 0; unsigned char addon[6]; int addon_gap = 0; - float addon_text_posn = 0.0f; - float addon_bar_height = 0.0f; + float addon_text_yposn = 0.0f; float xoffset, yoffset, roffset, boffset; float textoffset; - float default_text_posn; - float row_height, row_posn; + float yposn; int upceanflag = 0; int addon_latch = 0; unsigned char textpart1[5], textpart2[7], textpart3[7], textpart4[2]; - float textpos; int hide_text; int i, r; int text_height; /* Font pixel size (so whole integers) */ + float text_gap; /* Gap between barcode and text */ + float guard_height; int upcae_outside_text_height = 0; /* UPC-A/E outside digits font size */ float digit_ascent_factor = 0.25f; /* Assuming digit ascent roughly 25% less than font size */ - float text_gap; /* Gap between barcode and text */ float dot_overspill = 0.0f; float dot_offset = 0.0f; int rect_count, last_row_start = 0; - int this_row; struct zint_vector *vector; - struct zint_vector_rect *rectangle, *rect, *last_rectangle = NULL; - struct zint_vector_hexagon *last_hexagon = NULL; + struct zint_vector_rect *rect, *last_rectangle = NULL; + struct zint_vector_hexagon *hexagon, *last_hexagon = NULL; struct zint_vector_string *last_string = NULL; - struct zint_vector_circle *last_circle = NULL; + struct zint_vector_circle *circle, *last_circle = NULL; // Free any previous rendering structures vector_free(symbol); @@ -433,7 +436,10 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ // Allocate memory vector = symbol->vector = (struct zint_vector *) malloc(sizeof(struct zint_vector)); - if (!vector) return ZINT_ERROR_MEMORY; + if (!vector) { + strcpy(symbol->errtxt, "696: Insufficient memory for vector header"); + return ZINT_ERROR_MEMORY; + } vector->rectangles = NULL; vector->hexagons = NULL; vector->circles = NULL; @@ -444,10 +450,11 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ main_width = symbol->width; if (is_extendable(symbol->symbology)) { - upceanflag = output_process_upcean(symbol, &main_width, &comp_offset, addon, &addon_gap); + upceanflag = output_process_upcean(symbol, &main_width, &comp_xoffset, addon, &addon_gap); } - output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset); + output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset, 0 /*scaler*/, + NULL, NULL, NULL, NULL); /* Note font sizes scaled by 2 so really twice these values */ if (upceanflag) { @@ -456,18 +463,22 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ upcae_outside_text_height = symbol->output_options & SMALL_TEXT ? 6 : 7; /* Negative to move close to barcode (less digit ascent, then add 0.5X) */ text_gap = -text_height * digit_ascent_factor + 0.5f; + /* Guard bar height (none for EAN-2 and EAN-5) */ + guard_height = upceanflag != 2 && upceanflag != 5 ? 5.0f : 0.0f; /* TODO: use zint_symbol field */ } else { text_height = symbol->output_options & SMALL_TEXT ? 6 : 7; text_gap = text_height * 0.1f; + guard_height = 0.0f; } hide_text = ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)); if (hide_text) { - textoffset = upceanflag && upceanflag != 2 && upceanflag != 5 ? 5.0f : 0.0f; /* Allow for guard bars */ + textoffset = guard_height; } else { if (upceanflag) { - textoffset = text_height + 0.2f + text_gap; /* Add fudge for anti-aliasing of digits */ + /* Add fudge for anti-aliasing of digits */ + textoffset = (text_height > guard_height ? text_height : guard_height) + 0.2f + text_gap; } else { textoffset = text_height * 1.25f + text_gap; /* Allow +25% for characters descending below baseline */ } @@ -487,16 +498,8 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ vector->width = symbol->width + dot_overspill + (xoffset + roffset); vector->height = symbol->height + textoffset + dot_overspill + (yoffset + boffset); - if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) { - default_text_posn = symbol->height + text_height + text_gap + symbol->whitespace_height - + symbol->border_width * 2; - } else { - default_text_posn = symbol->height + text_height + text_gap + symbol->whitespace_height; - } - // Plot Maxicode symbols if (symbol->symbology == BARCODE_MAXICODE) { - struct zint_vector_circle *circle; float bull_x, bull_y, bull_d_incr, bull_width; const float two_div_sqrt3 = 1.1547f; /* 2 / √3 */ const float sqrt3_div_two = 0.866f; /* √3 / 2 == 1.5 / √3 */ @@ -519,13 +522,17 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ bull_d_incr = (hex_diameter * 9 - hex_ydiameter) / 5.0f; bull_width = bull_d_incr / 2.0f; - circle = vector_plot_create_circle(bull_x, bull_y, hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width, - 0); + circle = vector_plot_create_circle(symbol, bull_x, bull_y, + hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width, 0); + if (!circle) return ZINT_ERROR_MEMORY; vector_plot_add_circle(symbol, circle, &last_circle); - circle = vector_plot_create_circle(bull_x, bull_y, hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width, - 0); + circle = vector_plot_create_circle(symbol, bull_x, bull_y, + hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width, 0); + if (!circle) return ZINT_ERROR_MEMORY; vector_plot_add_circle(symbol, circle, &last_circle); - circle = vector_plot_create_circle(bull_x, bull_y, hex_ydiameter + bull_d_incr - bull_width, bull_width, 0); + circle = vector_plot_create_circle(symbol, bull_x, bull_y, + hex_ydiameter + bull_d_incr - bull_width, bull_width, 0); + if (!circle) return ZINT_ERROR_MEMORY; vector_plot_add_circle(symbol, circle, &last_circle); /* Hexagons */ @@ -536,7 +543,8 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ for (i = 0; i < symbol->width - odd_row; i++) { if (module_is_set(symbol, r, i)) { const float xposn = i * hex_diameter + xposn_offset; - struct zint_vector_hexagon *hexagon = vector_plot_create_hexagon(xposn, yposn, hex_diameter); + hexagon = vector_plot_create_hexagon(symbol, xposn, yposn, hex_diameter); + if (!hexagon) return ZINT_ERROR_MEMORY; vector_plot_add_hexagon(symbol, hexagon, &last_hexagon); } } @@ -546,10 +554,9 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ for (r = 0; r < symbol->rows; r++) { for (i = 0; i < symbol->width; i++) { if (module_is_set(symbol, r, i)) { - struct zint_vector_circle *circle = vector_plot_create_circle( - i + dot_offset + xoffset, - r + dot_offset + yoffset, - symbol->dot_size, 0, 0); + circle = vector_plot_create_circle(symbol, i + dot_offset + xoffset, r + dot_offset + yoffset, + symbol->dot_size, 0, 0); + if (!circle) return ZINT_ERROR_MEMORY; vector_plot_add_circle(symbol, circle, &last_circle); } } @@ -557,27 +564,27 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ // Plot rectangles - most symbols created here } else { rect_count = 0; - row_posn = yoffset; + yposn = yoffset; for (r = 0; r < symbol->rows; r++) { - this_row = r; + float row_height = symbol->row_height[r] ? symbol->row_height[r] : large_bar_height; last_row_start = rect_count; - row_height = symbol->row_height[this_row] ? symbol->row_height[this_row] : large_bar_height; i = 0; if (symbol->symbology == BARCODE_ULTRA) { do { - int module_fill = module_colour_is_set(symbol, this_row, i); + int module_fill = module_colour_is_set(symbol, r, i); int block_width = 0; do { block_width++; } while (i + block_width < symbol->width - && module_colour_is_set(symbol, this_row, i + block_width) == module_fill); + && module_colour_is_set(symbol, r, i + block_width) == module_fill); if (module_fill) { /* a colour block */ - rectangle = vector_plot_create_rect(i + xoffset, row_posn, block_width, row_height); - rectangle->colour = module_colour_is_set(symbol, this_row, i); - vector_plot_add_rect(symbol, rectangle, &last_rectangle); + rect = vector_plot_create_rect(symbol, i + xoffset, yposn, block_width, row_height); + if (!rect) return ZINT_ERROR_MEMORY; + rect->colour = module_colour_is_set(symbol, r, i); + vector_plot_add_rect(symbol, rect, &last_rectangle); rect_count++; } i += block_width; @@ -585,43 +592,45 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ } while (i < symbol->width); } else { do { - int module_fill = module_is_set(symbol, this_row, i); + float addon_row_height; + int module_fill = module_is_set(symbol, r, i); int block_width = 0; do { block_width++; } while (i + block_width < symbol->width - && module_is_set(symbol, this_row, i + block_width) == module_fill); + && module_is_set(symbol, r, i + block_width) == module_fill); + if (upceanflag && (addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { - addon_text_posn = row_posn + text_height - text_height * digit_ascent_factor; - if (addon_text_posn < 0.0f) { - addon_text_posn = 0.0f; + addon_text_yposn = yposn + text_height - text_height * digit_ascent_factor; + if (addon_text_yposn < 0.0f) { + addon_text_yposn = 0.0f; } - addon_bar_height = row_height - (addon_text_posn - row_posn) + text_gap; - if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E don't descend */ - addon_bar_height += 5.0f; + addon_row_height = row_height - (addon_text_yposn - yposn) + text_gap; + if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E add-ons don't descend */ + addon_row_height += guard_height; } - if (addon_bar_height < 0.5f) { - addon_bar_height = 0.5f; + if (addon_row_height < 0.5f) { + addon_row_height = 0.5f; } addon_latch = 1; } if (module_fill) { /* a bar */ if (addon_latch == 0) { - rectangle = vector_plot_create_rect(i + xoffset, row_posn, block_width, row_height); + rect = vector_plot_create_rect(symbol, i + xoffset, yposn, block_width, row_height); } else { - rectangle = vector_plot_create_rect(i + xoffset, addon_text_posn - text_gap, block_width, - addon_bar_height); + rect = vector_plot_create_rect(symbol, i + xoffset, addon_text_yposn - text_gap, + block_width, addon_row_height); } - vector_plot_add_rect(symbol, rectangle, &last_rectangle); + if (!rect) return ZINT_ERROR_MEMORY; + vector_plot_add_rect(symbol, rect, &last_rectangle); rect_count++; } i += block_width; } while (i < symbol->width); } - - row_posn += row_height; + yposn += row_height; } } @@ -636,7 +645,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ case 14: case 15: case 16: - rect->height += 5.0f; + rect->height += guard_height; break; } i++; @@ -651,7 +660,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ case 11: case 20: case 21: - rect->height += 5.0f; + rect->height += guard_height; break; } i++; @@ -670,7 +679,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ case 27: case 28: case 29: - rect->height += 5.0f; + rect->height += guard_height; break; } i++; @@ -685,7 +694,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ case 15: case 28: case 29: - rect->height += 5.0f; + rect->height += guard_height; break; } i++; @@ -696,8 +705,16 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ /* Add the text */ if (!hide_text) { + int textdone = 0; + float text_xposn; + float text_yposn; - xoffset += comp_offset; + xoffset += comp_xoffset; + + text_yposn = yoffset + symbol->height + text_height + text_gap; /* Calculated to bottom of text */ + if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BOX | BARCODE_BIND))) { + text_yposn += symbol->border_width; + } if (upceanflag) { float textwidth; @@ -705,115 +722,115 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ output_upcean_split_text(upceanflag, symbol->text, textpart1, textpart2, textpart3, textpart4); if (upceanflag == 6) { /* UPC-E */ - textpos = -5.0f + xoffset; + text_xposn = -5.0f + xoffset; textwidth = 6.2f; - vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, upcae_outside_text_height, - textwidth, 2 /*right align*/, &last_string); - textpos = 24.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn, upcae_outside_text_height, + textwidth, 2 /*right align*/, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 24.0f + xoffset; textwidth = 6.0f * 8.5f; - vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); - textpos = 51.0f + 3.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn, text_height, + textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 51.0f + 3.0f + xoffset; textwidth = 6.2f; - vector_plot_add_string(symbol, textpart3, textpos, default_text_posn, upcae_outside_text_height, - textwidth, 1 /*left align*/, &last_string); + if (!vector_plot_add_string(symbol, textpart3, text_xposn, text_yposn, upcae_outside_text_height, + textwidth, 1 /*left align*/, &last_string)) return ZINT_ERROR_MEMORY; textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = 61.0f + xoffset + addon_gap; + text_xposn = 61.0f + xoffset + addon_gap; textwidth = 2.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; case 5: - textpos = 75.0f + xoffset + addon_gap; + text_xposn = 75.0f + xoffset + addon_gap; textwidth = 5.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; } } else if (upceanflag == 8) { /* EAN-8 */ - textpos = 17.0f + xoffset; + text_xposn = 17.0f + xoffset; textwidth = 4.0f * 8.5f; - vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); - textpos = 50.0f + xoffset; - vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 50.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = 77.0f + xoffset + addon_gap; + text_xposn = 77.0f + xoffset + addon_gap; textwidth = 2.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; case 5: - textpos = 91.0f + xoffset + addon_gap; + text_xposn = 91.0f + xoffset + addon_gap; textwidth = 5.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; } } else if (upceanflag == 12) { /* UPC-A */ - textpos = -5.0f + xoffset; + text_xposn = -5.0f + xoffset; textwidth = 6.2f; - vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, upcae_outside_text_height, - textwidth, 2 /*right align*/, &last_string); - textpos = 27.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn, upcae_outside_text_height, + textwidth, 2 /*right align*/, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 27.0f + xoffset; textwidth = 5.0f * 8.5f; - vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); - textpos = 67.0f + xoffset; - vector_plot_add_string(symbol, textpart3, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); - textpos = 95.0f + 5.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn, text_height, + textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 67.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart3, text_xposn, text_yposn, text_height, + textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 95.0f + 5.0f + xoffset; textwidth = 6.2f; - vector_plot_add_string(symbol, textpart4, textpos, default_text_posn, upcae_outside_text_height, - textwidth, 1 /*left align*/, &last_string); + if (!vector_plot_add_string(symbol, textpart4, text_xposn, text_yposn, upcae_outside_text_height, + textwidth, 1 /*left align*/, &last_string)) return ZINT_ERROR_MEMORY; textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = 105.0f + xoffset + addon_gap; + text_xposn = 105.0f + xoffset + addon_gap; textwidth = 2.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; case 5: - textpos = 119.0f + xoffset + addon_gap; + text_xposn = 119.0f + xoffset + addon_gap; textwidth = 5.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; } } else if (upceanflag == 13) { /* EAN-13 */ - textpos = -5.0f + xoffset; + text_xposn = -5.0f + xoffset; textwidth = 8.5f; - vector_plot_add_string(symbol, textpart1, textpos, default_text_posn, text_height, textwidth, - 2 /*right align*/, &last_string); - textpos = 24.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart1, text_xposn, text_yposn, + text_height, textwidth, 2 /*right align*/, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 24.0f + xoffset; textwidth = 6.0f * 8.5f; - vector_plot_add_string(symbol, textpart2, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); - textpos = 71.0f + xoffset; - vector_plot_add_string(symbol, textpart3, textpos, default_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, textpart2, text_xposn, text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; + text_xposn = 71.0f + xoffset; + if (!vector_plot_add_string(symbol, textpart3, text_xposn, text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; textdone = 1; switch (ustrlen(addon)) { case 2: - textpos = 105.0f + xoffset + addon_gap; + text_xposn = 105.0f + xoffset + addon_gap; textwidth = 2.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; case 5: - textpos = 119.0f + xoffset + addon_gap; + text_xposn = 119.0f + xoffset + addon_gap; textwidth = 5.0f * 8.5f; - vector_plot_add_string(symbol, addon, textpos, addon_text_posn, text_height, textwidth, 0, - &last_string); + if (!vector_plot_add_string(symbol, addon, text_xposn, addon_text_yposn, + text_height, textwidth, 0, &last_string)) return ZINT_ERROR_MEMORY; break; } } @@ -822,70 +839,76 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ if (!textdone) { /* Put normal human readable text at the bottom (and centered) */ // calculate start xoffset to center text - vector_plot_add_string(symbol, symbol->text, main_width / 2.0f + xoffset, default_text_posn, text_height, - symbol->width, 0, &last_string); + text_xposn = main_width / 2.0f + xoffset; + if (!vector_plot_add_string(symbol, symbol->text, text_xposn, text_yposn, + text_height, symbol->width, 0, &last_string)) return ZINT_ERROR_MEMORY; } - xoffset -= comp_offset; // Restore xoffset + xoffset -= comp_xoffset; // Restore xoffset } - // Binding and boxes - if (symbol->output_options & BARCODE_BIND) { - if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { - float sep_height = 1.0f; - if (symbol->option_3 > 0 && symbol->option_3 <= 4) { - sep_height = symbol->option_3; - } - /* row binding */ - if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) { - for (r = 1; r < symbol->rows; r++) { - row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height; - rectangle = vector_plot_create_rect(xoffset, (r * row_height) + yoffset - sep_height / 2, - symbol->width, sep_height); - vector_plot_add_rect(symbol, rectangle, &last_rectangle); - } - } else { - for (r = 1; r < symbol->rows; r++) { - /* Avoid 11-module start and 13-module stop chars */ - row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height; - rectangle = vector_plot_create_rect(xoffset + 11, (r * row_height) + yoffset - sep_height / 2, - symbol->width - 24, sep_height); - vector_plot_add_rect(symbol, rectangle, &last_rectangle); - } - } + // Separator binding for stacked barcodes + if ((symbol->output_options & BARCODE_BIND) && (symbol->rows > 1) && is_stackable(symbol->symbology)) { + float sep_xoffset = xoffset; + float sep_width = symbol->width; + float sep_height = 1.0f, sep_yoffset; + if (symbol->option_3 > 0 && symbol->option_3 <= 4) { + sep_height = symbol->option_3; + } + sep_yoffset = yoffset - sep_height / 2; + if (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF) { + /* Avoid 11-module start and 13-module stop chars */ + sep_xoffset += 11; + sep_width -= 11 + 13; + } + for (r = 1; r < symbol->rows; r++) { + float row_height = symbol->row_height[r - 1] ? symbol->row_height[r - 1] : large_bar_height; + rect = vector_plot_create_rect(symbol, sep_xoffset, (r * row_height) + sep_yoffset, + sep_width, sep_height); + if (!rect) return ZINT_ERROR_MEMORY; + vector_plot_add_rect(symbol, rect, &last_rectangle); } } + + // Bind/box if (symbol->border_width > 0) { if (symbol->output_options & (BARCODE_BOX | BARCODE_BIND)) { - float ybind_bottom = vector->height - symbol->border_width - textoffset - symbol->whitespace_height; + const float ybind_top = yoffset - symbol->border_width; + // Following equivalent to yoffset + symbol->height + dot_overspill except for BARCODE_MAXICODE + const float ybind_bot = vector->height - textoffset - boffset; // Top - rectangle = vector_plot_create_rect(0.0f, symbol->whitespace_height, vector->width, symbol->border_width); + rect = vector_plot_create_rect(symbol, 0.0f, ybind_top, vector->width, symbol->border_width); + if (!rect) return ZINT_ERROR_MEMORY; if (!(symbol->output_options & BARCODE_BOX) && (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF)) { /* CodaBlockF bind - does not extend over horizontal whitespace */ - rectangle->x = xoffset; - rectangle->width -= (2.0f * xoffset); + rect->x = xoffset; + rect->width -= xoffset + roffset; } - vector_plot_add_rect(symbol, rectangle, &last_rectangle); + vector_plot_add_rect(symbol, rect, &last_rectangle); // Bottom - rectangle = vector_plot_create_rect(0.0f, ybind_bottom, vector->width, symbol->border_width); + rect = vector_plot_create_rect(symbol, 0.0f, ybind_bot, vector->width, symbol->border_width); + if (!rect) return ZINT_ERROR_MEMORY; if (!(symbol->output_options & BARCODE_BOX) && (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF)) { /* CodaBlockF bind - does not extend over horizontal whitespace */ - rectangle->x = xoffset; - rectangle->width -= (2.0f * xoffset); + rect->x = xoffset; + rect->width -= xoffset + roffset; } - vector_plot_add_rect(symbol, rectangle, &last_rectangle); + vector_plot_add_rect(symbol, rect, &last_rectangle); } if (symbol->output_options & BARCODE_BOX) { float xbox_right = vector->width - symbol->border_width; - float box_height = vector->height - textoffset - (symbol->whitespace_height + symbol->border_width) * 2; + // Following equivalent to symbol->height except for BARCODE_MAXICODE + float box_height = vector->height - textoffset - dot_overspill - yoffset - boffset; // Left - rectangle = vector_plot_create_rect(0.0f, yoffset, symbol->border_width, box_height); - vector_plot_add_rect(symbol, rectangle, &last_rectangle); + rect = vector_plot_create_rect(symbol, 0.0f, yoffset, symbol->border_width, box_height); + if (!rect) return ZINT_ERROR_MEMORY; + vector_plot_add_rect(symbol, rect, &last_rectangle); // Right - rectangle = vector_plot_create_rect(xbox_right, yoffset, symbol->border_width, box_height); - vector_plot_add_rect(symbol, rectangle, &last_rectangle); + rect = vector_plot_create_rect(symbol, xbox_right, yoffset, symbol->border_width, box_height); + if (!rect) return ZINT_ERROR_MEMORY; + vector_plot_add_rect(symbol, rect, &last_rectangle); } } diff --git a/docs/manual.txt b/docs/manual.txt index d9587b85..296febdc 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -503,6 +503,8 @@ The minimum scale for raster output in dotty mode is 1 (see 4.14). The minimum scale for vector output is 0.1, giving a minimum X-dimension of 0.2. +The maximum scale for both raster and vector is 100. + 4.9.1 Scaling example --------------------- The GS1 General Specifications Section 5.2.6.6 "Symbol dimensions at nominal diff --git a/frontend/main.c b/frontend/main.c index 5747e1f3..ae416269 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -521,7 +521,7 @@ static int batch_process(struct zint_symbol *symbol, const char *filename, const } else { file = fopen(filename, "rb"); if (!file) { - strcpy(symbol->errtxt, "102: Unable to read input file"); + sprintf(symbol->errtxt, "102: Unable to read input file '%s'", filename); return ZINT_ERROR_INVALID_DATA; } } @@ -776,6 +776,7 @@ int main(int argc, char **argv) { #else arg_opt *arg_opts = (arg_opt *) _alloca(argc * sizeof(arg_opt)); #endif + int no_getopt_error = 1; if (argc == 1) { usage(); @@ -794,7 +795,7 @@ int main(int argc, char **argv) { win_args(&argc, &argv); #endif - while (1) { + while (no_getopt_error) { enum options { OPT_ADDONGAP = 128, OPT_BATCH, OPT_BINARY, OPT_BG, OPT_BIND, OPT_BOLD, OPT_BORDER, OPT_BOX, OPT_CMYK, OPT_COLS, OPT_DIRECT, OPT_DMRE, OPT_DOTSIZE, OPT_DOTTY, OPT_DUMP, @@ -863,7 +864,7 @@ int main(int argc, char **argv) { {"whitesp", 1, NULL, 'w'}, {NULL, 0, NULL, 0} }; - int c = getopt_long(argc, argv, "b:d:ehi:o:rtw:", long_options, &option_index); + int c = getopt_long_only(argc, argv, "b:d:ehi:o:rtw:", long_options, &option_index); if (c == -1) break; switch (c) { @@ -1258,11 +1259,13 @@ int main(int argc, char **argv) { break; case '?': + no_getopt_error = 0; break; - default: - fprintf(stderr, "Error 123: ?? getopt error 0%o\n", c); + default: /* Shouldn't happen */ + fprintf(stderr, "Error 123: ?? getopt error 0%o\n", c); /* Not reached */ fflush(stderr); + no_getopt_error = 0; break; } } diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c index f377a10d..e7baf51c 100644 --- a/frontend/tests/test_args.c +++ b/frontend/tests/test_args.c @@ -895,26 +895,27 @@ static void test_other_opts(int index, int debug) { // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { /* 0*/ { BARCODE_CODE128, "1", -1, " --bg=", "EF9900", "" }, - /* 1*/ { BARCODE_CODE128, "1", -1, " --bg=", "EF9900AA", "" }, - /* 2*/ { BARCODE_CODE128, "1", -1, " --bg=", "GF9900", "Error 654: Malformed background colour target" }, - /* 3*/ { BARCODE_CODE128, "1", -1, " --fg=", "000000", "" }, - /* 4*/ { BARCODE_CODE128, "1", -1, " --fg=", "00000000", "" }, - /* 5*/ { BARCODE_CODE128, "1", -1, " --fg=", "000000F", "Error 651: Malformed foreground colour target" }, - /* 6*/ { BARCODE_CODE128, "1", -1, " --fg=", "000000FG", "Error 653: Malformed foreground colour target" }, - /* 7*/ { BARCODE_CODE128, "1", -1, " --fontsize=", "10", "" }, - /* 8*/ { BARCODE_CODE128, "1", -1, " --fontsize=", "101", "Warning 126: Font size out of range (0 to 100), ignoring" }, - /* 9*/ { BARCODE_CODE128, "1", -1, " --nobackground", "", "" }, - /* 10*/ { BARCODE_CODE128, "1", -1, " --notext", "", "" }, - /* 11*/ { BARCODE_CODE128, "1", -1, " --reverse", "", "" }, - /* 12*/ { BARCODE_CODE128, "1", -1, " --werror", NULL, "" }, - /* 13*/ { 19, "1", -1, " --werror", NULL, "Error 207: Codabar 18 not supported" }, - /* 14*/ { BARCODE_GS1_128, "[01]12345678901231", -1, "", NULL, "" }, - /* 15*/ { BARCODE_GS1_128, "0112345678901231", -1, "", NULL, "Error 252: Data does not start with an AI" }, - /* 16*/ { BARCODE_GS1_128, "0112345678901231", -1, " --gs1nocheck", NULL, "Error 252: Data does not start with an AI" }, - /* 17*/ { BARCODE_GS1_128, "[00]376104250021234569", -1, "", NULL, "" }, - /* 18*/ { BARCODE_GS1_128, "[00]376104250021234568", -1, "", NULL, "Warning 261: AI (00) position 18: Bad checksum '8', expected '9'" }, - /* 19*/ { BARCODE_GS1_128, "[00]376104250021234568", -1, " --gs1nocheck", NULL, "" }, - /* 20*/ { BARCODE_GS1_128, "[00]376104250021234568", -1, " --werror", NULL, "Error 261: AI (00) position 18: Bad checksum '8', expected '9'" }, + /* 1*/ { BARCODE_CODE128, "1", -1, " -bg=", "EF9900", "" }, + /* 2*/ { BARCODE_CODE128, "1", -1, " --bg=", "EF9900AA", "" }, + /* 3*/ { BARCODE_CODE128, "1", -1, " --bg=", "GF9900", "Error 654: Malformed background colour target" }, + /* 4*/ { BARCODE_CODE128, "1", -1, " --fg=", "000000", "" }, + /* 5*/ { BARCODE_CODE128, "1", -1, " --fg=", "00000000", "" }, + /* 6*/ { BARCODE_CODE128, "1", -1, " --fg=", "000000F", "Error 651: Malformed foreground colour target" }, + /* 7*/ { BARCODE_CODE128, "1", -1, " --fg=", "000000FG", "Error 653: Malformed foreground colour target" }, + /* 8*/ { BARCODE_CODE128, "1", -1, " --fontsize=", "10", "" }, + /* 9*/ { BARCODE_CODE128, "1", -1, " --fontsize=", "101", "Warning 126: Font size out of range (0 to 100), ignoring" }, + /* 10*/ { BARCODE_CODE128, "1", -1, " --nobackground", "", "" }, + /* 11*/ { BARCODE_CODE128, "1", -1, " --notext", "", "" }, + /* 12*/ { BARCODE_CODE128, "1", -1, " --reverse", "", "" }, + /* 13*/ { BARCODE_CODE128, "1", -1, " --werror", NULL, "" }, + /* 14*/ { 19, "1", -1, " --werror", NULL, "Error 207: Codabar 18 not supported" }, + /* 15*/ { BARCODE_GS1_128, "[01]12345678901231", -1, "", NULL, "" }, + /* 16*/ { BARCODE_GS1_128, "0112345678901231", -1, "", NULL, "Error 252: Data does not start with an AI" }, + /* 17*/ { BARCODE_GS1_128, "0112345678901231", -1, " --gs1nocheck", NULL, "Error 252: Data does not start with an AI" }, + /* 18*/ { BARCODE_GS1_128, "[00]376104250021234569", -1, "", NULL, "" }, + /* 19*/ { BARCODE_GS1_128, "[00]376104250021234568", -1, "", NULL, "Warning 261: AI (00) position 18: Bad checksum '8', expected '9'" }, + /* 20*/ { BARCODE_GS1_128, "[00]376104250021234568", -1, " --gs1nocheck", NULL, "" }, + /* 21*/ { BARCODE_GS1_128, "[00]376104250021234568", -1, " --werror", NULL, "Error 261: AI (00) position 18: Bad checksum '8', expected '9'" }, }; int data_size = ARRAY_SIZE(data); int i; diff --git a/frontend_qt/mainWindow.ui b/frontend_qt/mainWindow.ui index a7dd3bb7..00c6a5c8 100644 --- a/frontend_qt/mainWindow.ui +++ b/frontend_qt/mainWindow.ui @@ -830,6 +830,9 @@ in X-dimensions X + + 100 + @@ -841,6 +844,9 @@ in X-dimensions X + + 100 + @@ -876,7 +882,7 @@ in X-dimensions 0.100000000000000 - 99.500000000000000 + 100.000000000000000 0.500000000000000