int dump_plot(struct zint_symbol *symbol) { FILE *f; int i, r; if(symbol->output_options & BARCODE_STDOUT) { f = stdout; } else { f = fopen(symbol->outfile, "w"); if(!f) { strcpy(symbol->errtxt, "Could not open output file"); return ZERROR_FILE_ACCESS; } } fputs("[\n", f); for (r = 0; r < symbol->rows; r++) { fputs(" [ ", f); for (i = 0; i < symbol->width; i++) { fputs(module_is_set(symbol, r, i) ? "1 " : "0 ", f); } fputs("]\n", f); } fputs("]\n", f); if(symbol->output_options & BARCODE_STDOUT) { fflush(f); } else { fclose(f); } return 0; }
int maxi_png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) { int i, row, column, xposn, yposn; int image_height, image_width; char *pixelbuf; int error_number; int xoffset, yoffset; xoffset = symbol->border_width + symbol->whitespace_width; yoffset = symbol->border_width; image_width = 300 + (2 * xoffset * 2); image_height = 300 + (2 * yoffset * 2); if (!(pixelbuf = (char *) malloc(image_width * image_height))) { printf("Insifficient memory for pixel buffer"); return ZERROR_ENCODING_PROBLEM; } else { for(i = 0; i < (image_width * image_height); i++) { *(pixelbuf + i) = '0'; } } draw_bullseye(pixelbuf, image_width, (2 * xoffset), (2 * yoffset)); for(row = 0; row < symbol->rows; row++) { yposn = row * 9; for(column = 0; column < symbol->width; column++) { xposn = column * 10; if(module_is_set(symbol, row, column)) { if(row & 1) { /* Odd (reduced) row */ xposn += 5; draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset)); } else { /* Even (full) row */ draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset)); } } } } if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { /* boundary bars */ draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height); draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height); } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height); draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height); } error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); free(pixelbuf); return error_number; }
void spigot(struct zint_symbol *symbol, int row_no) { int i; for(i = symbol->width - 1; i > 0; i--) { if(module_is_set(symbol, row_no, i - 1)) { set_module(symbol, row_no, i); } } }
static uint8_t tick(void) { float time = getSysTick() / 10000.0f; char text[128]; snprintf(text, 127, "Device Time: %.1fs", time); struct zint_symbol zs; memset(&zs, 0, sizeof(zs)); zs.input_mode = DATA_MODE; zs.option_1 = 3; /* zs.option_2 = 2; */ int qr_res = qr_code(&zs, (unsigned char *)text, strlen(text)); if (qr_res) { /* printf("Error: %i\n", qr_res); */ } int zoom = MAX(1, MIN(LED_WIDTH / (zs.width + (BORDER * 2)), LED_HEIGHT / (zs.rows + (BORDER * 2)))); static int old_width = 0; if (old_width != zs.width) { old_width = zs.width; lcdFillRGB(255, 255, 255); } int x0 = (LED_WIDTH - zoom * zs.width) / 2; int y0 = (LED_HEIGHT - zoom * zs.rows) / 2; for(int y = 0; y < zs.width; y++) { for(int x = 0; x < zs.rows; x++) { for(int y1 = y * zoom; y1 < (y + 1) * zoom; y1++) { for(int x1 = x * zoom; x1 < (x + 1) * zoom; x1++) { if (module_is_set(&zs, x, y)) { setLedXY(x0 + x1, y0 + y1, 0, 0, 0); } else { setLedXY(x0 + x1, y0 + y1, 255, 255, 255); } } } } } time++; return 0; }
int png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) { int textdone, main_width, comp_offset, large_bar_count; char textpart[10], addon[6]; float addon_text_posn, preset_height, large_bar_height; int i, r, textoffset, yoffset, xoffset, latch, image_width, image_height; char *pixelbuf; int addon_latch = 0, smalltext = 0; int this_row, block_width, plot_height, plot_yposn, textpos; float row_height, row_posn; int error_number; int default_text_posn; int next_yposn; unsigned char local_text[ustrlen(symbol->text) + 1]; if(symbol->show_hrt != 0) { to_latin1(symbol->text, local_text); } else { local_text[0] = '\0'; } textdone = 0; main_width = symbol->width; strcpy(addon, ""); comp_offset = 0; addon_text_posn = 0.0; row_height = 0; if(symbol->output_options & SMALL_TEXT) { smalltext = 1; } if (symbol->height == 0) { symbol->height = 50; } large_bar_count = 0; preset_height = 0.0; for(i = 0; i < symbol->rows; i++) { preset_height += symbol->row_height[i]; if(symbol->row_height[i] == 0) { large_bar_count++; } } if (large_bar_count == 0) { symbol->height = preset_height; large_bar_height = 10; } else { large_bar_height = (symbol->height - preset_height) / large_bar_count; } while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { comp_offset++; } /* Certain symbols need whitespace otherwise characters get chopped off the sides */ if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { switch(ustrlen(local_text)) { case 13: /* EAN 13 */ case 16: case 19: if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } main_width = 96 + comp_offset; break; default: main_width = 68 + comp_offset; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_width = 96 + comp_offset; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_width = 51 + comp_offset; } } latch = 0; r = 0; /* Isolate add-on text */ if(is_extendable(symbol->symbology)) { for(i = 0; i < ustrlen(local_text); i++) { if (latch == 1) { addon[r] = local_text[i]; r++; } if (symbol->text[i] == '+') { latch = 1; } } } addon[r] = '\0'; if(ustrlen(local_text) != 0) { textoffset = 9; } else { textoffset = 0; } xoffset = symbol->border_width + symbol->whitespace_width; yoffset = symbol->border_width; image_width = 2 * (symbol->width + xoffset + xoffset); image_height = 2 * (symbol->height + textoffset + yoffset + yoffset); if (!(pixelbuf = (char *) malloc(image_width * image_height))) { printf("Insufficient memory for pixel buffer"); return ZERROR_ENCODING_PROBLEM; } else { for(i = 0; i < (image_width * image_height); i++) { *(pixelbuf + i) = '0'; } } if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { default_text_posn = image_height - 17; } else { default_text_posn = image_height - 17 - symbol->border_width - symbol->border_width; } row_posn = textoffset + yoffset; next_yposn = textoffset + yoffset; row_height = 0; /* Plot the body of the symbol to the pixel buffer */ for(r = 0; r < symbol->rows; r++) { this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ row_posn += row_height; plot_yposn = next_yposn; if(symbol->row_height[this_row] == 0) { row_height = large_bar_height; } else { row_height = symbol->row_height[this_row]; } next_yposn = (int)(row_posn + row_height); plot_height = next_yposn - plot_yposn; i = 0; if(module_is_set(symbol, this_row, 0)) { latch = 1; } else { latch = 0; } do { block_width = 0; do { block_width++; } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); if((addon_latch == 0) && (r == 0) && (i > main_width)) { plot_height = (int)(row_height - 5.0); plot_yposn = (int)(row_posn - 5.0); addon_text_posn = row_posn + row_height - 8.0; addon_latch = 1; } if(latch == 1) { /* a bar */ draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < symbol->width); } xoffset += comp_offset; if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { /* guard bar extensions and text formatting for EAN8 and EAN13 */ switch(ustrlen(local_text)) { case 8: /* EAN-8 */ case 11: case 14: draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i]; } textpart[4] = '\0'; textpos = 2 * (17 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i + 4]; } textpart[4] = '\0'; textpos = 2 * (50 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); textdone = 1; switch(strlen(addon)) { case 2: textpos = 2 * (xoffset + 86); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; case 5: textpos = 2 * (xoffset + 100); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; } break; case 13: /* EAN 13 */ case 16: case 19: draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = 2 * (-7 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; textpos = 2 * (24 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 7]; } textpart[6] = '\0'; textpos = 2 * (71 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); textdone = 1; switch(strlen(addon)) { case 2: textpos = 2 * (xoffset + 114); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; case 5: textpos = 2 * (xoffset + 128); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; } break; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { /* guard bar extensions and text formatting for UPCA */ latch = 1; i = 0 + comp_offset; do { block_width = 0; do { block_width++; } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); if(latch == 1) { /* a bar */ draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < 11 + comp_offset); draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); latch = 1; i = 85 + comp_offset; do { block_width = 0; do { block_width++; } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); if(latch == 1) { /* a bar */ draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < 96 + comp_offset); textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = 2 * (-5 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 1]; } textpart[5] = '\0'; textpos = 2 * (27 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 6]; } textpart[6] = '\0'; textpos = 2 * (68 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); textpart[0] = symbol->text[11]; textpart[1] = '\0'; textpos = 2 * (100 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); textdone = 1; switch(strlen(addon)) { case 2: textpos = 2 * (xoffset + 116); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; case 5: textpos = 2 * (xoffset + 130); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { /* guard bar extensions and text formatting for UPCE */ draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = 2 * (-5 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; textpos = 2 * (24 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); textpart[0] = symbol->text[7]; textpart[1] = '\0'; textpos = 2 * (55 + xoffset); draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); textdone = 1; switch(strlen(addon)) { case 2: textpos = 2 * (xoffset + 70); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; case 5: textpos = 2 * (xoffset + 84); draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); break; } } xoffset -= comp_offset; /* Put boundary bars or box around symbol */ if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { /* boundary bars */ draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height); draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height); if((symbol->output_options & BARCODE_BIND) != 0) { if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { /* row binding */ for(r = 1; r < symbol->rows; r++) { draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height); } } } } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); draw_bar(pixelbuf, (symbol->width + xoffset + xoffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); } /* Put the human readable text at the bottom */ if((textdone == 0) && (ustrlen(local_text) != 0)) { textpos = (image_width / 2); draw_string(pixelbuf, (char*)local_text, textpos, default_text_posn, smalltext, image_width, image_height); } error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); free(pixelbuf); return error_number; }
int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { /* splits string to parts before and after '+' parts */ unsigned char first_part[20] = { 0 }, second_part[20] = { 0 }, dest[1000] = { 0 }; unsigned char local_source[20] = { 0 }; unsigned int latch, reader, writer, with_addon; int error_number, i; with_addon = FALSE; latch = FALSE; writer = 0; if(src_len > 19) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } if(symbol->symbology != BARCODE_ISBNX) { /* ISBN has it's own checking routine */ error_number = is_sane("0123456789+", source, src_len); if(error_number == ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } } else { error_number = is_sane("0123456789Xx", source, src_len); if(error_number == ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Invalid characters in input"); return error_number; } } /* Add leading zeroes */ ustrcpy(local_source, (unsigned char *)""); if(symbol->symbology == BARCODE_ISBNX) { to_upper(local_source); } ean_leading_zeroes(symbol, source, local_source); for(reader = 0; reader <= ustrlen(local_source); reader++) { if(source[reader] == '+') { with_addon = TRUE; } } reader = 0; if(with_addon) { do { if(local_source[reader] == '+') { first_part[writer] = '\0'; latch = TRUE; reader++; writer = 0; } if(latch) { second_part[writer] = local_source[reader]; reader++; writer++; } else { first_part[writer] = local_source[reader]; reader++; writer++; } } while (reader <= ustrlen(local_source)); } else { strcpy((char*)first_part, (char*)local_source); } switch(symbol->symbology) { case BARCODE_EANX: switch(ustrlen(first_part)) { case 2: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; case 5: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; case 7: ean8(symbol, first_part, (char*)dest); break; case 12: ean13(symbol, first_part, (char*)dest); break; default: strcpy(symbol->errtxt, "Invalid length input"); return ERROR_TOO_LONG; break; } break; case BARCODE_EANX_CC: switch(ustrlen(first_part)) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ case 7: set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 67); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 68); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 1, 67); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; ean8(symbol, first_part, (char*)dest); break; case 12:set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 95); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 96); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 2, 95); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; ean13(symbol, first_part, (char*)dest); break; default: strcpy(symbol->errtxt, "Invalid length EAN input"); return ERROR_TOO_LONG; break; } break; case BARCODE_UPCA: if(ustrlen(first_part) == 11) { upca(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "Input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_UPCA_CC: if(ustrlen(first_part) == 11) { set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 95); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 96); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 2, 95); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; upca(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "UPCA input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_UPCE: if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { upce(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "Input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_UPCE_CC: if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 51); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 52); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 2, 51); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; upce(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "UPCE input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_ISBNX: error_number = isbn(symbol, first_part, ustrlen(first_part), (char*)dest); if(error_number > 4) { return error_number; } break; } switch(ustrlen(second_part)) { case 0: break; case 2: add_on(second_part, (char*)dest, 1); uconcat(symbol->text, (unsigned char*)"+"); uconcat(symbol->text, second_part); break; case 5: add_on(second_part, (char*)dest, 1); uconcat(symbol->text, (unsigned char*)"+"); uconcat(symbol->text, second_part); break; default: strcpy(symbol->errtxt, "Invalid length input"); return ERROR_TOO_LONG; break; } expand(symbol, (char*)dest); switch(symbol->symbology) { case BARCODE_EANX_CC: case BARCODE_UPCA_CC: case BARCODE_UPCE_CC: /* shift the symbol to the right one space to allow for separator bars */ for(i = (symbol->width + 1); i >= 1; i--) { if(module_is_set(symbol, symbol->rows - 1, i - 1)) { set_module(symbol, symbol->rows - 1, i); } else { unset_module(symbol, symbol->rows - 1, i); } } unset_module(symbol, symbol->rows - 1, 0); symbol->width += 2; break; } if((symbol->errtxt[0] == 'w') && (error_number == 0)) { error_number = 1; /* flag UPC-E warnings */ } return error_number; }
int ean_128(struct zint_symbol *symbol, unsigned char source[], int length) { /* Handle EAN-128 (Now known as GS1-128) */ int i, j,values[170], bar_characters, read, total_sum; int error_number, indexchaine, indexliste; char set[170], mode, last_set; float glyph_count; char dest[1000]; int separator_row, linkage_flag, c_count; #ifndef _MSC_VER char reduced[length + 1]; #else char* reduced = (char*)_alloca(length + 1); #endif error_number = 0; strcpy(dest, ""); linkage_flag = 0; j = 0; bar_characters = 0; separator_row = 0; memset(values, 0, sizeof(values)); memset(set, ' ', sizeof(set)); if(length > 160) { /* This only blocks rediculously long input - the actual length of the resulting barcode depends on the type of data, so this is trapped later */ strcpy(symbol->errtxt, "Input too long"); return ZINT_ERROR_TOO_LONG; } for(i = 0; i < length; i++) { if(source[i] == '\0') { /* Null characters not allowed! */ strcpy(symbol->errtxt, "NULL character in input data"); return ZINT_ERROR_INVALID_DATA; } } /* if part of a composite symbol make room for the separator pattern */ if(symbol->symbology == BARCODE_EAN128_CC) { separator_row = symbol->rows; symbol->row_height[symbol->rows] = 1; symbol->rows += 1; } if(symbol->input_mode != GS1_MODE) { /* GS1 data has not been checked yet */ error_number = gs1_verify(symbol, source, length, reduced); if(error_number != 0) { return error_number; } } /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ indexliste = 0; indexchaine = 0; mode = parunmodd(reduced[indexchaine]); if(reduced[indexchaine] == '[') { mode = ABORC; } for(i = 0; i < 170; i++) { list[0][i] = 0; } do { list[1][indexliste] = mode; while ((list[1][indexliste] == mode) && (indexchaine < strlen(reduced))) { list[0][indexliste]++; indexchaine++; mode = parunmodd(reduced[indexchaine]); if(reduced[indexchaine] == '[') { mode = ABORC; } } indexliste++; } while (indexchaine < strlen(reduced)); dxsmooth(&indexliste); /* Put set data into set[] */ read = 0; for(i = 0; i < indexliste; i++) { for(j = 0; j < list[0][i]; j++) { switch(list[1][i]) { case SHIFTA: set[read] = 'a'; break; case LATCHA: set[read] = 'A'; break; case SHIFTB: set[read] = 'b'; break; case LATCHB: set[read] = 'B'; break; case LATCHC: set[read] = 'C'; break; } read++; } } /* Watch out for odd-length Mode C blocks */ c_count = 0; for(i = 0; i < read; i++) { if(set[i] == 'C') { if(reduced[i] == '[') { if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } c_count = 0; } else { c_count++; } } else { if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } c_count = 0; } } if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } for(i = 1; i < read - 1; i++) { if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { set[i] = 'B'; } } /* for(i = 0; i < read; i++) { printf("char %c mode %c\n", reduced[i], set[i]); } */ /* Now we can calculate how long the barcode is going to be - and stop it from being too long */ last_set = ' '; glyph_count = 0.0; for(i = 0; i < strlen(reduced); i++) { if((set[i] == 'a') || (set[i] == 'b')) { glyph_count = glyph_count + 1.0; } if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if(set[i] != last_set) { last_set = set[i]; glyph_count = glyph_count + 1.0; } } if((set[i] == 'C') && (reduced[i] != '[')) { glyph_count = glyph_count + 0.5; } else { glyph_count = glyph_count + 1.0; } } if(glyph_count > 80.0) { strcpy(symbol->errtxt, "Input too long"); return ZINT_ERROR_TOO_LONG; } /* So now we know what start character to use - we can get on with it! */ switch(set[0]) { case 'A': /* Start A */ concat(dest, C128Table[103]); values[0] = 103; break; case 'B': /* Start B */ concat(dest, C128Table[104]); values[0] = 104; break; case 'C': /* Start C */ concat(dest, C128Table[105]); values[0] = 105; break; } bar_characters++; concat(dest, C128Table[102]); values[1] = 102; bar_characters++; /* Encode the data */ read = 0; do { if((read != 0) && (set[read] != set[read - 1])) { /* Latch different code set */ switch(set[read]) { case 'A': concat(dest, C128Table[101]); values[bar_characters] = 101; bar_characters++; break; case 'B': concat(dest, C128Table[100]); values[bar_characters] = 100; bar_characters++; break; case 'C': concat(dest, C128Table[99]); values[bar_characters] = 99; bar_characters++; break; } } if((set[read] == 'a') || (set[read] == 'b')) { /* Insert shift character */ concat(dest, C128Table[98]); values[bar_characters] = 98; bar_characters++; } if(reduced[read] != '[') { switch(set[read]) { /* Encode data characters */ case 'A': case 'a': c128_set_a(reduced[read], dest, values, &bar_characters); read++; break; case 'B': case 'b': c128_set_b(reduced[read], dest, values, &bar_characters); read++; break; case 'C': c128_set_c(reduced[read], reduced[read + 1], dest, values, &bar_characters); read += 2; break; } } else { concat(dest, C128Table[102]); values[bar_characters] = 102; bar_characters++; read++; } } while (read < strlen(reduced)); /* "...note that the linkage flag is an extra code set character between the last data character and the Symbol Check Character" (GS1 Specification) */ /* Linkage flags in GS1-128 are determined by ISO/IEC 24723 section 7.4 */ switch(symbol->option_1) { case 1: case 2: /* CC-A or CC-B 2D component */ switch(set[strlen(reduced) - 1]) { case 'A': linkage_flag = 100; break; case 'B': linkage_flag = 99; break; case 'C': linkage_flag = 101; break; } break; case 3: /* CC-C 2D component */ switch(set[strlen(reduced) - 1]) { case 'A': linkage_flag = 99; break; case 'B': linkage_flag = 101; break; case 'C': linkage_flag = 100; break; } break; } if(linkage_flag != 0) { concat(dest, C128Table[linkage_flag]); values[bar_characters] = linkage_flag; bar_characters++; } /*for(i = 0; i < bar_characters; i++) { printf("[%d] ", values[i]); } printf("\n");*/ /* check digit calculation */ total_sum = 0; for(i = 0; i < bar_characters; i++) { if(i > 0) { values[i] *= i; } total_sum += values[i]; } concat(dest, C128Table[total_sum%103]); values[bar_characters] = total_sum % 103; bar_characters++; /* Stop character */ concat(dest, C128Table[106]); values[bar_characters] = 106; bar_characters++; expand(symbol, dest); /* Add the separator pattern for composite symbols */ if(symbol->symbology == BARCODE_EAN128_CC) { for(i = 0; i < symbol->width; i++) { if(!(module_is_set(symbol, separator_row + 1, i))) { set_module(symbol, separator_row, i); } } } for(i = 0; i < length; i++) { if((source[i] != '[') && (source[i] != ']')) { symbol->text[i] = source[i]; } if(source[i] == '[') { symbol->text[i] = '('; } if(source[i] == ']') { symbol->text[i] = ')'; } } return error_number; }
int render_plot(struct zint_symbol *symbol, float width, float height) { struct zint_render *render; struct zint_render_line *line, *last_line = NULL; struct zint_render_string *last_string = NULL; struct zint_render_ring *ring, *last_ring = NULL; struct zint_render_hexagon *hexagon, *last_hexagon = NULL; int i, r, block_width, latch, this_row; float textpos, textwidth, large_bar_height, preset_height, row_height, row_posn = 0.0; // int error_number = 0; int text_offset, text_height, xoffset, yoffset, textdone, main_symbol_width_x, addon_width_x; char addon[6], textpart[10]; int large_bar_count, symbol_lead_in, total_symbol_width_x, total_area_width_x; float addon_text_posn; float default_text_posn; float scaler; const char *locale = NULL; int hide_text = 0; float required_aspect; float symbol_aspect = 1; float x_dimension; int upceanflag = 0; // Allocate memory for the rendered version #ifndef _MSC_VER render = symbol->rendered = malloc(sizeof(struct zint_render)); #else render = symbol->rendered = (struct zint_render *)_alloca(sizeof(struct zint_render)); #endif render->lines = NULL; render->strings = NULL; render->rings = NULL; render->hexagons = NULL; locale = setlocale(LC_ALL, "C"); row_height = 0; textdone = 0; textpos = 0.0; main_symbol_width_x = symbol->width; strcpy(addon, ""); symbol_lead_in = 0; addon_text_posn = 0.0; addon_width_x = 0; /* * Determine if there will be any addon texts and text height */ latch = 0; r = 0; /* Isolate add-on text */ if(is_extendable(symbol->symbology)) { for(i = 0; i < ustrlen(symbol->text); i++) { if (latch == 1) { addon[r] = symbol->text[i]; r++; } if (symbol->text[i] == '+') { latch = 1; } } } addon[r] = '\0'; if((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)) { hide_text = 1; text_height = text_offset = 0.0; } else { text_height = 9.0; text_offset = 2.0; } /* * Calculate the width of the barcode, especially if there are any extra * borders or white space to add. */ while(!(module_is_set(symbol, symbol->rows - 1, symbol_lead_in))) { symbol_lead_in++; } /* Certain symbols need whitespace otherwise characters get chopped off the sides */ if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { switch(ustrlen(symbol->text)) { case 13: /* EAN 13 */ case 16: case 19: if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } main_symbol_width_x = 96 + symbol_lead_in; upceanflag = 13; break; case 2: main_symbol_width_x = 22 + symbol_lead_in; upceanflag = 2; break; case 5: main_symbol_width_x = 49 + symbol_lead_in; upceanflag = 5; break; default: main_symbol_width_x = 68 + symbol_lead_in; upceanflag = 8; } switch(ustrlen(symbol->text)) { case 11: case 16: /* EAN-2 add-on */ addon_width_x = 31; break; case 14: case 19: /* EAN-5 add-on */ addon_width_x = 58; break; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { upceanflag = 12; if(symbol->whitespace_width < 10) { symbol->whitespace_width = 10; main_symbol_width_x = 96 + symbol_lead_in; } switch(ustrlen(symbol->text)) { case 15: /* EAN-2 add-on */ addon_width_x = 31; break; case 18: /* EAN-5 add-on */ addon_width_x = 58; break; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { upceanflag = 6; if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_symbol_width_x = 51 + symbol_lead_in; } switch(ustrlen(symbol->text)) { case 11: /* EAN-2 add-on */ addon_width_x = 31; break; case 14: /* EAN-5 add-on */ addon_width_x = 58; break; } } total_symbol_width_x = main_symbol_width_x + addon_width_x; total_area_width_x = total_symbol_width_x + (2 * (symbol->border_width + symbol->whitespace_width)); xoffset = symbol->border_width + symbol->whitespace_width; yoffset = symbol->border_width; // Determine if height should be overridden large_bar_count = 0; preset_height = 0.0; for(i = 0; i < symbol->rows; i++) { preset_height += symbol->row_height[i]; if(symbol->row_height[i] == 0) { large_bar_count++; } } if (large_bar_count == 0) { required_aspect = width / height; symbol_aspect = (total_symbol_width_x + (2 * xoffset)) / (preset_height + (2 * yoffset) + text_offset + text_height); symbol->height = preset_height; if (required_aspect > symbol_aspect) { /* the area is too wide */ scaler = height / (preset_height + (2 * yoffset) + text_offset + text_height); render->width = symbol_aspect * height; render->height = height; } else { /* the area is too high */ scaler = width / (total_symbol_width_x + (2 * xoffset)); render->width = width; render->height = width / symbol_aspect; } } else { scaler = width / (total_symbol_width_x + (2 * xoffset)); symbol->height = (height / scaler) - ((2 * yoffset) + text_offset + text_height); render->width = width; render->height = height; } large_bar_height = (symbol->height - preset_height) / large_bar_count; if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler; } else { default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler; } x_dimension = render->width / total_area_width_x; x_dimension /= GL_CONST; /* Set minimum size of symbol */ /* Barcode must be at least 2mm high by 2mm across */ if(render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST) { render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST; } if(render->width < (2.0 * GL_CONST)) { render->width = (2.0 * GL_CONST); } if(symbol->symbology == BARCODE_CODABAR) { /* The minimum X-dimension of Codabar is 0.191mm. The minimum bar height is 5mm */ if(x_dimension < 0.191) { render->width = 0.191 * GL_CONST * total_area_width_x; } if(render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST) { render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST; } } if(symbol->symbology == BARCODE_CODE49) { /* The minimum X-dimension of Code 49 is 0.191mm */ if(x_dimension < 0.191) { render->width = 0.191 * GL_CONST * total_area_width_x; render->height = render->width / symbol_aspect; } } if(upceanflag != 0) { /* The X-dimension of UPC/EAN symbols is fixed at 0.330mm */ /* NOTE: This code will need adjustment before it correctly deals with composite symbols */ render->width = 0.330 * GL_CONST * total_area_width_x; /* The height is also fixed */ switch (upceanflag) { case 6: case 12: case 13: /* UPC-A, UPC-E and EAN-13 */ /* Height of bars should be 22.85mm */ render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 22.85) * GL_CONST; break; case 8: /* EAN-8 */ /* Height of bars should be 18.23mm */ render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 18.23) * GL_CONST; break; default: /* EAN-2 and EAN-5 */ /* Height of bars should be 21.10mm */ render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 21.10) * GL_CONST; } } if(symbol->symbology == BARCODE_ONECODE) { /* The size of USPS Intelligent Mail barcode is fixed */ render->width = 0.508 * GL_CONST * total_area_width_x; render->height = 4.064 * GL_CONST; } if((symbol->symbology == BARCODE_POSTNET) || (symbol->symbology == BARCODE_PLANET)) { /* The size of PostNet and PLANET are fized */ render->width = 0.508 * GL_CONST * total_area_width_x; render->height = 2.921 * GL_CONST; } if(((symbol->symbology == BARCODE_AUSPOST) || (symbol->symbology == BARCODE_AUSREPLY)) || ((symbol->symbology == BARCODE_AUSROUTE) || (symbol->symbology == BARCODE_AUSREDIRECT))) { /* Australia Post use the same sizes as USPS */ render->width = 0.508 * GL_CONST * total_area_width_x; render->height = 4.064 * GL_CONST; } if((symbol->symbology == BARCODE_RM4SCC) || (symbol->symbology == BARCODE_KIX)) { /* Royal Mail and KIX Code uses 22 bars per inch */ render->width = 0.577 * GL_CONST * total_area_width_x; render->height = 5.22 * GL_CONST; } if(symbol->symbology == BARCODE_MAXICODE) { /* Maxicode is a fixed size */ scaler = GL_CONST; /* Converts from millimeters to the scale used by glabels */ render->width = 28.16 * scaler; render->height = 26.86 * scaler; /* Central bullseye pattern */ ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 0.85 * scaler, 0.67 * scaler); render_plot_add_ring(symbol, ring, &last_ring); ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 2.20 * scaler, 0.67 * scaler); render_plot_add_ring(symbol, ring, &last_ring); ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 3.54 * scaler, 0.67 * scaler); render_plot_add_ring(symbol, ring, &last_ring); /* Hexagons */ for(r = 0; r < symbol->rows; r++) { for(i = 0; i < symbol->width; i++) { if(module_is_set(symbol, r, i)) { hexagon = render_plot_create_hexagon(((i * 0.88) + (r & 1 ? 1.76 : 1.32)) * scaler, ((r * 0.76) + 0.76) * scaler); render_plot_add_hexagon(symbol, hexagon, &last_hexagon); } } } } else { /* everything else uses rectangles (or squares) */ /* Works from the bottom of the symbol up */ int addon_latch = 0; for(r = 0; r < symbol->rows; r++) { this_row = r; if(symbol->row_height[this_row] == 0) { row_height = large_bar_height; } else { row_height = symbol->row_height[this_row]; } row_posn = 0; for(i = 0; i < r; i++) { if(symbol->row_height[i] == 0) { row_posn += large_bar_height; } else { row_posn += symbol->row_height[i]; } } row_posn += yoffset; i = 0; if(module_is_set(symbol, this_row, 0)) { latch = 1; } else { latch = 0; } do { block_width = 0; do { block_width++; } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); if((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_symbol_width_x)) { addon_text_posn = row_posn * scaler; addon_latch = 1; } if(latch == 1) { /* a bar */ if(addon_latch == 0) { line = render_plot_create_line((i + xoffset) * scaler, (row_posn) * scaler, block_width * scaler, row_height * scaler); } else { line = render_plot_create_line((i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); } latch = 0; render_plot_add_line(symbol, line, &last_line); } else { /* a space */ latch = 1; } i += block_width; } while (i < symbol->width); } } /* That's done the actual data area, everything else is human-friendly */ /* Add the text */ xoffset -= symbol_lead_in; row_posn = (row_posn + large_bar_height) * scaler; if (!hide_text) { if(upceanflag == 8) { /* guard bar extensions and text formatting for EAN-8 */ i = 0; for (line = symbol->rendered->lines; line != NULL; line = line->next) { switch(i) { case 0: case 1: case 10: case 11: case 20: case 21: line->length += (5.0 * scaler); break; } i++; } for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i]; } textpart[4] = '\0'; textpos = 17; textwidth = 4.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i + 4]; } textpart[4] = '\0'; textpos = 50; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 86; textwidth = 2.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; case 5: textpos = xoffset + 100; textwidth = 5.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; } } if(upceanflag == 13) { /* guard bar extensions and text formatting for EAN-13 */ i = 0; for (line = symbol->rendered->lines; line != NULL; line = line->next) { switch(i) { case 0: case 1: case 14: case 15: case 28: case 29: line->length += (5.0 * scaler); break; } i++; } textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = -5; // 7 textwidth = 8.5; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; textpos = 25; textwidth = 6.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 7]; } textpart[6] = '\0'; textpos = 72; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 114; textwidth = 2.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; case 5: textpos = xoffset + 128; textwidth = 5.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; } } if (upceanflag == 12) { /* guard bar extensions and text formatting for UPCA */ i = 0; for (line = symbol->rendered->lines; line != NULL; line = line->next) { switch(i) { case 0: case 1: case 2: case 3: case 14: case 15: case 26: case 27: case 28: case 29: line->length += (5.0 * scaler); break; } i++; } textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = -5; textwidth = 6.2; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 1]; } textpart[5] = '\0'; textpos = 27; textwidth = 5.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 6]; } textpos = 68; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); textpart[0] = symbol->text[11]; textpart[1] = '\0'; textpos = 100; textwidth = 6.2; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 116; textwidth = 2.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; case 5: textpos = xoffset + 130; textwidth = 5.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; } } if (upceanflag == 6) { /* guard bar extensions and text formatting for UPCE */ i = 0; for (line = symbol->rendered->lines; line != NULL; line = line->next) { switch(i) { case 0: case 1: case 14: case 15: case 16: line->length += (5.0 * scaler); break; } i++; } textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = -5; textwidth = 6.2; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; textpos = 24; textwidth = 6.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); textpart[0] = symbol->text[7]; textpart[1] = '\0'; textpos = 55; textwidth = 6.2; render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 70; textwidth = 2.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; case 5: textpos = xoffset + 84; textwidth = 5.0 * 8.5; render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); break; } } /* Put normal human readable text at the bottom (and centered) */ if (textdone == 0) { // caculate start xoffset to center text render_plot_add_string(symbol, symbol->text, ((symbol->width / 2.0) + xoffset) * scaler, default_text_posn, 9.0 * scaler, 0.0, &last_string); } } switch(symbol->symbology) { case BARCODE_MAXICODE: /* Do nothing! */ break; default: if((symbol->output_options & BARCODE_BIND) != 0) { if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { /* row binding */ for(r = 1; r < symbol->rows; r++) { line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); render_plot_add_line(symbol, line, &last_line); } } } if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); render_plot_add_line(symbol, line, &last_line); line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); render_plot_add_line(symbol, line, &last_line); } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); render_plot_add_line(symbol, line, &last_line); line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); render_plot_add_line(symbol, line, &last_line); } break; } if (locale) setlocale(LC_ALL, locale); return 1; }
int svg_plot(struct zint_symbol *symbol) { int i, block_width, latch, r, this_row; float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0; FILE *fsvg; int error_number = 0; int textoffset, xoffset, yoffset, textdone, main_width; char textpart[10], addon[6]; int large_bar_count, comp_offset; float addon_text_posn; float scaler = symbol->scale; float default_text_posn; int plot_text = 1; const char *locale = NULL; row_height=0; textdone = 0; main_width = symbol->width; strcpy(addon, ""); comp_offset = 0; addon_text_posn = 0.0; if((symbol->output_options & BARCODE_STDOUT) != 0) { fsvg = stdout; } else { fsvg = fopen(symbol->outfile, "w"); } if(fsvg == NULL) { strcpy(symbol->errtxt, "Could not open output file"); return ZINT_ERROR_FILE_ACCESS; } /* sort out colour options */ to_upper((unsigned char*)symbol->fgcolour); to_upper((unsigned char*)symbol->bgcolour); if(strlen(symbol->fgcolour) != 6) { strcpy(symbol->errtxt, "Malformed foreground colour target"); return ZINT_ERROR_INVALID_OPTION; } if(strlen(symbol->bgcolour) != 6) { strcpy(symbol->errtxt, "Malformed background colour target"); return ZINT_ERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed foreground colour target"); return ZINT_ERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed background colour target"); return ZINT_ERROR_INVALID_OPTION; } locale = setlocale(LC_ALL, "C"); if (symbol->height == 0) { symbol->height = 50; } large_bar_count = 0; preset_height = 0.0; for(i = 0; i < symbol->rows; i++) { preset_height += symbol->row_height[i]; if(symbol->row_height[i] == 0) { large_bar_count++; } } large_bar_height = (symbol->height - preset_height) / large_bar_count; if (large_bar_count == 0) { symbol->height = preset_height; } while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { comp_offset++; } /* Certain symbols need whitespace otherwise characters get chopped off the sides */ if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { switch(ustrlen(symbol->text)) { case 13: /* EAN 13 */ case 16: case 19: if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } main_width = 96 + comp_offset; break; default: main_width = 68 + comp_offset; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_width = 96 + comp_offset; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_width = 51 + comp_offset; } } latch = 0; r = 0; /* Isolate add-on text */ if(is_extendable(symbol->symbology)) { for(i = 0; i < ustrlen(symbol->text); i++) { if (latch == 1) { addon[r] = symbol->text[i]; r++; } if (symbol->text[i] == '+') { latch = 1; } } } addon[r] = '\0'; if((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) { plot_text = 0; } if(plot_text) { textoffset = 9; } else { textoffset = 0; } xoffset = symbol->border_width + symbol->whitespace_width; yoffset = symbol->border_width; /* Start writing the header */ fprintf(fsvg, "<?xml version=\"1.0\" standalone=\"no\"?>\n"); fprintf(fsvg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"); fprintf(fsvg, " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); if(symbol->symbology != BARCODE_MAXICODE) { fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); } else { fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler)); } fprintf(fsvg, " xmlns=\"http://www.w3.org/2000/svg\">\n"); if(ustrlen(symbol->text) != 0) { fprintf(fsvg, " <desc>%s\n", symbol->text); } else { fprintf(fsvg, " <desc>Zint Generated Symbol\n"); } fprintf(fsvg, " </desc>\n"); fprintf(fsvg, "\n <g id=\"barcode\" fill=\"#%s\">\n", symbol->fgcolour); if(symbol->symbology != BARCODE_MAXICODE) { fprintf(fsvg, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler), symbol->bgcolour); } else { fprintf(fsvg, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler), symbol->bgcolour); } if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { default_text_posn = (symbol->height + textoffset + symbol->border_width + symbol->border_width) * scaler; } else { default_text_posn = (symbol->height + textoffset + symbol->border_width) * scaler; } if(symbol->symbology == BARCODE_MAXICODE) { /* Maxicode uses hexagons */ float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; textoffset = 0.0; if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); } fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, symbol->fgcolour); fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, symbol->bgcolour); fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, symbol->fgcolour); fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, symbol->bgcolour); fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, symbol->fgcolour); fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, symbol->bgcolour); for(r = 0; r < symbol->rows; r++) { for(i = 0; i < symbol->width; i++) { if(module_is_set(symbol, r, i)) { /* Dump a hexagon */ my = r * 2.135 + 1.43; ay = my + 1.0 + yoffset; by = my + 0.5 + yoffset; cy = my - 0.5 + yoffset; dy = my - 1.0 + yoffset; ey = my - 0.5 + yoffset; fy = my + 0.5 + yoffset; if(r & 1) { mx = (2.46 * i) + 1.23 + 1.23; } else { mx = (2.46 * i) + 1.23; } ax = mx + xoffset; bx = mx + 0.86 + xoffset; cx = mx + 0.86 + xoffset; dx = mx + xoffset; ex = mx - 0.86 + xoffset; fx = mx - 0.86 + xoffset; fprintf(fsvg, " <path d=\"M %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f Z\" />\n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); } } } } if(symbol->symbology != BARCODE_MAXICODE) { /* everything else uses rectangles (or squares) */ /* Works from the bottom of the symbol up */ int addon_latch = 0; for(r = 0; r < symbol->rows; r++) { this_row = r; if(symbol->row_height[this_row] == 0) { row_height = large_bar_height; } else { row_height = symbol->row_height[this_row]; } row_posn = 0; for(i = 0; i < r; i++) { if(symbol->row_height[i] == 0) { row_posn += large_bar_height; } else { row_posn += symbol->row_height[i]; } } row_posn += yoffset; i = 0; if(module_is_set(symbol, this_row, 0)) { latch = 1; } else { latch = 0; } do { block_width = 0; do { block_width++; } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); if((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { addon_text_posn = (row_posn + 8.0) * scaler; addon_latch = 1; } if(latch == 1) { /* a bar */ if(addon_latch == 0) { fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler); } else { fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); } latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < symbol->width); } } /* That's done the actual data area, everything else is human-friendly */ xoffset += comp_offset; row_posn = (row_posn + large_bar_height) * scaler; if(plot_text) { if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { /* guard bar extensions and text formatting for EAN8 and EAN13 */ switch(ustrlen(symbol->text)) { case 8: /* EAN-8 */ case 11: case 14: fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i]; } textpart[4] = '\0'; textpos = 17; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i + 4]; } textpart[4] = '\0'; textpos = 50; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 86; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; case 5: textpos = xoffset + 100; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; } break; case 13: /* EAN 13 */ case 16: case 19: fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = -7; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; textpos = 24; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 7]; } textpart[6] = '\0'; textpos = 71; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 114; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; case 5: textpos = xoffset + 128; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; } break; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { /* guard bar extensions and text formatting for UPCA */ latch = 1; i = 0 + comp_offset; do { block_width = 0; do { block_width++; } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); if(latch == 1) { /* a bar */ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < 11 + comp_offset); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); latch = 1; i = 85 + comp_offset; do { block_width = 0; do { block_width++; } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); if(latch == 1) { /* a bar */ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < 96 + comp_offset); textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = -5; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 1]; } textpart[5] = '\0'; textpos = 27; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 6]; } textpart[6] = '\0'; textpos = 68; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); textpart[0] = symbol->text[11]; textpart[1] = '\0'; textpos = 100; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 116; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; case 5: textpos = xoffset + 130; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { /* guard bar extensions and text formatting for UPCE */ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); textpart[0] = symbol->text[0]; textpart[1] = '\0'; textpos = -5; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; textpos = 24; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); textpart[0] = symbol->text[7]; textpart[1] = '\0'; textpos = 55; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", textpart); fprintf(fsvg, " </text>\n"); textdone = 1; switch(strlen(addon)) { case 2: textpos = xoffset + 70; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; case 5: textpos = xoffset + 84; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", addon); fprintf(fsvg, " </text>\n"); break; } } } /* if (plot_text) */ xoffset -= comp_offset; switch(symbol->symbology) { case BARCODE_MAXICODE: /* Do nothing! (It's already been done) */ break; default: if((symbol->output_options & BARCODE_BIND) != 0) { if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { /* row binding */ for(r = 1; r < symbol->rows; r++) { fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); } } } if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); } break; } /* Put the human readable text at the bottom */ if(plot_text && (textdone == 0)) { textpos = symbol->width / 2.0; fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour); fprintf(fsvg, " %s\n", symbol->text); fprintf(fsvg, " </text>\n"); } fprintf(fsvg, " </g>\n"); fprintf(fsvg, "</svg>\n"); if(symbol->output_options & BARCODE_STDOUT) { fflush(fsvg); } else { fclose(fsvg); } if (locale) setlocale(LC_ALL, locale); return error_number; }
int ps_plot(struct zint_symbol *symbol) { int i, block_width, latch, r, this_row; float textpos, large_bar_height, preset_height, row_height, row_posn; FILE *feps; int fgred, fggrn, fgblu, bgred, bggrn, bgblu; float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; int error_number = 0; int textoffset, xoffset, yoffset, textdone, main_width; char textpart[10], addon[6]; int large_bar_count, comp_offset; float addon_text_posn; float scaler = symbol->scale; float default_text_posn; int plot_text = 1; const char *locale = NULL; row_height=0; textdone = 0; main_width = symbol->width; strcpy(addon, ""); comp_offset = 0; addon_text_posn = 0.0; if((symbol->output_options & BARCODE_STDOUT) != 0) { feps = stdout; } else { feps = fopen(symbol->outfile, "w"); } if(feps == NULL) { strcpy(symbol->errtxt, "Could not open output file"); return ZERROR_FILE_ACCESS; } /* sort out colour options */ to_upper((unsigned char*)symbol->fgcolour); to_upper((unsigned char*)symbol->bgcolour); if(strlen(symbol->fgcolour) != 6) { strcpy(symbol->errtxt, "Malformed foreground colour target"); return ZERROR_INVALID_OPTION; } if(strlen(symbol->bgcolour) != 6) { strcpy(symbol->errtxt, "Malformed background colour target"); return ZERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); if (error_number == ZERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed foreground colour target"); return ZERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); if (error_number == ZERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed background colour target"); return ZERROR_INVALID_OPTION; } locale = setlocale(LC_ALL, "C"); fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); red_ink = fgred / 256.0; green_ink = fggrn / 256.0; blue_ink = fgblu / 256.0; red_paper = bgred / 256.0; green_paper = bggrn / 256.0; blue_paper = bgblu / 256.0; if (symbol->height == 0) { symbol->height = 50; } large_bar_count = 0; preset_height = 0.0; for(i = 0; i < symbol->rows; i++) { preset_height += symbol->row_height[i]; if(symbol->row_height[i] == 0) { large_bar_count++; } } large_bar_height = (symbol->height - preset_height) / large_bar_count; if (large_bar_count == 0) { symbol->height = preset_height; } while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { comp_offset++; } /* Certain symbols need whitespace otherwise characters get chopped off the sides */ if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { switch(ustrlen(symbol->text)) { case 13: /* EAN 13 */ case 16: case 19: if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } main_width = 96 + comp_offset; break; default: main_width = 68 + comp_offset; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_width = 96 + comp_offset; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { if(symbol->whitespace_width == 0) { symbol->whitespace_width = 10; main_width = 51 + comp_offset; } } latch = 0; r = 0; /* Isolate add-on text */ if(is_extendable(symbol->symbology)) { for(i = 0; i < ustrlen(symbol->text); i++) { if (latch == 1) { addon[r] = symbol->text[i]; r++; } if (symbol->text[i] == '+') { latch = 1; } } } addon[r] = '\0'; if((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) { plot_text = 0; } if(plot_text) { textoffset = 9; } else { textoffset = 0; } xoffset = symbol->border_width + symbol->whitespace_width; yoffset = symbol->border_width; /* Start writing the header */ fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n"); fprintf(feps, "%%%%Creator: Zint %s\n", ZINT_VERSION); if(ustrlen(symbol->text) != 0) { fprintf(feps, "%%%%Title: %s\n",symbol->text); } else { fprintf(feps, "%%%%Title: Zint Generated Symbol\n"); } fprintf(feps, "%%%%Pages: 0\n"); if(symbol->symbology != BARCODE_MAXICODE) { fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); } else { fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler)); } fprintf(feps, "%%%%EndComments\n"); /* Definitions */ fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n"); fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n"); fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n"); fprintf(feps, "/TB { 2 copy } bind def\n"); fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n"); fprintf(feps, "/TE { pop pop } bind def\n"); fprintf(feps, "newpath\n"); /* Now the actual representation */ fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper); fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", (symbol->height + textoffset + yoffset + yoffset) * scaler, (symbol->width + xoffset + xoffset) * scaler); if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { default_text_posn = 0.5 * scaler; } else { default_text_posn = (symbol->border_width + 0.5) * scaler; } if(symbol->symbology == BARCODE_MAXICODE) { /* Maxicode uses hexagons */ float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; textoffset = 0.0; if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + 72.0 + symbol->border_width) * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, (74.0 + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); } fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, (44.73 + xoffset) * scaler, (35.60 + yoffset) * scaler); fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, (40.98 + xoffset) * scaler, (35.60 + yoffset) * scaler); fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, (37.19 + xoffset) * scaler, (35.60 + yoffset) * scaler); for(r = 0; r < symbol->rows; r++) { for(i = 0; i < symbol->width; i++) { if(module_is_set(symbol, r, i)) { /* Dump a hexagon */ my = ((symbol->rows - r - 1)) * 2.135 + 1.43; ay = my + 1.0 + yoffset; by = my + 0.5 + yoffset; cy = my - 0.5 + yoffset; dy = my - 1.0 + yoffset; ey = my - 0.5 + yoffset; fy = my + 0.5 + yoffset; mx = 2.46 * i + 1.23 + (r & 1 ? 1.23 : 0); ax = mx + xoffset; bx = mx + 0.86 + xoffset; cx = mx + 0.86 + xoffset; dx = mx + xoffset; ex = mx - 0.86 + xoffset; fx = mx - 0.86 + xoffset; fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); } } } } if(symbol->symbology != BARCODE_MAXICODE) { /* everything else uses rectangles (or squares) */ /* Works from the bottom of the symbol up */ int addon_latch = 0; for(r = 0; r < symbol->rows; r++) { this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ if(symbol->row_height[this_row] == 0) { row_height = large_bar_height; } else { row_height = symbol->row_height[this_row]; } row_posn = 0; for(i = 0; i < r; i++) { if(symbol->row_height[symbol->rows - i - 1] == 0) { row_posn += large_bar_height; } else { row_posn += symbol->row_height[symbol->rows - i - 1]; } } row_posn += (textoffset + yoffset); fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f ", row_height * scaler, row_posn * scaler); i = 0; if(module_is_set(symbol, this_row, 0)) { latch = 1; } else { latch = 0; } do { block_width = 0; do { block_width++; } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); if((addon_latch == 0) && (r == 0) && (i > main_width)) { fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f ", (row_height - 5.0) * scaler, (row_posn - 5.0) * scaler); addon_text_posn = row_posn + row_height - 8.0; addon_latch = 1; } if(latch == 1) { /* a bar */ fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset) * scaler, block_width * scaler); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < symbol->width); } } /* That's done the actual data area, everything else is human-friendly */ xoffset += comp_offset; if (plot_text) { if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { /* guard bar extensions and text formatting for EAN8 and EAN13 */ switch(ustrlen(symbol->text)) { case 8: /* EAN-8 */ case 11: case 14: fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (32 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (34 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (64 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (66 + xoffset) * scaler, 1 * scaler); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i]; } textpart[4] = '\0'; fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 17; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); for(i = 0; i < 4; i++) { textpart[i] = symbol->text[i + 4]; } textpart[4] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 50; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); textdone = 1; switch(strlen(addon)) { case 2: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 86; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; case 5: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 100; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; } break; case 13: /* EAN 13 */ case 16: case 19: fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (92 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (94 + xoffset) * scaler, 1 * scaler); textpart[0] = symbol->text[0]; textpart[1] = '\0'; fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = -7; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 24; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 7]; } textpart[6] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 71; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); textdone = 1; switch(strlen(addon)) { case 2: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 114; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; case 5: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 128; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; } break; } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { /* guard bar extensions and text formatting for UPCA */ fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); latch = 1; i = 0 + comp_offset; do { block_width = 0; do { block_width++; } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); if(latch == 1) { /* a bar */ fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < 11 + comp_offset); fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); latch = 1; i = 85 + comp_offset; do { block_width = 0; do { block_width++; } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); if(latch == 1) { /* a bar */ fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < 96 + comp_offset); textpart[0] = symbol->text[0]; textpart[1] = '\0'; fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); textpos = -5; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 1]; } textpart[5] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 27; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); for(i = 0; i < 5; i++) { textpart[i] = symbol->text[i + 6]; } textpart[6] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 68; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); textpart[0] = symbol->text[11]; textpart[1] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); textpos = 100; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); textdone = 1; switch(strlen(addon)) { case 2: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 116; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; case 5: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 130; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { /* guard bar extensions and text formatting for UPCE */ fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); fprintf(feps, "TB %.2f %.2f TR\n", (50 + xoffset) * scaler, 1 * scaler); textpart[0] = symbol->text[0]; textpart[1] = '\0'; fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); textpos = -5; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); for(i = 0; i < 6; i++) { textpart[i] = symbol->text[i + 1]; } textpart[6] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = 24; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); textpart[0] = symbol->text[7]; textpart[1] = '\0'; fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); textpos = 55; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", textpart); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", textpart); fprintf(feps, "setmatrix\n"); textdone = 1; switch(strlen(addon)) { case 2: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 70; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; case 5: fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); textpos = xoffset + 84; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); fprintf(feps, " (%s) stringwidth\n", addon); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", addon); fprintf(feps, "setmatrix\n"); break; } } } /* if (plot_text) */ xoffset -= comp_offset; switch(symbol->symbology) { case BARCODE_MAXICODE: /* Do nothing! (It's already been done) */ break; default: if((symbol->output_options & BARCODE_BIND) != 0) { if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { /* row binding */ fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); for(r = 1; r < symbol->rows; r++) { fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, xoffset * scaler, symbol->width * scaler); } } } if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); } if((symbol->output_options & BARCODE_BOX) != 0) { /* side bars */ fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); } break; } /* Put the human readable text at the bottom */ if(plot_text && (textdone == 0)) { fprintf(feps, "TE\n"); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/Helvetica findfont\n"); fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); textpos = symbol->width / 2.0; fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); fprintf(feps, " (%s) stringwidth\n", symbol->text); fprintf(feps, "pop\n"); fprintf(feps, "-2 div 0 rmoveto\n"); fprintf(feps, " (%s) show\n", symbol->text); fprintf(feps, "setmatrix\n"); } fprintf(feps, "\nshowpage\n"); if(symbol->output_options & BARCODE_STDOUT) { fflush(feps); } else { fclose(feps); } if (locale) setlocale(LC_ALL, locale); return error_number; }