gbarcode 0.98.16-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +3 -0
- data/COPYING +0 -0
- data/README +199 -0
- data/Rakefile +109 -0
- data/ext/barcode.h +119 -0
- data/ext/barcode_wrap.c +3192 -0
- data/ext/codabar.c +182 -0
- data/ext/code128.c +607 -0
- data/ext/code39.c +173 -0
- data/ext/code93.c +213 -0
- data/ext/ean.c +774 -0
- data/ext/extconf.rb +6 -0
- data/ext/i25.c +164 -0
- data/ext/library.c +244 -0
- data/ext/msi.c +155 -0
- data/ext/pcl.c +200 -0
- data/ext/plessey.c +164 -0
- data/ext/ps.c +272 -0
- data/ext/svg.c +174 -0
- data/extras/mingw-rbconfig.rb +176 -0
- data/lib/gbarcode.so +0 -0
- data/test/assets/gb-code128b.eps +44 -0
- data/test/gbarcode_test.rb +48 -0
- data/test/test_helper.rb +2 -0
- metadata +77 -0
data/ext/pcl.c
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
/*
|
2
|
+
* pcl.c -- printing the "partial" bar encoding in PCL format
|
3
|
+
*
|
4
|
+
* Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org)
|
5
|
+
* Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
|
6
|
+
* Copyright (c) 2001 Andrea Scopece (a.scopece@tin.it)
|
7
|
+
*
|
8
|
+
* This program is free software; you can redistribute it and/or modify
|
9
|
+
* it under the terms of the GNU General Public License as published by
|
10
|
+
* the Free Software Foundation; either version 2 of the License, or
|
11
|
+
* (at your option) any later version.
|
12
|
+
*
|
13
|
+
* This program is distributed in the hope that it will be useful,
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
* GNU General Public License for more details.
|
17
|
+
*
|
18
|
+
* You should have received a copy of the GNU General Public License
|
19
|
+
* along with this program; if not, write to the Free Software
|
20
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include <stdio.h>
|
24
|
+
#include <stdlib.h>
|
25
|
+
#include <string.h>
|
26
|
+
#include <ctype.h>
|
27
|
+
#include <errno.h>
|
28
|
+
|
29
|
+
#include "barcode.h"
|
30
|
+
|
31
|
+
#define SHRINK_AMOUNT 0.15 /* shrink the bars to account for ink spreading */
|
32
|
+
|
33
|
+
|
34
|
+
/*
|
35
|
+
* How do the "partial" and "textinfo" strings work? See file "ps.c"
|
36
|
+
*/
|
37
|
+
|
38
|
+
|
39
|
+
int Barcode_pcl_print(struct Barcode_Item *bc, FILE *f)
|
40
|
+
{
|
41
|
+
int i, j, k, barlen;
|
42
|
+
double f1, f2, fsav=0;
|
43
|
+
int mode = '-'; /* text below bars */
|
44
|
+
double scalef=1, xpos, x0, y0, yr;
|
45
|
+
unsigned char *ptr;
|
46
|
+
unsigned char c;
|
47
|
+
|
48
|
+
char font_id[6]; /* default font, should be "scalable" */
|
49
|
+
/* 0 Line printer, use on older LJet II, isn't scalable */
|
50
|
+
/* 4148 Univers, use on LJet III series, and Lj 4L, 5L */
|
51
|
+
/* 16602 Arial, default LJ family 4, 5, 6, Color, Djet */
|
52
|
+
|
53
|
+
if (!bc->partial || !bc->textinfo) {
|
54
|
+
bc->error = EINVAL;
|
55
|
+
return -1;
|
56
|
+
}
|
57
|
+
|
58
|
+
/*
|
59
|
+
* Maybe this first part can be made common to several printing back-ends,
|
60
|
+
* we'll see how that works when other ouput engines are added
|
61
|
+
*/
|
62
|
+
|
63
|
+
/* First, calculate barlen */
|
64
|
+
barlen = bc->partial[0] - '0';
|
65
|
+
for (ptr = bc->partial+1; *ptr; ptr++)
|
66
|
+
if (isdigit(*ptr))
|
67
|
+
barlen += (*ptr - '0');
|
68
|
+
else if (islower(*ptr))
|
69
|
+
barlen += (*ptr - 'a'+1);
|
70
|
+
|
71
|
+
/* The scale factor depends on bar length */
|
72
|
+
if (!bc->scalef) {
|
73
|
+
if (!bc->width) bc->width = barlen; /* default */
|
74
|
+
scalef = bc->scalef = (double)bc->width / (double)barlen;
|
75
|
+
}
|
76
|
+
|
77
|
+
/* The width defaults to "just enough" */
|
78
|
+
if (!bc->width) bc->width = barlen * scalef +1;
|
79
|
+
|
80
|
+
/* But it can be too small, in this case enlarge and center the area */
|
81
|
+
if (bc->width < barlen * scalef) {
|
82
|
+
int wid = barlen * scalef + 1;
|
83
|
+
bc->xoff -= (wid - bc->width)/2 ;
|
84
|
+
bc->width = wid;
|
85
|
+
/* Can't extend too far on the left */
|
86
|
+
if (bc->xoff < 0) {
|
87
|
+
bc->width += -bc->xoff;
|
88
|
+
bc->xoff = 0;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
/* The height defaults to 80 points (rescaled) */
|
93
|
+
if (!bc->height) bc->height = 80 * scalef;
|
94
|
+
|
95
|
+
#if 0
|
96
|
+
/* If too small (5 + text), enlarge and center */
|
97
|
+
i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
|
98
|
+
if (bc->height < i * scalef ) {
|
99
|
+
int hei = i * scalef;
|
100
|
+
bc->yoff -= (hei-bc->height)/2;
|
101
|
+
bc->height = hei;
|
102
|
+
if (bc->yoff < 0) {
|
103
|
+
bc->height += -bc->yoff;
|
104
|
+
bc->yoff = 0;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
#else
|
108
|
+
/* If too small (5 + text), reduce the scale factor and center */
|
109
|
+
i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
|
110
|
+
if (bc->height < i * scalef ) {
|
111
|
+
double scaleg = ((double)bc->height) / i;
|
112
|
+
int wid = bc->width * scaleg / scalef;
|
113
|
+
bc->xoff += (bc->width - wid)/2;
|
114
|
+
bc->width = wid;
|
115
|
+
scalef = scaleg;
|
116
|
+
}
|
117
|
+
#endif
|
118
|
+
|
119
|
+
/*
|
120
|
+
* deal with PCL output
|
121
|
+
*/
|
122
|
+
|
123
|
+
xpos = bc->margin + (bc->partial[0]-'0') * scalef;
|
124
|
+
for (ptr = bc->partial+1, i=1; *ptr; ptr++, i++) {
|
125
|
+
/* special cases: '+' and '-' */
|
126
|
+
if (*ptr == '+' || *ptr == '-') {
|
127
|
+
mode = *ptr; /* don't count it */ i++; continue;
|
128
|
+
}
|
129
|
+
|
130
|
+
/* j is the width of this bar/space */
|
131
|
+
if (isdigit (*ptr)) j = *ptr-'0';
|
132
|
+
else j = *ptr-'a'+1;
|
133
|
+
if (i%2) { /* bar */
|
134
|
+
x0 = bc->xoff + xpos;
|
135
|
+
y0 = bc->yoff + bc->margin;
|
136
|
+
yr = bc->height;
|
137
|
+
if (!(bc->flags & BARCODE_NO_ASCII)) { /* leave space for text */
|
138
|
+
if (mode == '-') {
|
139
|
+
/* text below bars: 10 points or five points */
|
140
|
+
yr -= (isdigit(*ptr) ? 10 : 5) * scalef;
|
141
|
+
} else { /* '+' */
|
142
|
+
/* text above bars: 10 or 0 from bottom, and 10 from top */
|
143
|
+
y0 += (isdigit(*ptr) ? 10 : 0) * scalef;
|
144
|
+
yr -= (isdigit(*ptr) ? 20 : 10) * scalef;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
fprintf(f,"%c&a%.0fH", 27, x0 * 10.0);
|
149
|
+
fprintf(f,"%c&a%.0fV", 27, y0 * 10.0);
|
150
|
+
fprintf(f,"%c*c%.0fH", 27, ((j*scalef)-SHRINK_AMOUNT) * 10.0);
|
151
|
+
fprintf(f,"%c*c%.0fV", 27, yr * 10.0);
|
152
|
+
fprintf(f,"%c*c0P\n", 27);
|
153
|
+
}
|
154
|
+
xpos += j * scalef;
|
155
|
+
}
|
156
|
+
|
157
|
+
/* the text */
|
158
|
+
|
159
|
+
mode = '-'; /* reinstantiate default */
|
160
|
+
if (!(bc->flags & BARCODE_NO_ASCII)) {
|
161
|
+
k=0; /* k is the "previous font size" */
|
162
|
+
for (ptr = bc->textinfo; ptr; ptr = strchr(ptr, ' ')) {
|
163
|
+
while (*ptr == ' ') ptr++;
|
164
|
+
if (!*ptr) break;
|
165
|
+
if (*ptr == '+' || *ptr == '-') {
|
166
|
+
mode = *ptr; continue;
|
167
|
+
}
|
168
|
+
if (sscanf(ptr, "%lf:%lf:%c", &f1, &f2, &c) != 3) {
|
169
|
+
fprintf(stderr, "barcode: impossible data: %s\n", ptr);
|
170
|
+
continue;
|
171
|
+
}
|
172
|
+
|
173
|
+
/* select a Scalable Font */
|
174
|
+
|
175
|
+
if (fsav != f2)
|
176
|
+
{
|
177
|
+
if ((bc->flags & BARCODE_OUT_PCL_III) == BARCODE_OUT_PCL_III)
|
178
|
+
{ strcpy(font_id, "4148"); /* font Univers */
|
179
|
+
}
|
180
|
+
else
|
181
|
+
{ strcpy(font_id, "16602"); /* font Arial */
|
182
|
+
}
|
183
|
+
|
184
|
+
fprintf(f,"%c(8U%c(s1p%5.2fv0s0b%sT", 27, 27, f2 * scalef, font_id);
|
185
|
+
}
|
186
|
+
fsav = f2;
|
187
|
+
|
188
|
+
fprintf(f,"%c&a%.0fH", 27, (bc->xoff + f1 * scalef + bc->margin) * 10.0);
|
189
|
+
fprintf(f,"%c&a%.0fV", 27,
|
190
|
+
mode != '-'
|
191
|
+
? ((double)bc->yoff + bc->margin + 8*scalef) * 10.0
|
192
|
+
: ((double)bc->yoff + bc->margin + bc->height ) * 10.0);
|
193
|
+
|
194
|
+
fprintf(f, "%c", c);
|
195
|
+
}
|
196
|
+
|
197
|
+
}
|
198
|
+
|
199
|
+
return 0;
|
200
|
+
}
|
data/ext/plessey.c
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
/*
|
2
|
+
* plessey.c -- encoding for Plessey
|
3
|
+
*
|
4
|
+
* Copyright (c) 2000 Leonid A. Broukhis (leob@mailcom.com)
|
5
|
+
*
|
6
|
+
* This program is free software; you can redistribute it and/or modify
|
7
|
+
* it under the terms of the GNU General Public License as published by
|
8
|
+
* the Free Software Foundation; either version 2 of the License, or
|
9
|
+
* (at your option) any later version.
|
10
|
+
*
|
11
|
+
* This program is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
* GNU General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU General Public License
|
17
|
+
* along with this program; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
19
|
+
*/
|
20
|
+
|
21
|
+
#include <stdio.h>
|
22
|
+
#include <stdlib.h>
|
23
|
+
#include <string.h>
|
24
|
+
#include <ctype.h>
|
25
|
+
#include <errno.h>
|
26
|
+
|
27
|
+
#include "barcode.h"
|
28
|
+
|
29
|
+
static char * patterns[] = { "13", "31" };
|
30
|
+
|
31
|
+
/* this is ordered in decades to simplify encoding */
|
32
|
+
static char alphabet[] =
|
33
|
+
"0123456789" "ABCDEF";
|
34
|
+
|
35
|
+
/* stop sequence may be 231311313 (barcodemill.com) */
|
36
|
+
static char *fillers[] = { "031311331", "331311313" };
|
37
|
+
|
38
|
+
static int width = 16, startpos = 16;
|
39
|
+
|
40
|
+
/*
|
41
|
+
* Check that the text can be encoded. Returns 0 or -1.
|
42
|
+
* If it's all lowecase convert to uppercase and accept it
|
43
|
+
*/
|
44
|
+
int Barcode_pls_verify(unsigned char *text)
|
45
|
+
{
|
46
|
+
int i, upper = 0, lower = 0;
|
47
|
+
|
48
|
+
if (!strlen(text))
|
49
|
+
return -1;
|
50
|
+
for (i=0; text[i]; i++) {
|
51
|
+
if (!strchr(alphabet,toupper(text[i])))
|
52
|
+
return -1;
|
53
|
+
if (isupper(text[i])) upper++;
|
54
|
+
if (islower(text[i])) lower++;
|
55
|
+
}
|
56
|
+
if (upper && lower)
|
57
|
+
return -1;
|
58
|
+
return 0;
|
59
|
+
}
|
60
|
+
|
61
|
+
static int add_one(char *ptr, int code)
|
62
|
+
{
|
63
|
+
sprintf(ptr, "%s%s%s%s",
|
64
|
+
patterns[code & 1],
|
65
|
+
patterns[(code >> 1) & 1],
|
66
|
+
patterns[(code >> 2) & 1],
|
67
|
+
patterns[(code >> 3) & 1]
|
68
|
+
);
|
69
|
+
return 0;
|
70
|
+
}
|
71
|
+
|
72
|
+
/*
|
73
|
+
* The encoding functions fills the "partial" and "textinfo" fields.
|
74
|
+
* Lowercase chars are converted to uppercase
|
75
|
+
*/
|
76
|
+
int Barcode_pls_encode(struct Barcode_Item *bc)
|
77
|
+
{
|
78
|
+
static char *text;
|
79
|
+
static char *partial; /* dynamic */
|
80
|
+
static char *textinfo; /* dynamic */
|
81
|
+
char *c, *ptr, *textptr;
|
82
|
+
unsigned char *checkptr;
|
83
|
+
int i, code, textpos;
|
84
|
+
static char check[9] = {1,1,1,1,0,1,0,0,1};
|
85
|
+
if (bc->partial)
|
86
|
+
free(bc->partial);
|
87
|
+
if (bc->textinfo)
|
88
|
+
free(bc->textinfo);
|
89
|
+
bc->partial = bc->textinfo = NULL; /* safe */
|
90
|
+
|
91
|
+
if (!bc->encoding)
|
92
|
+
bc->encoding = strdup("plessey");
|
93
|
+
|
94
|
+
text = bc->ascii;
|
95
|
+
if (!text) {
|
96
|
+
bc->error = EINVAL;
|
97
|
+
return -1;
|
98
|
+
}
|
99
|
+
/* the partial code is 8 * (head + text + check + tail) + margin + term. */
|
100
|
+
partial = malloc( (strlen(text) + 4) * 8 + 3);
|
101
|
+
checkptr = calloc (1, strlen(text) * 4 + 8);
|
102
|
+
|
103
|
+
if (!partial || !checkptr) {
|
104
|
+
if (partial) free(partial);
|
105
|
+
if (checkptr) free(checkptr);
|
106
|
+
bc->error = errno;
|
107
|
+
return -1;
|
108
|
+
}
|
109
|
+
|
110
|
+
/* the text information is at most "nnn:fff:c " * strlen +term */
|
111
|
+
textinfo = malloc(10*strlen(text) + 2);
|
112
|
+
if (!textinfo) {
|
113
|
+
bc->error = errno;
|
114
|
+
free(partial);
|
115
|
+
return -1;
|
116
|
+
}
|
117
|
+
|
118
|
+
strcpy(partial, fillers[0]);
|
119
|
+
ptr = partial + strlen(partial);
|
120
|
+
textptr = textinfo;
|
121
|
+
textpos = startpos;
|
122
|
+
|
123
|
+
for (i=0; i<strlen(text); i++) {
|
124
|
+
c = strchr(alphabet, toupper(text[i]));
|
125
|
+
if (!c) {
|
126
|
+
bc->error = EINVAL; /* impossible if text is verified */
|
127
|
+
free(partial);
|
128
|
+
free(textinfo);
|
129
|
+
return -1;
|
130
|
+
}
|
131
|
+
code = c - alphabet;
|
132
|
+
add_one(ptr, code);
|
133
|
+
sprintf(textptr, "%i:12:%c ", textpos, toupper(text[i]));
|
134
|
+
|
135
|
+
textpos += width; /* width of each code */
|
136
|
+
textptr += strlen(textptr);
|
137
|
+
ptr += strlen(ptr);
|
138
|
+
checkptr[4*i] = code & 1;
|
139
|
+
checkptr[4*i+1] = (code >> 1) & 1;
|
140
|
+
checkptr[4*i+2] = (code >> 2) & 1;
|
141
|
+
checkptr[4*i+3] = (code >> 3) & 1;
|
142
|
+
}
|
143
|
+
/* The CRC checksum is required */
|
144
|
+
for (i=0; i < 4*strlen(text); i++) {
|
145
|
+
int j;
|
146
|
+
if (checkptr[i])
|
147
|
+
for (j = 0; j < 9; j++)
|
148
|
+
checkptr[i+j] ^= check[j];
|
149
|
+
}
|
150
|
+
for (i = 0; i < 8; i++) {
|
151
|
+
sprintf(ptr, patterns[checkptr[strlen(text) * 4 + i]]);
|
152
|
+
ptr += 2;
|
153
|
+
}
|
154
|
+
fprintf(stderr, "CRC: ");
|
155
|
+
for (i = 0; i < 8; i++) {
|
156
|
+
fputc('0' + checkptr[strlen(text) * 4 + i], stderr);
|
157
|
+
}
|
158
|
+
fputc('\n', stderr);
|
159
|
+
strcpy(ptr, fillers[1]);
|
160
|
+
bc->partial = partial;
|
161
|
+
bc->textinfo = textinfo;
|
162
|
+
|
163
|
+
return 0;
|
164
|
+
}
|
data/ext/ps.c
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
/*
|
2
|
+
* ps.c -- printing the "partial" bar encoding
|
3
|
+
*
|
4
|
+
* Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org)
|
5
|
+
* Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
|
6
|
+
*
|
7
|
+
* This program is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the GNU General Public License as published by
|
9
|
+
* the Free Software Foundation; either version 2 of the License, or
|
10
|
+
* (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This program is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
* GNU General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU General Public License
|
18
|
+
* along with this program; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <stdio.h>
|
23
|
+
#include <stdlib.h>
|
24
|
+
#include <string.h>
|
25
|
+
#include <ctype.h>
|
26
|
+
#include <errno.h>
|
27
|
+
|
28
|
+
#include "barcode.h"
|
29
|
+
|
30
|
+
#define SHRINK_AMOUNT 0.15 /* shrink the bars to account for ink spreading */
|
31
|
+
|
32
|
+
|
33
|
+
/*
|
34
|
+
* How do the "partial" and "textinfo" strings work?
|
35
|
+
*
|
36
|
+
* The first char in "partial" tells how much extra space to add to the
|
37
|
+
* left of the bars. For EAN-13, it is used to leave space to print the
|
38
|
+
* first digit, other codes may have '0' for no-extra-space-needed.
|
39
|
+
*
|
40
|
+
* The next characters are alternating bars and spaces, as multiples
|
41
|
+
* of the base dimension which is 1 unless the code is
|
42
|
+
* rescaled. Rescaling is calculated as the ratio from the requested
|
43
|
+
* width and the calculated width. Digits represent bar/space
|
44
|
+
* dimensions. Lower-case letters represent those bars that should
|
45
|
+
* extend lower than the others: 'a' is equivalent to '1', 'b' is '2' and
|
46
|
+
* so on.
|
47
|
+
*
|
48
|
+
* The "textinfo" string is made up of fields "%lf:%lf:%c" separated by
|
49
|
+
* blank space. The first integer is the x position of the character,
|
50
|
+
* the second is the font size (before rescaling) and the char item is
|
51
|
+
* the charcter to be printed.
|
52
|
+
*
|
53
|
+
* Both the "partial" and "textinfo" strings may include "-" or "+" as
|
54
|
+
* special characters (in "textinfo" the char should be a standalone
|
55
|
+
* word). They state where the text should be printed: below the bars
|
56
|
+
* ("-", default) or above the bars. This is used, for example, to
|
57
|
+
* print the add-5 and add-2 codes to the right of UPC or EAN codes
|
58
|
+
* (the add-5 extension is mostly used in ISBN codes.
|
59
|
+
*/
|
60
|
+
|
61
|
+
|
62
|
+
int Barcode_ps_print(struct Barcode_Item *bc, FILE *f)
|
63
|
+
{
|
64
|
+
int i, j, k, barlen, printable=1;
|
65
|
+
double f1, f2, fsav=0;
|
66
|
+
int mode = '-'; /* text below bars */
|
67
|
+
double scalef=1, xpos, x0, y0, yr;
|
68
|
+
unsigned char *ptr;
|
69
|
+
unsigned char c;
|
70
|
+
|
71
|
+
if (!bc->partial || !bc->textinfo) {
|
72
|
+
bc->error = EINVAL;
|
73
|
+
return -1;
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
/*
|
78
|
+
* Maybe this first part can be made common to several printing back-ends,
|
79
|
+
* we'll see how that works when other ouput engines are added
|
80
|
+
*/
|
81
|
+
|
82
|
+
/* First, calculate barlen */
|
83
|
+
barlen = bc->partial[0] - '0';
|
84
|
+
for (ptr = bc->partial+1; *ptr; ptr++)
|
85
|
+
if (isdigit(*ptr))
|
86
|
+
barlen += (*ptr - '0');
|
87
|
+
else if (islower(*ptr))
|
88
|
+
barlen += (*ptr - 'a'+1);
|
89
|
+
|
90
|
+
/* The scale factor depends on bar length */
|
91
|
+
if (!bc->scalef) {
|
92
|
+
if (!bc->width) bc->width = barlen; /* default */
|
93
|
+
scalef = bc->scalef = (double)bc->width / (double)barlen;
|
94
|
+
}
|
95
|
+
|
96
|
+
/* The width defaults to "just enough" */
|
97
|
+
if (!bc->width) bc->width = barlen * scalef +1;
|
98
|
+
|
99
|
+
/* But it can be too small, in this case enlarge and center the area */
|
100
|
+
if (bc->width < barlen * scalef) {
|
101
|
+
int wid = barlen * scalef + 1;
|
102
|
+
bc->xoff -= (wid - bc->width)/2 ;
|
103
|
+
bc->width = wid;
|
104
|
+
/* Can't extend too far on the left */
|
105
|
+
if (bc->xoff < 0) {
|
106
|
+
bc->width += -bc->xoff;
|
107
|
+
bc->xoff = 0;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
/* The height defaults to 80 points (rescaled) */
|
112
|
+
if (!bc->height) bc->height = 80 * scalef;
|
113
|
+
|
114
|
+
#if 0
|
115
|
+
/* If too small (5 + text), enlarge and center */
|
116
|
+
i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
|
117
|
+
if (bc->height < i * scalef ) {
|
118
|
+
int hei = i * scalef;
|
119
|
+
bc->yoff -= (hei-bc->height)/2;
|
120
|
+
bc->height = hei;
|
121
|
+
if (bc->yoff < 0) {
|
122
|
+
bc->height += -bc->yoff;
|
123
|
+
bc->yoff = 0;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
#else
|
127
|
+
/* If too small (5 + text), reduce the scale factor and center */
|
128
|
+
i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
|
129
|
+
if (bc->height < i * scalef ) {
|
130
|
+
double scaleg = ((double)bc->height) / i;
|
131
|
+
int wid = bc->width * scaleg / scalef;
|
132
|
+
bc->xoff += (bc->width - wid)/2;
|
133
|
+
bc->width = wid;
|
134
|
+
scalef = scaleg;
|
135
|
+
}
|
136
|
+
#endif
|
137
|
+
|
138
|
+
/*
|
139
|
+
* Ok, then deal with actual ps (eps) output
|
140
|
+
*/
|
141
|
+
|
142
|
+
if (!(bc->flags & BARCODE_OUT_NOHEADERS)) { /* spit a header first */
|
143
|
+
if (bc->flags & BARCODE_OUT_EPS)
|
144
|
+
fprintf(f, "%%!PS-Adobe-2.0 EPSF-1.2\n");
|
145
|
+
else
|
146
|
+
fprintf(f, "%%!PS-Adobe-2.0\n");
|
147
|
+
fprintf(f, "%%%%Creator: libbarcode\n");
|
148
|
+
if (bc->flags & BARCODE_OUT_EPS) {
|
149
|
+
fprintf(f, "%%%%BoundingBox: %i %i %i %i\n",
|
150
|
+
bc->xoff,
|
151
|
+
bc->yoff,
|
152
|
+
bc->xoff + bc->width + 2* bc->margin,
|
153
|
+
bc->yoff + bc->height + 2* bc->margin);
|
154
|
+
}
|
155
|
+
fprintf(f, "%%%%EndComments\n");
|
156
|
+
if (bc->flags & BARCODE_OUT_PS) {
|
157
|
+
fprintf(f, "%%%%EndProlog\n\n");
|
158
|
+
fprintf(f, "%%%%Page: 1 1\n\n");
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
/* Print some informative comments */
|
163
|
+
for (i=0; bc->ascii[i]; i++)
|
164
|
+
if (bc->ascii[i] < ' ')
|
165
|
+
printable = 0;
|
166
|
+
|
167
|
+
fprintf(f,"%% Printing barcode for \"%s\", scaled %5.2f",
|
168
|
+
printable ? bc->ascii : "<unprintable string>", scalef);
|
169
|
+
if (bc->encoding)
|
170
|
+
fprintf(f,", encoded using \"%s\"",bc->encoding);
|
171
|
+
fprintf(f, "\n");
|
172
|
+
fprintf(f,"%% The space/bar succession is represented "
|
173
|
+
"by the following widths (space first):\n"
|
174
|
+
"%% ");
|
175
|
+
for (i=0; i<strlen(bc->partial); i++) {
|
176
|
+
unsigned char c = bc->partial[i];
|
177
|
+
if (isdigit(c)) putc(c, f);
|
178
|
+
if (islower(c)) putc(c-'a'+'1', f);
|
179
|
+
if (isupper(c)) putc(c-'A'+'1', f);
|
180
|
+
}
|
181
|
+
/* open array for "forall" */
|
182
|
+
fprintf(f, "\n[\n%% height xpos ypos width"
|
183
|
+
" height xpos ypos width\n");
|
184
|
+
|
185
|
+
xpos = bc->margin + (bc->partial[0]-'0') * scalef;
|
186
|
+
for (ptr = bc->partial+1, i=1; *ptr; ptr++, i++) {
|
187
|
+
/* special cases: '+' and '-' */
|
188
|
+
if (*ptr == '+' || *ptr == '-') {
|
189
|
+
mode = *ptr; /* don't count it */ i++; continue;
|
190
|
+
}
|
191
|
+
/* j is the width of this bar/space */
|
192
|
+
if (isdigit (*ptr)) j = *ptr-'0';
|
193
|
+
else j = *ptr-'a'+1;
|
194
|
+
if (i%2) { /* bar */
|
195
|
+
x0 = bc->xoff + xpos + (j*scalef)/2;
|
196
|
+
y0 = bc->yoff + bc->margin;
|
197
|
+
yr = bc->height;
|
198
|
+
if (!(bc->flags & BARCODE_NO_ASCII)) { /* leave space for text */
|
199
|
+
if (mode == '-') {
|
200
|
+
/* text below bars: 10 points or five points */
|
201
|
+
y0 += (isdigit(*ptr) ? 10 : 5) * scalef;
|
202
|
+
yr -= (isdigit(*ptr) ? 10 : 5) * scalef;
|
203
|
+
} else { /* '+' */
|
204
|
+
/* text above bars: 10 or 0 from bottom, and 10 from top */
|
205
|
+
y0 += (isdigit(*ptr) ? 10 : 0) * scalef;
|
206
|
+
yr -= (isdigit(*ptr) ? 20 : 10) * scalef;
|
207
|
+
}
|
208
|
+
}
|
209
|
+
/* Define an array and then use "forall" (Hans Schou) */
|
210
|
+
fprintf(f," [%5.2f %6.2f %6.2f %5.2f]%s",
|
211
|
+
yr, x0, y0, (j * scalef) - SHRINK_AMOUNT,
|
212
|
+
i%4 == 1 ? " " : "\n");
|
213
|
+
}
|
214
|
+
xpos += j * scalef;
|
215
|
+
}
|
216
|
+
fprintf(f,"\n]\t{ {} forall setlinewidth moveto 0 exch rlineto stroke} "
|
217
|
+
"bind forall\n");
|
218
|
+
|
219
|
+
/* Then, the text */
|
220
|
+
|
221
|
+
mode = '-'; /* reinstantiate default */
|
222
|
+
if (!(bc->flags & BARCODE_NO_ASCII)) {
|
223
|
+
fprintf(f, "[\n%% char xpos ypos fontsize\n");
|
224
|
+
k=0; /* k is the "previous font size" */
|
225
|
+
for (ptr = bc->textinfo; ptr; ptr = strchr(ptr, ' ')) {
|
226
|
+
while (*ptr == ' ') ptr++;
|
227
|
+
if (!*ptr) break;
|
228
|
+
if (*ptr == '+' || *ptr == '-') {
|
229
|
+
mode = *ptr; continue;
|
230
|
+
}
|
231
|
+
if (sscanf(ptr, "%lf:%lf:%c", &f1, &f2, &c) != 3) {
|
232
|
+
fprintf(stderr, "barcode: impossible data: %s\n", ptr);
|
233
|
+
continue;
|
234
|
+
}
|
235
|
+
|
236
|
+
fprintf(f, " [(");
|
237
|
+
/* Both the backslash and the two parens are special */
|
238
|
+
if (c=='\\' || c==')' || c=='(')
|
239
|
+
fprintf(f, "\\%c) ", c);
|
240
|
+
else
|
241
|
+
fprintf(f, "%c) ", c);
|
242
|
+
fprintf(f, "%6.2f %6.2f %5.2f]\n",
|
243
|
+
bc->xoff + f1 * scalef + bc->margin,
|
244
|
+
mode == '-'
|
245
|
+
? (double)bc->yoff + bc->margin
|
246
|
+
: (double)bc->yoff + bc->margin+bc->height - 8*scalef,
|
247
|
+
fsav == f2 ? 0.0 : f2 * scalef);
|
248
|
+
fsav = f2;
|
249
|
+
}
|
250
|
+
fprintf(f,"] { {} forall dup 0.00 ne {\n\t"
|
251
|
+
"/Helvetica findfont exch scalefont setfont\n"
|
252
|
+
" } {pop} ifelse\n"
|
253
|
+
" moveto show} bind forall\n");
|
254
|
+
|
255
|
+
|
256
|
+
}
|
257
|
+
|
258
|
+
fprintf(f,"%% End barcode for \"%s\"\n\n",
|
259
|
+
printable ? bc->ascii : "<unprintable string>");
|
260
|
+
|
261
|
+
if (!(bc->flags & BARCODE_OUT_NOHEADERS)) {
|
262
|
+
if (bc->flags & BARCODE_OUT_PS) {
|
263
|
+
fprintf(f,"showpage\n");
|
264
|
+
fprintf(f, "%%%%Trailer\n\n");
|
265
|
+
}
|
266
|
+
}
|
267
|
+
return 0;
|
268
|
+
}
|
269
|
+
|
270
|
+
|
271
|
+
|
272
|
+
|