/* emf.c - Support for Microsoft Enhanced Metafile Format libzint - the open source barcode library Copyright (C) 2016 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Developed according to [MS-EMF] - v20160714, Released July 14, 2016 * and [MS-WMF] - v20160714, Released July 14, 2016 */ #include #include #include #include #include "common.h" #include "emf.h" #define SSET "0123456789ABCDEF" int count_rectangles(struct zint_symbol *symbol) { int rectangles = 0; int this_row; int latch, i; if ((symbol->symbology != BARCODE_MAXICODE) && ((symbol->output_options & BARCODE_DOTTY_MODE) == 0)) { for(this_row = 0; this_row < symbol->rows; this_row++) { latch = 0; for(i = 0; i < symbol->width; i++) { if ((module_is_set(symbol, this_row, i)) && (latch == 0)) { latch = 1; rectangles++; } if ((!(module_is_set(symbol, this_row, i))) && (latch == 1)) { latch = 0; } } } } return rectangles; } int count_circles(struct zint_symbol *symbol) { int circles = 0; int this_row; int i; if ((symbol->symbology != BARCODE_MAXICODE) && ((symbol->output_options & BARCODE_DOTTY_MODE) != 0)) { for(this_row = 0; this_row < symbol->rows; this_row++) { for(i = 0; i < symbol->width; i++) { if (module_is_set(symbol, this_row, i)) { circles++; } } } } return circles; } int count_hexagons(struct zint_symbol *symbol) { int hexagons = 0; int this_row; int i; if (symbol->symbology == BARCODE_MAXICODE) { for(this_row = 0; this_row < symbol->rows; this_row++) { for(i = 0; i < symbol->width; i++) { if (module_is_set(symbol, this_row, i)) { hexagons++; } } } } return hexagons; } void utfle_copy(unsigned char *output, unsigned char *input, int length) { int i; int o; /* Convert UTF-8 to UTF-16LE - only needs to handle characters <= U+00FF */ i = 0; o = 0; do { if(input[i] <= 0x7f) { /* 1 byte mode (7-bit ASCII) */ output[o] = input[i]; output[o + 1] = 0x00; o += 2; i++; } else { /* 2 byte mode */ output[o] = ((input[i] & 0x1f) << 6) + (input[i + 1] & 0x3f); output[o + 1] = 0x00; o += 2; i += 2; } } while (i < length); } int bump_up(int input) { /* Strings length must be a multiple of 4 bytes */ if ((input % 2) == 1) { input++; } return input; } int emf_plot(struct zint_symbol *symbol) { int i, block_width, latch, this_row; float large_bar_height, preset_height, row_height, row_posn; FILE *emf_file; int fgred, fggrn, fgblu, bgred, bggrn, bgblu; int error_number = 0; int textoffset, xoffset, yoffset, textdone; int large_bar_count, comp_offset; float scaler = symbol->scale * 10; int rectangle_count, this_rectangle; int circle_count, this_circle; int hexagon_count, this_hexagon; int bytecount, recordcount; int upcean = 0; unsigned char regw[7]; unsigned char regx[7]; unsigned char regy[7]; unsigned char regz[7]; unsigned char output_buffer[12]; uint32_t dx; emr_header_t emr_header; emr_eof_t emr_eof; emr_createbrushindirect_t emr_createbrushindirect_fg; emr_createbrushindirect_t emr_createbrushindirect_bg; emr_selectobject_t emr_selectobject_fgbrush; emr_selectobject_t emr_selectobject_bgbrush; emr_createpen_t emr_createpen; emr_selectobject_t emr_selectobject_pen; emr_rectangle_t background; emr_ellipse_t bullseye[6]; emr_extcreatefontindirectw_t emr_extcreatefontindirectw; emr_selectobject_t emr_selectobject_font; emr_exttextoutw_t emr_exttextoutw[6]; emr_extcreatefontindirectw_t emr_extcreatefontindirectw_big; emr_selectobject_t emr_selectobject_font_big; box_t box; #ifndef _MSC_VER unsigned char local_text[bump_up(ustrlen(symbol->text) + 1)]; unsigned char string_buffer[2 * bump_up(ustrlen(symbol->text) + 1)]; #else unsigned char* local_text; unsigned char* string_buffer; emr_rectangle_t *rectangle, *row_binding; emr_ellipse_t* circle; emr_polygon_t* hexagon; local_text = (unsigned char*) _alloca(bump_up(ustrlen(symbol->text) + 1) * sizeof (unsigned char)); string_buffer = (unsigned char*) _alloca(2 * bump_up(ustrlen(symbol->text) + 1) * sizeof (unsigned char)); #endif row_height = 0; textdone = 0; comp_offset = 0; this_rectangle = 0; this_circle = 0; this_hexagon = 0; dx = 0; latch = 0; for(i = 0; i < 6; i++) { regw[i] = '\0'; regx[i] = '\0'; regy[i] = '\0'; regz[i] = '\0'; } if (symbol->show_hrt != 0) { /* Copy text from symbol */ ustrcpy(local_text, symbol->text); } else { /* No text needed */ switch (symbol->symbology) { case BARCODE_EANX: case BARCODE_EANX_CC: case BARCODE_ISBNX: case BARCODE_UPCA: case BARCODE_UPCE: case BARCODE_UPCA_CC: case BARCODE_UPCE_CC: /* For these symbols use dummy text to ensure formatting is done * properly even if no text is required */ for (i = 0; i < ustrlen(symbol->text); i++) { if (symbol->text[i] == '+') { local_text[i] = '+'; } else { local_text[i] = ' '; } local_text[ustrlen(symbol->text)] = '\0'; } break; default: /* For everything else, just remove the text */ local_text[0] = '\0'; break; } } /* 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 (F41)"); return ZINT_ERROR_INVALID_OPTION; } if (strlen(symbol->bgcolour) != 6) { strcpy(symbol->errtxt, "Malformed background colour target (F42)"); return ZINT_ERROR_INVALID_OPTION; } 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]); 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(local_text)) { case 13: /* EAN 13 */ case 16: case 19: if (symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } break; } upcean = 1; } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { if (symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } upcean = 1; } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { if (symbol->whitespace_width == 0) { symbol->whitespace_width = 10; } upcean = 1; } if (ustrlen(local_text) != 0) { textoffset = 9; } else { textoffset = 0; } xoffset = symbol->border_width + symbol->whitespace_width; yoffset = symbol->border_width; rectangle_count = count_rectangles(symbol); circle_count = count_circles(symbol); hexagon_count = count_hexagons(symbol); #ifndef _MSC_VER emr_rectangle_t rectangle[rectangle_count]; emr_rectangle_t row_binding[symbol->rows - 1]; emr_ellipse_t circle[circle_count]; emr_polygon_t hexagon[hexagon_count]; #else rectangle = (emr_rectangle_t*) _alloca(rectangle_count*sizeof(emr_rectangle_t)); row_binding = (emr_rectangle_t*) _alloca((symbol->rows - 1)*sizeof(emr_rectangle_t)); circle = (emr_ellipse_t*) _alloca(circle_count*sizeof(emr_ellipse_t)); hexagon = (emr_polygon_t*) _alloca(hexagon_count*sizeof(emr_polygon_t)); #endif /* Header */ emr_header.type = 0x00000001; // EMR_HEADER emr_header.size = 88; // Assuming no additional data in header emr_header.emf_header.bounds.left = 0; if (symbol->symbology != BARCODE_MAXICODE) { emr_header.emf_header.bounds.right = ceil((symbol->width + xoffset + xoffset) * scaler); emr_header.emf_header.bounds.bottom = ceil((symbol->height + textoffset + yoffset + yoffset) * scaler); } else { emr_header.emf_header.bounds.right = ceil((74.0F + xoffset + xoffset) * scaler); emr_header.emf_header.bounds.bottom = ceil((72.0F + yoffset + yoffset) * scaler); } emr_header.emf_header.bounds.top = 0; emr_header.emf_header.frame.left = 0; emr_header.emf_header.frame.right = emr_header.emf_header.bounds.right * 30; emr_header.emf_header.frame.top = 0; emr_header.emf_header.frame.bottom = emr_header.emf_header.bounds.bottom * 30; emr_header.emf_header.record_signature = 0x464d4520; // ENHMETA_SIGNATURE emr_header.emf_header.version = 0x00010000;; emr_header.emf_header.handles = 6; // Number of graphics objects emr_header.emf_header.reserved = 0x0000; emr_header.emf_header.n_description = 0; emr_header.emf_header.off_description = 0; emr_header.emf_header.n_pal_entries = 0; emr_header.emf_header.device.cx = 1000; emr_header.emf_header.device.cy = 1000; emr_header.emf_header.millimeters.cx = 300; emr_header.emf_header.millimeters.cy = 300; bytecount = 88; recordcount = 1; /* Create Brushes */ emr_createbrushindirect_fg.type = 0x00000027; // EMR_CREATEBRUSHINDIRECT emr_createbrushindirect_fg.size = 24; emr_createbrushindirect_fg.ih_brush = 1; emr_createbrushindirect_fg.log_brush.brush_style = 0x0000; // BS_SOLID emr_createbrushindirect_fg.log_brush.color.red = fgred; emr_createbrushindirect_fg.log_brush.color.green = fggrn; emr_createbrushindirect_fg.log_brush.color.blue = fgblu; emr_createbrushindirect_fg.log_brush.color.reserved = 0; emr_createbrushindirect_fg.log_brush.brush_hatch = 0; // ignored bytecount += 24; recordcount++; emr_createbrushindirect_bg.type = 0x00000027; // EMR_CREATEBRUSHINDIRECT emr_createbrushindirect_bg.size = 24; emr_createbrushindirect_bg.ih_brush = 2; emr_createbrushindirect_bg.log_brush.brush_style = 0x0000; // BS_SOLID emr_createbrushindirect_bg.log_brush.color.red = bgred; emr_createbrushindirect_bg.log_brush.color.green = bggrn; emr_createbrushindirect_bg.log_brush.color.blue = bgblu; emr_createbrushindirect_bg.log_brush.color.reserved = 0; emr_createbrushindirect_bg.log_brush.brush_hatch = 0; // ignored bytecount += 24; recordcount++; emr_selectobject_fgbrush.type = 0x00000025; // EMR_SELECTOBJECT emr_selectobject_fgbrush.size = 12; emr_selectobject_fgbrush.ih_object = 1; bytecount += 12; recordcount++; emr_selectobject_bgbrush.type = 0x00000025; // EMR_SELECTOBJECT emr_selectobject_bgbrush.size = 12; emr_selectobject_bgbrush.ih_object = 2; bytecount += 12; recordcount++; /* Create Pens */ emr_createpen.type = 0x00000026; // EMR_CREATEPEN emr_createpen.size = 28; emr_createpen.ih_pen = 3; emr_createpen.log_pen.pen_style = 0x00000005; // PS_NULL emr_createpen.log_pen.width.x = 1; emr_createpen.log_pen.width.y = 0; // ignored emr_createpen.log_pen.color_ref.red = 0; emr_createpen.log_pen.color_ref.green = 0; emr_createpen.log_pen.color_ref.blue = 0; emr_createpen.log_pen.color_ref.reserved = 0; bytecount += 28; recordcount++; emr_selectobject_pen.type = 0x00000025; // EMR_SELECTOBJECT emr_selectobject_pen.size = 12; emr_selectobject_pen.ih_object = 3; bytecount += 12; recordcount++; /* Create font records */ if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { emr_extcreatefontindirectw.type = 0x00000052; // EMR_EXTCREATEFONTINDIRECTW emr_extcreatefontindirectw.size = 104; emr_extcreatefontindirectw.ih_fonts = 4; emr_extcreatefontindirectw.elw.height = (8 * scaler); emr_extcreatefontindirectw.elw.width = 0; // automatic emr_extcreatefontindirectw.elw.escapement = 0; emr_extcreatefontindirectw.elw.orientation = 0; emr_extcreatefontindirectw.elw.weight = 400; emr_extcreatefontindirectw.elw.italic = 0x00; emr_extcreatefontindirectw.elw.underline = 0x00; emr_extcreatefontindirectw.elw.strike_out = 0x00; emr_extcreatefontindirectw.elw.char_set = 0x01; emr_extcreatefontindirectw.elw.out_precision = 0x00; // OUT_DEFAULT_PRECIS emr_extcreatefontindirectw.elw.clip_precision = 0x00; // CLIP_DEFAULT_PRECIS emr_extcreatefontindirectw.elw.quality = 0x00; emr_extcreatefontindirectw.elw.pitch_and_family = 0x00; for(i = 0; i < 64; i++) { emr_extcreatefontindirectw.elw.facename[i] = '\0'; } utfle_copy(emr_extcreatefontindirectw.elw.facename, (unsigned char*) "sans-serif", 10); emr_selectobject_font.type = 0x00000025; // EMR_SELECTOBJECT emr_selectobject_font.size = 12; emr_selectobject_font.ih_object = 4; if (!((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX))) { bytecount += 104; recordcount++; bytecount += 12; recordcount++; } if (upcean) { emr_extcreatefontindirectw_big.type = 0x00000052; // EMR_EXTCREATEFONTINDIRECTW emr_extcreatefontindirectw_big.size = 104; if (!((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX))) { emr_extcreatefontindirectw_big.ih_fonts = 4; } else { emr_extcreatefontindirectw_big.ih_fonts = 5; } emr_extcreatefontindirectw_big.elw.height = (11 * scaler); emr_extcreatefontindirectw_big.elw.width = 0; // automatic emr_extcreatefontindirectw_big.elw.escapement = 0; emr_extcreatefontindirectw_big.elw.orientation = 0; emr_extcreatefontindirectw_big.elw.weight = 400; emr_extcreatefontindirectw_big.elw.italic = 0x00; emr_extcreatefontindirectw_big.elw.underline = 0x00; emr_extcreatefontindirectw_big.elw.strike_out = 0x00; emr_extcreatefontindirectw_big.elw.char_set = 0x01; emr_extcreatefontindirectw_big.elw.out_precision = 0x00; // OUT_DEFAULT_PRECIS emr_extcreatefontindirectw_big.elw.clip_precision = 0x00; // CLIP_DEFAULT_PRECIS emr_extcreatefontindirectw_big.elw.quality = 0x00; emr_extcreatefontindirectw_big.elw.pitch_and_family = 0x00; for(i = 0; i < 64; i++) { emr_extcreatefontindirectw_big.elw.facename[i] = '\0'; } utfle_copy(emr_extcreatefontindirectw_big.elw.facename, (unsigned char*) "sans-serif", 10); bytecount += 104; recordcount++; emr_selectobject_font_big.type = 0x00000025; // EMR_SELECTOBJECT emr_selectobject_font_big.size = 12; emr_selectobject_font_big.ih_object = 5; bytecount += 12; recordcount++; } } /* Text */ if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) { latch = ustrlen(local_text); for(i = 0; i < ustrlen(local_text); i++) { if (local_text[i] == '+') { latch = i; } } if (latch > 8) { // EAN-13 for(i = 1; i <= 6; i++) { regw[i - 1] = local_text[i]; regx[i - 1] = local_text[i + 6]; } if (ustrlen(local_text) > latch) { // With add-on for (i = (latch + 1); i <= ustrlen(local_text); i++) { regz[i - (latch + 1)] = local_text[i]; } } local_text[1] = '\0'; } else if (latch > 5) { // EAN-8 for(i = 0; i <= 3; i++) { regw[i] = local_text[i + 4]; } if (ustrlen(local_text) > latch) { // With add-on for (i = (latch + 1); i <= ustrlen(local_text); i++) { regz[i - (latch + 1)] = local_text[i]; } } local_text[4] = '\0'; } } if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CC)) { latch = ustrlen(local_text); for(i = 0; i < ustrlen(local_text); i++) { if (local_text[i] == '+') { latch = i; } } if (ustrlen(local_text) > latch) { // With add-on for (i = (latch + 1); i <= ustrlen(local_text); i++) { regz[i - (latch + 1)] = local_text[i]; } } for(i = 1; i <= 5; i++) { regw[i - 1] = local_text[i]; regx[i - 1] = local_text[i + 6]; } regy[0] = local_text[11]; local_text[1] = '\0'; } if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CC)) { latch = ustrlen(local_text); for(i = 0; i < ustrlen(local_text); i++) { if (local_text[i] == '+') { latch = i; } } if (ustrlen(local_text) > latch) { // With add-on for (i = (latch + 1); i <= ustrlen(local_text); i++) { regz[i - (latch + 1)] = local_text[i]; } } for(i = 1; i <= 6; i++) { regw[i - 1] = local_text[i]; } regx[0] = local_text[7]; local_text[1] = '\0'; } for(i = 0; i <= 5; i++) { emr_exttextoutw[i].type = 0x00000054; // EMR_EXTTEXTOUTW emr_exttextoutw[i].bounds.top = 0; // ignored emr_exttextoutw[i].bounds.left = 0; // ignoredemr_header.emf_header.bytes += emr_exttextoutw[i].bounds.right = 0xffffffff; // ignored emr_exttextoutw[i].bounds.bottom = 0xffffffff; // ignored emr_exttextoutw[i].i_graphics_mode = 0x00000001; // GM_COMPATIBLE emr_exttextoutw[i].ex_scale = 1.0; emr_exttextoutw[i].ey_scale = 1.0; emr_exttextoutw[i].w_emr_text.off_string = 76; emr_exttextoutw[i].w_emr_text.options = 0; emr_exttextoutw[i].w_emr_text.rectangle.top = 0; emr_exttextoutw[i].w_emr_text.rectangle.left = 0; emr_exttextoutw[i].w_emr_text.rectangle.right = 0xffffffff; emr_exttextoutw[i].w_emr_text.rectangle.bottom = 0xffffffff; if (i > 0) { emr_exttextoutw[i].size = 76 + (6 * 6); emr_exttextoutw[i].w_emr_text.off_dx = 76 + (2 * 6); } } emr_exttextoutw[0].w_emr_text.chars = ustrlen(local_text); emr_exttextoutw[0].size = 76 + (6 * bump_up(ustrlen(local_text) + 1)); emr_exttextoutw[0].w_emr_text.reference.x = (emr_header.emf_header.bounds.right - (ustrlen(local_text) * 5.3 * scaler)) / 2; // text left emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler); // text top emr_exttextoutw[0].w_emr_text.off_dx = 76 + (2 * bump_up(ustrlen(local_text) + 1)); for (i = 0; i < bump_up(ustrlen(local_text) + 1) * 2; i++) { string_buffer[i] = '\0'; } utfle_copy(string_buffer, local_text, ustrlen(local_text)); bytecount += 76 + (6 * bump_up(ustrlen(local_text) + 1)); recordcount++; emr_exttextoutw[1].w_emr_text.chars = ustrlen(regw); emr_exttextoutw[2].w_emr_text.chars = ustrlen(regx); emr_exttextoutw[3].w_emr_text.chars = ustrlen(regy); emr_exttextoutw[4].w_emr_text.chars = ustrlen(regz); if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) { if (latch > 8) { /* EAN-13 */ emr_exttextoutw[0].w_emr_text.reference.x = (xoffset - 9) * scaler; emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[1].w_emr_text.reference.x = (8 + xoffset) * scaler; emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[2].w_emr_text.reference.x = (55 + xoffset) * scaler; emr_exttextoutw[2].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; if (ustrlen(regz) > 2) { emr_exttextoutw[4].w_emr_text.reference.x = (115 + xoffset) * scaler; bytecount += 112; recordcount++; } else if (ustrlen(regz) != 0) { emr_exttextoutw[4].w_emr_text.reference.x = (109 + xoffset) * scaler; bytecount += 112; recordcount++; } emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); bytecount += 2 * 112; recordcount += 2; } else if (latch > 5) { /* EAN-8 */ emr_exttextoutw[0].w_emr_text.reference.x = (7 + xoffset) * scaler; emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[1].w_emr_text.reference.x = (40 + xoffset) * scaler; emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; if (ustrlen(regz) > 2) { emr_exttextoutw[4].w_emr_text.reference.x = (87 + xoffset) * scaler; bytecount += 112; recordcount++; } else if (ustrlen(regz) != 0) { emr_exttextoutw[4].w_emr_text.reference.x = (81 + xoffset) * scaler; bytecount += 112; recordcount++; } emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); bytecount += 112; recordcount++; } } if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CC)) { emr_exttextoutw[0].w_emr_text.reference.x = (xoffset - 7) * scaler; emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[1].w_emr_text.reference.x = (14 + xoffset) * scaler; emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[2].w_emr_text.reference.x = (55 + xoffset) * scaler; emr_exttextoutw[2].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[3].w_emr_text.reference.x = (98 + xoffset) * scaler; emr_exttextoutw[3].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; if (ustrlen(regz) > 2) { emr_exttextoutw[4].w_emr_text.reference.x = (117 + xoffset) * scaler; bytecount += 112; recordcount++; } else if (ustrlen(regz) != 0) { emr_exttextoutw[4].w_emr_text.reference.x = (111 + xoffset) * scaler; bytecount += 112; recordcount++; } emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); bytecount += (3 * 112) + 12; recordcount += 4; } if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CC)) { emr_exttextoutw[0].w_emr_text.reference.x = (xoffset - 7) * scaler; emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[1].w_emr_text.reference.x = (8 + xoffset) * scaler; emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; emr_exttextoutw[2].w_emr_text.reference.x = (53 + xoffset) * scaler; emr_exttextoutw[2].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; if (ustrlen(regz) > 2) { emr_exttextoutw[4].w_emr_text.reference.x = (71 + xoffset) * scaler; bytecount += 112; recordcount++; } else if (ustrlen(regz) != 0) { emr_exttextoutw[4].w_emr_text.reference.x = (65 + xoffset) * scaler; bytecount += 112; recordcount++; } emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); bytecount += (2 * 112) + 12; recordcount += 3; } } /* Make background from a rectangle */ background.type = 0x0000002b; // EMR_RECTANGLE; background.size = 24; background.box.top = 0; background.box.left = 0; background.box.right = emr_header.emf_header.bounds.right; background.box.bottom = emr_header.emf_header.bounds.bottom; bytecount += 24; recordcount++; /* Make bind and box rectangles if needed */ if ((symbol->output_options & BARCODE_BIND) || (symbol->output_options & BARCODE_BOX)) { box.top.type = 0x0000002b; // EMR_RECTANGLE; box.top.size = 24; box.top.box.top = 0; box.top.box.bottom = symbol->border_width * scaler; box.top.box.left = symbol->border_width * scaler; box.top.box.right = emr_header.emf_header.bounds.right - (symbol->border_width * scaler); bytecount += 24; recordcount++; box.bottom.type = 0x0000002b; // EMR_RECTANGLE; box.bottom.size = 24; box.bottom.box.top = emr_header.emf_header.bounds.bottom - ((symbol->border_width + textoffset) * scaler); box.bottom.box.bottom = emr_header.emf_header.bounds.bottom - (textoffset * scaler); box.bottom.box.left = symbol->border_width * scaler; box.bottom.box.right = emr_header.emf_header.bounds.right - (symbol->border_width * scaler); bytecount += 24; recordcount++; if (symbol->output_options & BARCODE_BOX) { box.left.type = 0x0000002b; // EMR_RECTANGLE; box.left.size = 24; box.left.box.top = 0; box.left.box.bottom = emr_header.emf_header.bounds.bottom - (textoffset * scaler); box.left.box.left = 0; box.left.box.right = symbol->border_width * scaler; bytecount += 24; recordcount++; box.right.type = 0x0000002b; // EMR_RECTANGLE; box.right.size = 24; box.right.box.top = 0; box.right.box.bottom = emr_header.emf_header.bounds.bottom - (textoffset * scaler); box.right.box.left = emr_header.emf_header.bounds.right - (symbol->border_width * scaler); box.right.box.right = emr_header.emf_header.bounds.right; bytecount += 24; recordcount++; } } /* Make image rectangles, circles, hexagons */ for (this_row = 0; this_row < symbol->rows; this_row++) { 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 < this_row; i++) { if (symbol->row_height[i] == 0) { row_posn += large_bar_height; } else { row_posn += symbol->row_height[i]; } } row_posn += yoffset; if (symbol->symbology != BARCODE_MAXICODE) { if ((symbol->output_options & BARCODE_DOTTY_MODE) != 0) { // Use dots (circles) for(i = 0; i < symbol->width; i++) { if(module_is_set(symbol, this_row, i)) { circle[this_circle].type = 0x0000002a; // EMR_ELLIPSE circle[this_circle].size = 24; circle[this_circle].box.top = this_row * scaler; circle[this_circle].box.bottom = (this_row + 1) * scaler; circle[this_circle].box.left = (i + xoffset) * scaler; circle[this_circle].box.right = (i + xoffset + 1) * scaler; this_circle++; bytecount += 24; recordcount++; } } } else { // Normal mode, with rectangles 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 (latch == 1) { /* a bar */ rectangle[this_rectangle].type = 0x0000002b; // EMR_RECTANGLE; rectangle[this_rectangle].size = 24; rectangle[this_rectangle].box.top = row_posn * scaler; rectangle[this_rectangle].box.bottom = (row_posn + row_height) * scaler; rectangle[this_rectangle].box.left = (i + xoffset) * scaler; rectangle[this_rectangle].box.right = (i + xoffset + block_width) * scaler; bytecount += 24; recordcount++; if (this_row == symbol->rows - 1) { /* Last row, extend bars if needed */ if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { /* guard bar extensions for EAN8 and EAN13 */ if (ustrlen(regx) != 0) { /* EAN-13 */ switch (i) { case 0: case 2: case 46: case 48: case 92: case 94: rectangle[this_rectangle].box.bottom += (5 * scaler); break; } if (i > 94) { /* Add-on */ rectangle[this_rectangle].box.top += (10 * scaler); rectangle[this_rectangle].box.bottom += (5 * scaler); } } else if (ustrlen(regw) != 0) { /* EAN-8 */ switch (i) { case 0: case 2: case 32: case 34: case 64: case 66: rectangle[this_rectangle].box.bottom += (5 * scaler); break; } if (i > 66) { /* Add-on */ rectangle[this_rectangle].box.top += (10 * scaler); rectangle[this_rectangle].box.bottom += (5 * scaler); } } } if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { /* guard bar extensions for UPCA */ if (((i >= 0) && (i <= 11)) || ((i >= 85) && (i <= 96))) { rectangle[this_rectangle].box.bottom += (5 * scaler); } if ((i == 46) || (i == 48)) { rectangle[this_rectangle].box.bottom += (5 * scaler); } if (i > 96) { /* Add-on */ rectangle[this_rectangle].box.top += (10 * scaler); rectangle[this_rectangle].box.bottom += (5 * scaler); } } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { /* guard bar extensions for UPCE */ switch (i) { case 0: case 2: case 46: case 48: case 50: rectangle[this_rectangle].box.bottom += (5 * scaler); break; } if (i > 50) { /* Add-on */ rectangle[this_rectangle].box.top += (10 * scaler); rectangle[this_rectangle].box.bottom += (5 * scaler); } } } this_rectangle++; latch = 0; } else { /* a space */ latch = 1; } i += block_width; } while (i < symbol->width); } } else { float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; /* Maxicode, use hexagons */ /* Calculate bullseye */ for(i = 0; i < 6; i++) { bullseye[i].type = 0x0000002a; // EMR_ELLIPSE bullseye[i].size = 24; } bullseye[0].box.top = (35.60 - 10.85) * scaler; bullseye[0].box.bottom = (35.60 + 10.85) * scaler; bullseye[0].box.left = (35.76 - 10.85) * scaler; bullseye[0].box.right = (35.76 + 10.85) * scaler; bullseye[1].box.top = (35.60 - 8.97) * scaler; bullseye[1].box.bottom = (35.60 + 8.97) * scaler; bullseye[1].box.left = (35.76 - 8.97) * scaler; bullseye[1].box.right = (35.76 + 8.97) * scaler; bullseye[2].box.top = (35.60 - 7.10) * scaler; bullseye[2].box.bottom = (35.60 + 7.10) * scaler; bullseye[2].box.left = (35.76 - 7.10) * scaler; bullseye[2].box.right = (35.76 + 7.10) * scaler; bullseye[3].box.top = (35.60 - 5.22) * scaler; bullseye[3].box.bottom = (35.60 + 5.22) * scaler; bullseye[3].box.left = (35.76 - 5.22) * scaler; bullseye[3].box.right = (35.76 + 5.22) * scaler; bullseye[4].box.top = (35.60 - 3.31) * scaler; bullseye[4].box.bottom = (35.60 + 3.31) * scaler; bullseye[4].box.left = (35.76 - 3.31) * scaler; bullseye[4].box.right = (35.76 + 3.31) * scaler; bullseye[5].box.top = (35.60 - 1.43) * scaler; bullseye[5].box.bottom = (35.60 + 1.43) * scaler; bullseye[5].box.left = (35.76 - 1.43) * scaler; bullseye[5].box.right = (35.76 + 1.43) * scaler; /* Plot hexagons */ for(i = 0; i < symbol->width; i++) { if(module_is_set(symbol, this_row, i)) { hexagon[this_hexagon].type = 0x00000003; // EMR_POLYGON hexagon[this_hexagon].size = 76; hexagon[this_hexagon].count = 6; my = this_row * 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 (this_row & 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; hexagon[this_hexagon].a_points_a.x = ax * scaler; hexagon[this_hexagon].a_points_a.y = ay * scaler; hexagon[this_hexagon].a_points_b.x = bx * scaler; hexagon[this_hexagon].a_points_b.y = by * scaler; hexagon[this_hexagon].a_points_c.x = cx * scaler; hexagon[this_hexagon].a_points_c.y = cy * scaler; hexagon[this_hexagon].a_points_d.x = dx * scaler; hexagon[this_hexagon].a_points_d.y = dy * scaler; hexagon[this_hexagon].a_points_e.x = ex * scaler; hexagon[this_hexagon].a_points_e.y = ey * scaler; hexagon[this_hexagon].a_points_f.x = fx * scaler; hexagon[this_hexagon].a_points_f.y = fy * scaler; hexagon[this_hexagon].bounds.top = hexagon[this_hexagon].a_points_d.y; hexagon[this_hexagon].bounds.bottom = hexagon[this_hexagon].a_points_a.y; hexagon[this_hexagon].bounds.left = hexagon[this_hexagon].a_points_e.x; hexagon[this_hexagon].bounds.right = hexagon[this_hexagon].a_points_c.x; this_hexagon++; bytecount += 76; recordcount++; } } } } if (symbol->output_options & BARCODE_BIND) { if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { /* row binding */ for (i = 1; i < symbol->rows; i++) { row_binding[i - 1].type = 0x0000002b; // EMR_RECTANGLE; row_binding[i - 1].size = 24; row_binding[i - 1].box.top = ((i * row_height) + yoffset - 1) * scaler; row_binding[i - 1].box.bottom = row_binding[i - 1].box.top + (2 * scaler); if (symbol->symbology != BARCODE_CODABLOCKF) { row_binding[i - 1].box.left = xoffset * scaler; row_binding[i - 1].box.right = emr_header.emf_header.bounds.right - (xoffset * scaler); } else { row_binding[i - 1].box.left = (xoffset + 11) * scaler; row_binding[i - 1].box.right = emr_header.emf_header.bounds.right - ((xoffset + 14) * scaler); } bytecount += 24; recordcount++; } } } /* Create EOF record */ emr_eof.type = 0x0000000e; // EMR_EOF emr_eof.size = 18; // Assuming no palette entries emr_eof.n_pal_entries = 0; emr_eof.off_pal_entries = 0; emr_eof.size_last = emr_eof.size; bytecount += 18; recordcount++; /* Put final counts in header */ emr_header.emf_header.bytes = bytecount; emr_header.emf_header.records = recordcount; /* Send EMF data to file */ if (symbol->output_options & BARCODE_STDOUT) { emf_file = stdout; } else { emf_file = fopen(symbol->outfile, "w"); } if (emf_file == NULL) { strcpy(symbol->errtxt, "Could not open output file (F40)"); return ZINT_ERROR_FILE_ACCESS; } fwrite(&emr_header, sizeof(emr_header_t), 1, emf_file); fwrite(&emr_createbrushindirect_fg, sizeof(emr_createbrushindirect_t), 1, emf_file); fwrite(&emr_createbrushindirect_bg, sizeof(emr_createbrushindirect_t), 1, emf_file); fwrite(&emr_createpen, sizeof(emr_createpen_t), 1, emf_file); if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { fwrite(&emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw_t), 1, emf_file); } fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_selectobject_pen, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&background, sizeof(emr_rectangle_t), 1, emf_file); fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); for (i = 0; i < rectangle_count; i++) { fwrite(&rectangle[i], sizeof(emr_rectangle_t), 1, emf_file); } for (i = 0; i < circle_count; i++) { fwrite(&circle[i], sizeof(emr_ellipse_t), 1, emf_file); } for (i = 0; i < hexagon_count; i++) { fwrite(&hexagon[i], sizeof(emr_polygon_t), 1, emf_file); } if ((symbol->output_options & BARCODE_BIND) || (symbol->output_options & BARCODE_BOX)) { fwrite(&box.top, sizeof(emr_rectangle_t), 1, emf_file); fwrite(&box.bottom, sizeof(emr_rectangle_t), 1, emf_file); if (symbol->output_options & BARCODE_BOX) { fwrite(&box.left, sizeof(emr_rectangle_t), 1, emf_file); fwrite(&box.right, sizeof(emr_rectangle_t), 1, emf_file); } } if (symbol->output_options & BARCODE_BIND) { if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { for(i = 0; i < symbol->rows - 1; i++) { fwrite(&row_binding[i], sizeof(emr_rectangle_t), 1, emf_file); } } } if(symbol->symbology == BARCODE_MAXICODE) { fwrite(&bullseye[0], sizeof(emr_ellipse_t), 1, emf_file); fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&bullseye[1], sizeof(emr_ellipse_t), 1, emf_file); fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&bullseye[2], sizeof(emr_ellipse_t), 1, emf_file); fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&bullseye[3], sizeof(emr_ellipse_t), 1, emf_file); fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&bullseye[4], sizeof(emr_ellipse_t), 1, emf_file); fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&bullseye[5], sizeof(emr_ellipse_t), 1, emf_file); } if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) { if (ustrlen(regx) != 0) { /* EAN-13 */ fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regw, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_exttextoutw[2], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regx, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } if (ustrlen(regz) != 0) { fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regz, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } } textdone = 1; } else if (ustrlen(regw) != 0) { /* EAN-8 */ fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regw, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } if (ustrlen(regz) != 0) { fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regz, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } } textdone = 1; } } if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CC)) { fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_exttextoutw[3], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regy, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_selectobject_font_big, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regw, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_exttextoutw[2], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regx, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } if (ustrlen(regz) != 0) { fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regz, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } } textdone = 1; } if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_exttextoutw[2], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regx, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } fwrite(&emr_selectobject_font_big, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regw, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } if (ustrlen(regz) != 0) { fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); utfle_copy(output_buffer, regz, 6); fwrite(&output_buffer, 12, 1, emf_file); for (i = 0; i < 6; i++) { fwrite(&dx, 4, 1, emf_file); } } textdone = 1; } if (textdone == 0) { fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { fwrite(&dx, 4, 1, emf_file); } } } fwrite(&emr_eof, sizeof(emr_eof_t), 1, emf_file); if (symbol->output_options & BARCODE_STDOUT) { fflush(emf_file); } else { fclose(emf_file); } return error_number; }