]> git.sur5r.net Git - glabels/blob - barcode-0.98/pcl.c
Imported Upstream version 2.2.8
[glabels] / barcode-0.98 / pcl.c
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 }