diff -Naur barcode-0.98/barcode.h barcode-0.98-png/barcode.h --- barcode-0.98/barcode.h 2002-03-01 23:41:51.000000000 +0100 +++ barcode-0.98-png/barcode.h 2009-06-02 01:39:58.000000000 +0200 @@ -58,6 +58,7 @@ #define BARCODE_OUT_PCL 0x00004000 /* by Andrea Scopece */ /* PCL_III 0x00008000 */ #define BARCODE_OUT_PCL_III 0x0000C000 +#define BARCODE_OUT_PNG 0x00010000 #define BARCODE_OUT_NOHEADERS 0x00100000 /* no header nor footer */ enum { diff -Naur barcode-0.98/configure.in barcode-0.98-png/configure.in --- barcode-0.98/configure.in 2000-11-08 19:52:55.000000000 +0100 +++ barcode-0.98-png/configure.in 2009-06-02 01:39:58.000000000 +0200 @@ -16,6 +16,7 @@ dnl Check for getopt and libpaper. If getopt is missing, use our version AC_CHECK_HEADER(getopt.h, ,NO_GETOPT=-DNO_GETOPT;GETOPT_O=compat/getopt.o) AC_CHECK_HEADER(paper.h, LIBPAPER=-lpaper, NO_LIBPAPER=-DNO_LIBPAPER) +AC_CHECK_HEADER(gd.h, LIBGD=-lgd;HAVE_LIBGD=-DHAVE_LIBGD;PNGOBJ=png.o, NO_LIBGD=-DNO_LIBGD) AC_CHECK_HEADERS(unistd.h) AC_CHECK_FUNC(strerror, , NO_STRERROR=-DNO_STRERROR) @@ -50,6 +51,10 @@ AC_SUBST(NO_GETOPT) AC_SUBST(NO_LIBPAPER) AC_SUBST(LIBPAPER) +AC_SUBST(HAVE_LIBGD) +AC_SUBST(NO_LIBGD) +AC_SUBST(LIBGD) +AC_SUBST(PNGOBJ) AC_SUBST(NO_STRERROR) AC_SUBST(GMAKEDEPEND0) AC_SUBST(GMAKEDEPEND1) diff -Naur barcode-0.98/doc/doc.barcode barcode-0.98-png/doc/doc.barcode --- barcode-0.98/doc/doc.barcode 2002-03-01 23:41:50.000000000 +0100 +++ barcode-0.98-png/doc/doc.barcode 2009-06-02 01:39:58.000000000 +0200 @@ -361,11 +361,14 @@ @itemx BARCODE_OUT_EPS @itemx BARCODE_OUT_PCL @itemx BARCODE_OUT_PCL_III +@itemx BARCODE_OUT_PNG The currently supported encoding types: full-page postscript and encapsulated postscript; PCL (print command language, for - HP printers) and PCL-III (same as PCL, but uses a font not - available on older printers). + HP printers); PCL-III (same as PCL, but uses a font not + available on older printers); and PNG (only available if libgd + was detected at compile-time, otherwise the printing engine will + fail with ENOTSUP). @item BARCODE_OUT_NOHEADERS @@ -597,6 +600,9 @@ to bottom for PCL, and the origin for an image is the top-left corner instead of the bottom-left +@item -N + PNG output (only available if libgd was detected at compile time). + @item -p pagesize Specify a non-default page size. The page size can be specified in millimeters, inches or plain numbers (for example: "@t{210x297mm}", diff -Naur barcode-0.98/library.c barcode-0.98-png/library.c --- barcode-0.98/library.c 2002-03-01 23:39:24.000000000 +0100 +++ barcode-0.98-png/library.c 2009-06-02 01:39:58.000000000 +0200 @@ -3,6 +3,7 @@ * * Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org) * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it) + * PNG support by David Santinoli (david@santinoli.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -172,6 +173,9 @@ */ extern int Barcode_ps_print(struct Barcode_Item *bc, FILE *f); extern int Barcode_pcl_print(struct Barcode_Item *bc, FILE *f); +#ifdef HAVE_LIBGD +extern int Barcode_png_print(struct Barcode_Item *bc, FILE *f); +#endif /* * A function to print a partially decoded string. Meaningful bits for @@ -194,6 +198,14 @@ if (bc->flags & BARCODE_OUT_PCL) return Barcode_pcl_print(bc, f); + else if (bc->flags & BARCODE_OUT_PNG) { +#ifdef HAVE_LIBGD + return Barcode_png_print(bc, f); +#else + bc->error = ENOTSUP; + return -1; +#endif + } return Barcode_ps_print(bc, f); } diff -Naur barcode-0.98/main.c barcode-0.98-png/main.c --- barcode-0.98/main.c 2002-03-01 22:31:07.000000000 +0100 +++ barcode-0.98-png/main.c 2009-06-02 01:39:58.000000000 +0200 @@ -4,6 +4,7 @@ * Copyright (c) 1999 Michele Comitini (mcm@glisco.it) * Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org) * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it) + * PNG support by David Santinoli (david@santinoli.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -123,7 +124,7 @@ int xmargin0, ymargin0; /* both for "-g" and "-t" */ int xmargin1, ymargin1; /* same, but right and top */ int ximargin, yimargin; /* "-m": internal margins */ -int eps, pcl, ps, noascii, nochecksum; /* boolean flags */ +int eps, pcl, ps, png, noascii, nochecksum; /* boolean flags */ int page_wid, page_hei; /* page size in points */ char *page_name; /* name of the media */ double unit = 1.0; /* unit specification */ @@ -395,6 +396,10 @@ "print one code as eps file (default: multi-page ps)"}, {'P', CMDLINE_NONE, &pcl, NULL, NULL, NULL, "create PCL output instead of postscript"}, +#ifdef HAVE_LIBGD + {'N', CMDLINE_NONE, &png, NULL, NULL, NULL, + "create PNG output instead of postscript"}, +#endif {'p', CMDLINE_S, NULL, get_page_geometry, NULL, NULL, "page size (refer to the man page)"}, {0,} @@ -481,13 +486,15 @@ } if (encoding_type < 0) { /* unknown type specified */ - fprintf(stderr,"%s: Unknown endoding. Try \"%s --help\"\n", + fprintf(stderr,"%s: Unknown encoding. Try \"%s --help\"\n", argv[0], argv[0]); exit(1); } flags |= encoding_type; if (pcl) { flags |= BARCODE_OUT_PCL; + } else if (png) { + flags |= BARCODE_OUT_PNG; } else { ps = !eps; /* a shortcut */ if (eps) diff -Naur barcode-0.98/Makefile.in barcode-0.98-png/Makefile.in --- barcode-0.98/Makefile.in 2001-10-17 15:26:21.000000000 +0200 +++ barcode-0.98-png/Makefile.in 2009-06-02 01:39:58.000000000 +0200 @@ -3,12 +3,12 @@ # CC = @CC@ -CFLAGS = @CFLAGS@ @DEFS@ @NO_GETOPT@ @NO_LIBPAPER@ @NO_STRERROR@ +CFLAGS = @CFLAGS@ @DEFS@ @NO_GETOPT@ @NO_LIBPAPER@ @NO_STRERROR@ @HAVE_LIBGD@ RANLIB = @RANLIB@ INSTALL = @INSTALL@ -LDFLAGS = -L. -l$(TARGET) @LIBPAPER@ +LDFLAGS = -L. -l$(TARGET) @LIBPAPER@ @LIBGD@ prefix = @prefix@ BINDIR = $(prefix)/bin @@ -30,7 +30,7 @@ LIBOBJECTS = library.o ean.o code128.o code39.o code93.o i25.o \ msi.o plessey.o codabar.o \ - ps.o pcl.o + ps.o pcl.o @PNGOBJ@ EXEOBJECTS = main.o cmdline.o $(GETOPT_O) ALLSOURCES = $(LIBOBJECTS:.o=.c) $(EXEOBJECT:.o=.c) diff -Naur barcode-0.98/png.c barcode-0.98-png/png.c --- barcode-0.98/png.c 1970-01-01 01:00:00.000000000 +0100 +++ barcode-0.98-png/png.c 2009-06-02 01:39:58.000000000 +0200 @@ -0,0 +1,216 @@ +/* + * png.c -- printing the "partial" bar encoding in PNG format + * + * Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org) + * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it) + * Copyright (c) 2005 David Santinoli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + issues: + text font + scaling (see 'barcode -N -b 34875394 -g 200x100') + scalef should be read from bc->scalef? + (bc->width < barlen * scalef)... math rounding error! + + limitations: (FE=front-end) + [FE] multiple output not supported (only first (or last?) supplied code is + rendered) + +*/ + +#include +#include +#include +#include +#include +#include + +#include "barcode.h" + + + +/* + * How do the "partial" and "textinfo" strings work? See file "ps.c" + */ + + +int Barcode_png_print(struct Barcode_Item *bc, FILE *f) +{ + int i, j, k, barlen; + double f1, f2; + int mode = '-'; /* text below bars */ + double scalef=1; + int xpos, x0, y0, yr; + unsigned char *ptr; + unsigned char c; + gdImagePtr im; + int back, black; + int out_w, out_h; + int brect[8]; + char *font = "/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf"; + + if (!bc->partial || !bc->textinfo) { + bc->error = EINVAL; + return -1; + } + + //bc->margin=0; + + /* + * Maybe this first part can be made common to several printing back-ends, + * we'll see how that works when other ouput engines are added + */ + + /* First, calculate barlen */ + barlen = bc->partial[0] - '0'; + for (ptr = bc->partial+1; *ptr; ptr++) + if (isdigit(*ptr)) + barlen += (*ptr - '0'); + else if (islower(*ptr)) + barlen += (*ptr - 'a'+1); + + if(bc->flags & BARCODE_NO_ASCII) + if(bc->width==barlen) bc->width=barlen=barlen-(bc->partial[0]-'0'); + + /* The scale factor depends on bar length */ + if (!bc->scalef) { + if (!bc->width) bc->width = barlen; /* default */ + scalef = bc->scalef = (double)bc->width / (double)barlen; + } + + /* The width defaults to "just enough" */ + if (!bc->width) bc->width = barlen * scalef +1; + + /* But it can be too small, in this case enlarge and center the area */ + if (bc->width < barlen * scalef) { + int wid = barlen * scalef + 1; + bc->xoff -= (wid - bc->width)/2 ; + bc->width = wid; + /* Can't extend too far on the left */ + if (bc->xoff < 0) { + bc->width += -bc->xoff; + bc->xoff = 0; + } + } + + /* The height defaults to 80 points (rescaled) */ + if (!bc->height) bc->height = 80 * scalef; + +#if 0 + /* If too small (5 + text), enlarge and center */ + i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0); + if (bc->height < i * scalef ) { + int hei = i * scalef; + bc->yoff -= (hei-bc->height)/2; + bc->height = hei; + if (bc->yoff < 0) { + bc->height += -bc->yoff; + bc->yoff = 0; + } + } +#else + /* If too small (5 + text), reduce the scale factor and center */ + i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0); + if (bc->height < i * scalef ) { + double scaleg = ((double)bc->height) / i; + int wid = bc->width * scaleg / scalef; + bc->xoff += (bc->width - wid)/2; + bc->width = wid; + scalef = scaleg; + } +#endif + + out_w=bc->width+2*bc->margin; + out_h=bc->height+2*bc->margin; + im = gdImageCreateTrueColor(out_w,out_h); + fprintf(stderr,"Creating %dx%d box ...\n",out_w,out_h); + back = gdImageColorAllocate(im, 255,255,255); + black = gdImageColorAllocate(im, 0,0,0); + gdImageFilledRectangle(im, 0, 0, out_w-1, out_h-1, back); + + xpos = bc->margin; + if(!(bc->flags & BARCODE_NO_ASCII)) xpos+= (bc->partial[0]-'0') * scalef; + for (ptr = bc->partial+1, i=1; *ptr; ptr++, i++) { + /* special cases: '+' and '-' */ + if (*ptr == '+' || *ptr == '-') { + mode = *ptr; /* don't count it */ i++; continue; + } + + /* j is the width of this bar/space */ + if (isdigit (*ptr)) j = *ptr-'0'; + else j = *ptr-'a'+1; + if (i%2) { /* bar */ + x0 = bc->xoff + xpos; + y0 = bc->yoff + bc->margin; + yr = bc->height; + if (!(bc->flags & BARCODE_NO_ASCII)) { /* leave space for text */ + if (mode == '-') { + /* text below bars: 10 points or five points */ + yr -= (isdigit(*ptr) ? 10 : 5) * scalef; + } else { /* '+' */ + /* text above bars: 10 or 0 from bottom, and 10 from top */ + y0 += (isdigit(*ptr) ? 10 : 0) * scalef; + yr -= (isdigit(*ptr) ? 20 : 10) * scalef; + } + } + + fprintf(stderr,"%d %d %f %d\n", x0,y0,x0+j*scalef,y0+yr); + gdImageFilledRectangle(im, x0,y0,x0+j*scalef-1,y0+yr-1,black); + + } + xpos += j * scalef; + } + + /* the text */ + + fprintf(stderr,"%s\n",bc->textinfo); + mode = '-'; /* reinstantiate default */ + if (!(bc->flags & BARCODE_NO_ASCII)) { + char ch[2]= {0, 0}; + k=0; /* k is the "previous font size" */ + for (ptr = bc->textinfo; ptr; ptr = strchr(ptr, ' ')) { + while (*ptr == ' ') ptr++; + if (!*ptr) break; + if (*ptr == '+' || *ptr == '-') { + mode = *ptr; continue; + } + if (sscanf(ptr, "%lf:%lf:%c", &f1, &f2, &c) != 3) { + fprintf(stderr, "barcode: impossible data: %s\n", ptr); + continue; + } + + ch[0]=c; + gdImageStringFT(im,&brect[0],black,font,10*scalef,0.0, + bc->xoff + f1 * scalef + bc->margin, + mode != '-' + ? ((double)bc->yoff + bc->margin + 8*scalef) + : ((double)bc->yoff + bc->margin + bc->height ), ch); + fprintf(stderr," (%f %f) %c\n", (bc->xoff + f1 * scalef + bc->margin), + mode != '-' + ? ((double)bc->yoff + bc->margin + 8*scalef) + : ((double)bc->yoff + bc->margin + bc->height ), c); + + } + + } + + gdImagePng(im,f); + gdImageDestroy(im); + + return 0; +}