Codebase list ptouch-driver / 707f16d
* Initial Debian release (Closes: #555892). * Start from the Ubuntu packaging, thanks! * Put under Debian Printing Team umbrella, with myself as uploader. * Convert to 3.0 (quilt) source format. * Add the Ubuntu apport hook conditionally * Add VCS-* fields. * Use dh-autoreconf to have a cleaner build. * debian/watch: add. * Use dh_pyppd trough the --with stanza. * Drop explicit pyppd depends, they come trough dh_pyppd. * Add DEP-3 headers to all patches. * Rewrite debian/copyright DEP-5-style. * Enable parallel building, including specifying the number of threads for the foomatic compilation. * Drop unneeded dh_auto_test override. * Slightly rewrite the "long" description. * Bump Standards-Version to 3.9.2 without changes needed. Package Import Robot 12 years ago
19 changed file(s) with 2058 addition(s) and 122 deletion(s). Raw diff Collapse all Expand all
0 foomatic-data-fixes.patch
1 send-esc-i-A.patch
0 <!--
1 Copyright (c) 2006 Arne John Glenstrup <panic@itu.dk>
2
3 This file is part of ptouch-driver.
4
5 ptouch-driver is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at
8 your option) any later version.
9
10 ptouch-driver is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with ptouch-driver; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18 USA
19 -->
20 <driver id="driver/ptouch">
21 <name>ptouch</name>
22 <pcdriver>PT</pcdriver>
23 <url></url>
24 <execution>
25 <filter />
26 <prototype>gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -sDEVICE=cups %A%Z -sOutputFile=- - | rastertoptch dummyjob dummyuser dummytitle 1 '%B'</prototype>
27 </execution>
28 <comments>
29 <en>
30 </en>
31 </comments>
32 <printers>
33 <printer>
34 <id>printer/Brother-QL-500</id><!-- Brother P-touch QL-500 -->
35 </printer>
36 <printer>
37 <id>printer/Brother-QL-550</id><!-- Brother P-touch QL-550 -->
38 </printer>
39 <printer>
40 <id>printer/Brother-QL-650TD</id><!-- Brother P-touch QL-650TD -->
41 </printer>
42 <printer>
43 <id>printer/Brother-PT-PC</id><!-- Brother P-touch PT-PC -->
44 <margins>
45 <general>
46 <unit>mm</unit>
47 </general>
48 <exception PageSize='6x100mm'>
49 <left>1.3067</left><right>1.3067</right>
50 </exception>
51 <exception PageSize='9x100mm'>
52 <left>2.8067</left><right>2.8067</right>
53 </exception>
54 <exception PageSize='12x100mm'>
55 <left>4.3067</left><right>4.3067</right>
56 </exception>
57 <exception PageSize='18x100mm'>
58 <left>7.3067</left><right>7.3067</right>
59 </exception>
60 <exception PageSize='24x100mm'>
61 <left>10.3067</left><right>10.3067</right>
62 </exception>
63 </margins>
64 </printer>
65 <printer>
66 <id>printer/Brother-PT-18R</id><!-- Brother P-touch PT-18R -->
67 </printer>
68 <printer>
69 <id>printer/Brother-PT-550A</id><!-- Brother P-touch PT-550A -->
70 </printer>
71 <printer>
72 <id>printer/Brother-PT-1500PC</id><!-- Brother P-touch PT-1500PC -->
73 </printer>
74 <printer>
75 <id>printer/Brother-PT-1950VP</id><!-- Brother P-touch PT-1950VP -->
76 </printer>
77 <printer>
78 <id>printer/Brother-PT-1950</id><!-- Brother P-touch PT-1950 -->
79 </printer>
80 <printer>
81 <id>printer/Brother-PT-1960</id><!-- Brother P-touch PT-1960 -->
82 </printer>
83 <printer>
84 <id>printer/Brother-PT-2420PC</id><!-- Brother P-touch PT-2420PC -->
85 </printer>
86 <printer>
87 <id>printer/Brother-PT-2450DX</id><!-- Brother P-touch PT-2450DX -->
88 </printer>
89 <printer>
90 <id>printer/Brother-PT-2500PC</id><!-- Brother P-touch PT-2500PC -->
91 </printer>
92 <printer>
93 <id>printer/Brother-PT-2600</id><!-- Brother P-touch PT-2600 -->
94 </printer>
95 <printer>
96 <id>printer/Brother-PT-2610</id><!-- Brother P-touch PT-2610 -->
97 </printer>
98 <printer>
99 <id>printer/Brother-PT-3600</id><!-- Brother P-touch PT-3600 -->
100 </printer>
101 <printer>
102 <id>printer/Brother-PT-9200DX</id><!-- Brother P-touch PT-9200DX -->
103 </printer>
104 <printer>
105 <id>printer/Brother-PT-9200PC</id><!-- Brother P-touch PT-9200PC -->
106 </printer>
107 <printer>
108 <id>printer/Brother-PT-9400</id><!-- Brother P-touch PT-9400 -->
109 </printer>
110 <printer>
111 <id>printer/Brother-PT-9500PC</id><!-- Brother P-touch PT-9500PC -->
112 </printer>
113 <printer>
114 <id>printer/Brother-PT-9600</id><!-- Brother P-touch PT-9600 -->
115 </printer>
116 </printers>
117 </driver>
118
0 <!--
1 Copyright (c) 2006 Arne John Glenstrup <panic@itu.dk>
2
3 This file is part of ptouch-driver.
4
5 ptouch-driver is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at
8 your option) any later version.
9
10 ptouch-driver is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with ptouch-driver; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18 USA
19 -->
20 <printer id="printer/Brother-QL-550">
21 <make>Brother</make>
22 <model>QL-550</model>
23 <pcmodel>BRQ550</pcmodel>
24 <mechanism>
25 <thermal/>
26 <!--not "color"-->
27 <resolution>
28 <dpi>
29 <x>300</x>
30 <y>300</y>
31 </dpi>
32 </resolution>
33 <consumables>
34 <comments>
35 <en>
36 Special &quot;DK&quot; adhesive labels or adhesive tape thermal paper.
37 No ink or ribbons needed.
38 Die Cut Standard Address Labels 29mm x 90mm, 400 Labels - $7.99
39 Die Cut Shipping Labels 62mm x 100mm, 300 Labels - $13.99
40 Die Cut File Folder Labels 17mm x 87mm, 300 labels - $6.99
41 Multipurpose Die Cut Labels 17mm x 54mm, 400 Labels - $7.99
42 CD/DVD Film Labels 58mm x 58mm, 100 Labels - $14.99
43 Large Die Cut Address Labels 38mm x 90mm, 400 Labels/Roll - $10.99
44 Small Address Label 29mm x 62mm, 800 Labels - $13.99
45 Clear Continuous Film Roll 62mm x 15.24m, Clear - $44.99
46 White Continuous Film Roll 62mm x 30.48m, White - $13.99
47 White Continuous Film Roll 29mm x 30.48m, White - $8.99
48 White Continuous Film Roll 29mm x 15.24m, White - $15.99
49 White Continuous Film Roll 62mm x 15.24m, White - $30.99
50 White Continuous Film Roll 12mm x 30.48m, White - $7.99
51 Yellow Continuous Film Roll 62mm x 15.24m, Yellow - $44.99
52 Cutter Unit, 2 pcs
53 Cleaning Sheets, 10 sheets
54 </en>
55 </comments>
56 <partno>DK-11201</partno>
57 <partno>DK-11202</partno>
58 <partno>DK-11203</partno>
59 <partno>DK-11204</partno>
60 <partno>DK-11207</partno>
61 <partno>DK-11208</partno>
62 <partno>DK-11209</partno>
63 <partno>DK-22113</partno>
64 <partno>DK-22205</partno>
65 <partno>DK-22210</partno>
66 <partno>DK-22211</partno>
67 <partno>DK-22212</partno>
68 <partno>DK-22214</partno>
69 <partno>DK-22606</partno>
70 <partno>DKBU99</partno>
71 <partno>DKCL99</partno>
72 </consumables>
73 </mechanism>
74 <url>http://www.brother.co.uk/cms.cfm/s_page/55570/s_level/17510/s_product/QL550</url>
75 <lang>
76 <proprietary />
77 </lang>
78 <autodetect>
79 <general>
80 <ieee1284>MFG:Brother;CMD:PT-CBP;MDL:QL-550;CLS:PRINTER;</ieee1284>
81 <commandset>PT-CBP</commandset>
82 <description>Brother QL-550</description>
83 <manufacturer>Brother</manufacturer>
84 <model>QL-550</model>
85 </general>
86 </autodetect>
87 <functionality>B</functionality>
88 <driver>ptouch</driver>
89 <unverified />
90 <!--no "contrib_url"-->
91 <comments>
92 <en>
93 Prints 3 inches per second.
94 </en>
95 </comments>
96 </printer>
0 /* rastertoptch is a filter to convert CUPS raster data into a Brother
1 * P-touch label printer command byte stream.
2 *
3 * Copyright (c) 2006 Arne John Glenstrup <panic@itu.dk>
4 *
5 * This file is part of ptouch-driver
6 *
7 * ptouch-driver 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 * ptouch-driver 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 ptouch-driver; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 *
22 * Please note: This software is not in any way related to Brother
23 * Industries, Ltd., except that it is intended for use with their
24 * products. Any comments to this software should NOT be directed to
25 * Brother Industries, Ltd.
26 */
27
28 /** @file
29 * This filter processes CUPS raster data, converting it into a byte
30 * stream on stdout suitable for sending directly to a label printer
31 * of the Brother P-touch family.
32 *
33 * @version 1.2
34 * @author Arne John Glenstrup <panic@itu.dk>
35 * @date 2006
36
37 * <h2>Invocation</h2>
38 * The filter is invoked thus:
39 *
40 * rastertoptch job user title copies options [filename]
41 *
42 * @param printer The name of the printer queue (ignored)
43 * @param job The numeric job ID (ignored)
44 * @param user The string from the originating-user-name (ignored)
45 * @param title The string from the job-name attribute (ignored)
46 * @param copies The number of copies to be printed (ignored)
47 * @param options String representations of the job template
48 * parameters, separated by spaces. Boolean attributes
49 * are provided as "name" for true values and "noname"
50 * for false values. All other attributes are provided
51 * as "name=value" for single-valued attributes and
52 * "name=value1,value2,...,valueN" for set attributes
53 * @param filename The request file (if omitted, read from stdin)
54 *
55 * Available options (default values in [brackets]):
56 *
57 * @param PixelXfer=ULP|RLE|BIP Use uncompressed line printing (ULP),
58 * run-length encoding (RLE) or bit
59 * image printing (BIP) when emitting
60 * pixel data [ULP]
61 * @param PrintQuality=High|Fast Use high quality or fast printing [High]
62 * @param HalfCut Perform half-cut (crack & peel) when
63 * cutting [noHalfCut]
64 * @param BytesPerLine=N Emit N bytes per line [90]
65 * @param Align=Right|Center Pixel data alignment on tape [Right]
66 * @param PrintDensity=1|...|5 Print density level: 1=light, 5=dark
67 * @param ConcatPages Output all pages in one page [noConcatPages]
68 * @param RLEMemMax Maximum memory used for RLE buffer [1000000]
69 * @param SoftwareMirror Make the filter mirror pixel data
70 * if MirrorPrint is requested [noSoftwareMirror]
71 * @param LabelPreamble Emit preamble containing print quality,
72 * roll/label type, tape width, label height,
73 * and pixel lines [noLabelPreamble]
74 * @param Debug Emit diagnostic output to stderr [noDebug]
75 * (only if compiled with DEBUG set)
76 *
77 * Information about media type, resolution, mirror print, negative
78 * print, cut media, advance distance (feed) is extracted from the
79 * CUPS raster page headers given in the input stream. The MediaType
80 * page header field can be either "roll" or "labels" for continuous
81 * tape or pre-cut labels, respectively.
82 *
83 * LabelPreamble should usually not be used for the PT series printers.
84 *
85 * <h2>Output</h2>
86 * Each invocation of this filter is one job, containing a number of
87 * pages, each page containing a number of lines, each line consisting
88 * of a number of pixel bytes.
89 *
90 * Output consists of job-related printer initialisation commands,
91 * followed by a number of pages, each page consisting of page-related
92 * commands, followed by raster line data. Each page is followed by a
93 * finish page or (after the final page) finish job command.
94 *
95 * The following printer command language, printer, and tape
96 * information has been deduced from many sources, but is not official
97 * Brother documentation and may thus contain errors. Please send any
98 * corrections based on actual experience with these printers to the
99 * maintainer.
100 *
101 * <h3>Job-related commands</h3>
102 * <table>
103 * <tr><th>Byte sequence</th><th>Function</th><th>Description</th></tr>
104 * <tr><td>ESC @ (1b 40)</td>
105 <td>Initialise</td><td>Clear print buffer</td></tr>
106 * <tr><td>ESC i D # (1b 69 44 ##)
107 * <td>Set print density</td>
108 * <td>bit 0-3: 0=no change, 1-5=density level</td></tr>
109 * <tr><td>ESC i K # (1b 69 4b ##)
110 * <td>Set half cut</td>
111 * <td>bit 2: 0=full cut, 1=half cut</td></tr>
112 * <tr><td>ESC i R ## (1b 69 52 ##)</td>
113 * <td>Set transfer mode</td>
114 * <td>##: ?: 1=?</td></tr>
115 * <tr><td>M ## (4d ##)</td>
116 * <td>Set compression</td>
117 * <td>##: Compression type: 2=RLE</td></tr>
118 * </table>
119 *
120 * <h3>Page-related commands</h3>
121 * <table>
122 * <tr><th>Byte sequence</th><th>Function</th><th>Description</th></tr>
123 * <tr><td>ESC i c #1 #2 #3 NUL #4 <br>(1b 63 #1 #2 #3 00 #4)
124 * <td>Set width & resolution</td>
125 * <td>360x360DPI: #1 #2 #4 = 0x84 0x00 0x00<br>
126 * 360x720DPI: #1 #2 #4 = 0x86 0x09 0x01<br>
127 * #3: Tape width in mm</td></tr>
128 * <tr><td>ESC i M # <br>(1b 69 4d ##)</td>
129 * <td>Set mode</td>
130 * <td>bit 0-4: Feed amount (default=large): 0-7=none, 8-11=small,
131 * 12-25=medium, 26-31=large<br>
132 * bit 6: Auto cut/cut mark (default=on): 0=off, 1=on<br>
133 * bit 7: Mirror print (default=off): 0=off, 1=on.
134 * (note that it seems that QL devices do not reverse the
135 * data stream themselves, but rely on the driver doing
136 * it!)</td></tr>
137 * <tr><td>ESC i z #1 #2 #3 #4 #5 #6 NUL NUL NUL NUL<br>
138 * (1b 69 7a #1 #2 #3 #4 #5 #6 00 00 00 00)</td>
139 * <td>Set media & quality</td>
140 * <td>#1, bit 6: Print quality: 0=fast, 1=high<br>
141 * #2, bit 0: Media type: 0=continuous roll,
142 * 1=pre-cut labels<br>
143 * #3: Tape width in mm<br>
144 * #4: Label height in mm (0 for continuous roll)<br>
145 * #5 #6: Page consists of N=#5+256*#6 pixel lines</td></tr>
146 * <tr><td>ESC i d #1 #2 <br>(1b 69 64 #1 #2)</td>
147 * <td>Set margin</td>
148 * <td>Set size of right(?) margin to N=#1+256*#2 pixels</td></tr>
149 * <tr><td>FF (0c)</td>
150 * <td>Form feed</td>
151 * <td>Print buffer data without ejecting.</td></tr>
152 * <tr><td>SUB (1a)</td>
153 * <td>Eject</td>
154 * <td>Print buffer data and ejects.</td></tr>
155 * </table>
156 *
157 * <h3>Line-related commands</h3>
158 * <table>
159 * <tr><th>Byte sequence</th><th>Function</th><th>Description</th></tr>
160 * <tr><td>G #1 #2 ...data... <br>(47 #1 #2 ...data...)</td>
161 * <td>Send raster line</td>
162 * <td>data consists of
163 * N=#1+256*#2 bytes of RLE compressed raster data.
164 * </td></tr>
165 * <tr><td>Z (5a)</td>
166 * <td>Advance tape</td><td>Print 1 empty line</td></tr>
167 * <tr><td>g #1 #2 ...data... <br>(67 #1 #2 ...data...)</td>
168 * <td>Send raster line</td>
169 * <td>data consists of
170 * N=#2 bytes of uncompressed raster data.</td></tr>
171 * <tr><td>ESC * ' #1 #2 ...data... <br>(1b 2a 27 #1 #2 ...data...)</td>
172 * <td>Bit image printing (BIP)</td>
173 * <td>Print N=#1+256*#2 lines of 24 pixels; data consists of 3*N
174 * bytes</td></tr>
175 * </table>
176 *
177 * <h3>Compressed-data-related commands (RLE)</h3>
178 * <table>
179 * <tr><th>Byte sequence</th><th>Function</th><th>Description</th></tr>
180 * <tr><td>#1 ...data...</td>
181 * <td>#1 >= 0: Print uncompressed</td>
182 * <td>data consists of 1+#1 uncompressed bytes</td></tr>
183 * <tr><td>#1 #2</td>
184 * <td>#1 < 0: Print compressed</td>
185 * <td>#2 should be printed 1-#1 times</td></tr>
186 * </table>
187 * #1 is represented as a 2-complement signed integer.
188 *
189 * <h2>Printer model characteristics</h2>
190 * The following table lists for each model what kind of cutter it has
191 * (manual, auto, half cut), what kind of pixel data transfer mode it
192 * requires, its resolution, number of print head pixels, number of
193 * bytes of pixel data that must be transmitted per line (regardless
194 * of actual tape width!), and what kinds of tape it can take.
195 *
196 * For PC models, pixel data must be centered, so narrow tapes require
197 * padding raster data with zero bits on each side. For QL models,
198 * labels are left-aligned, so pixel data must be right aligned, so
199 * narrow tapes require padding raster data with zero bits at the end.
200 *
201 * For PC-PT, only the central 24 pixels (= 3,4mm!) can be used for
202 * pixel-based graphics. It might be possible to print several strips
203 * of 24 pixels side-by side by issuing CR and line-positioning
204 * commands. That is currently not supported, let alone attempted,
205 * with this driver.
206 *
207 * <table>
208 * <tr><th>Model <th>Cutter <th>Xfer<th>DPI<th>Pixels<th>Bytes<th>Tape
209 * <tr><td>QL-500 <td>manual <td>ULP<td>300<td>720<td>90<td>DK12-62mm
210 * <tr><td>QL-550 <td>auto <td>ULP<td>300<td>720<td>90<td>DK12-62mm
211 * <tr><td>QL-650TD <td>auto <td>ULP<td>300<td>720<td>90<td>DK12-62mm
212 * <tr><td>PT-PC <td>auto <td>BIP<td>180<td>128<td> 3<td>TZ6-24mm
213 * <tr><td>PT-18R <td>auto <td>RLE<td>180<td>128<td>16<td>TZ6-18mm
214 * <tr><td>PT-550A <td>auto <td>RLE<td>180<td>128<td>16<td>TZ6-36mm
215 * <tr><td>PT-1500PC<td>manual <td>RLE<td>180<td>112<td>14<td>TZ6-24mm
216 * <tr><td>PT-1950 <td>auto <td>RLE<td>180<td>128<td>16<td>TZ6-18mm
217 * <tr><td>PT-1950VP<td>auto <td>RLE<td>180<td>112<td>14<td>TZ6-18mm
218 * <tr><td>PT-1960 <td>auto <td>RLE<td>180<td> 96<td>12<td>TZ6-18mm
219 * <tr><td>PT-2300 <td>auto <td>RLE<td>180<td>112<td>14<td>TZ6-18mm
220 * <tr><td>PT-2420PC<td>manual <td>RLE<td>180<td>128<td>16<td>TZ6-24mm
221 * <tr><td>PT-2450DX<td>auto <td>RLE<td>180<td>128<td>16<td>TZ6-24mm
222 * <tr><td>PT-2500PC<td>auto <td>RLE<td>180<td>128<td>16<td>TZ6-24mm
223 * <tr><td>PT-2600 <td>auto <td>RLE<td>180<td>128<td>16<td>TZ,AV6-24mm
224 * <tr><td>PT-2610 <td>auto <td>RLE<td>180<td>128<td>16<td>TZ,AV6-24mm
225 * <tr><td>PT-3600 <td>auto/half<td>RLE<td>360<td>384<td>48<td>TZ,AV6-36mm
226 * <tr><td>PT-9200DX<td>auto/half<td>RLE<td>360<td>384<td>48<td>TZ6-36mm
227 * <tr><td>PT-9200PC<td>auto/half<td>RLE<td>360<td>384<td>48<td>TZ6-36mm
228 * <tr><td>PT-9400 <td>auto/half<td>RLE<td>360<td>384<td>48<td>TZ6-36mm
229 * <tr><td>PT-9500PC<td>auto/half<td>RLE<td>360<br>
230 360x720<td>384<td>48<td>TZ,AV6-36mm
231 * <tr><td>PT-9600 <td>auto/half<td>RLE<td>360<td>384<td>48<td>TZ,AV6-36mm
232 * </table>
233 *
234 * <h2>Tape characteristics</h2>
235 * <table>
236 * <tr><th>Tape width
237 * <th colspan=2>Print area <th>Margins</th><th>DPI</th></tr>
238 * <tr><td>62mm<td>61.0mm<td>720pixels</td><td>0.5mm</td><td>300</td></tr>
239 * <tr><td>36mm<td>27.1mm<td>384pixels</td><td>4.5mm</td><td>360</td></tr>
240 * <tr><td>24mm<td>18.0mm<td>128pixels</td><td>3mm</td><td>180</td></tr>
241 * <tr><td>18mm<td>12.0mm<td> 85pixels</td><td>3mm</td><td>180</td></tr>
242 * <tr><td>12mm<td> 8.0mm<td> 57pixels</td><td>2mm</td><td>180</td></tr>
243 * <tr><td> 9mm<td> 6.9mm<td> 49pixels</td><td>1mm</td><td>180</td></tr>
244 * <tr><td> 6mm<td> 3.9mm<td> 28pixels</td><td>1mm</td><td>180</td></tr>
245 * </table>
246 *
247 * <h2>Notes</h2>
248 * - Pixels bytes sent are printed from right to left, with bit 7
249 * rightmost!
250 * - Bit image printing (BIP) using "ESC * ' #1 #2 ...data..."
251 * probably only works for the PT-PC model.
252 * - QL Printer documentation might state that the print area is less
253 * than 61mm, which is probably to ensure that printed pixels stay
254 * within the tape even if it is not precisely positioned. The
255 * print head really IS 720 pixels.
256 */
257 /** Default pixel transfer method */
258 #define PIXEL_XFER_DEFAULT RLE
259 /** Default print quality */
260 #define PRINT_QUALITY_HIGH_DEFAULT true
261 /** Default half cut mode */
262 #define HALF_CUT_DEFAULT false
263 /** Maximum number of bytes per line */
264 #define BYTES_PER_LINE_MAX 255 /* cf. ULP_emit_line */
265 /** Default number of bytes per line */
266 #define BYTES_PER_LINE_DEFAULT 90
267 /** Default pixel data alignment on narrow tapes */
268 #define ALIGN_DEFAULT RIGHT
269 /** Maximum print density value */
270 #define PRINT_DENSITY_MAX 5
271 /** Default print density value (1: light, ..., 5:dark, 0: no change) */
272 #define PRINT_DENSITY_DEFAULT 0
273 /** Transfer mode default ??? (-1 = don't set) */
274 #define TRANSFER_MODE_DEFAULT -1
275 /** Driver pixel data mirroring default */
276 #define SOFTWARE_MIRROR_DEFAULT false
277 /** Label preamble emitting default */
278 #define LABEL_PREAMBLE_DEFAULT false
279 /** Interlabel margin removal default */
280 #define CONCAT_PAGES_DEFAULT false
281 /** RLE buffer maximum memory usage */
282 #define RLE_ALLOC_MAX_DEFAULT 1000000
283 /** Mirror printing default */
284 #define MIRROR_DEFAULT false
285 /** Negative printing default */
286 #define NEGATIVE_DEFAULT false
287 /** Cut media mode default */
288 #define CUT_MEDIA_DEFAULT CUPS_CUT_NONE
289 /** Roll fed media default */
290 #define ROLL_FED_MEDIA_DEFAULT true
291 /** Device resolution default in DPI */
292 #define RESOLUTION_DEFAULT { 300, 300 }
293 /** Page size default in PostScript points */
294 #define PAGE_SIZE_DEFAULT { 176, 142 } /* 62x50mm */
295 /** Image size default in pixels */
296 #define IMAGE_HEIGHT_DEFAULT 0
297 /** Feed amount default */
298 #define FEED_DEFAULT 0
299 /** When to perform feed default */
300 #define PERFORM_FEED_DEFAULT CUPS_ADVANCE_NONE
301
302 #include <config.h>
303 #include <stdio.h>
304 #include <unistd.h>
305 #include <limits.h>
306 #include <stdlib.h>
307 #include <string.h>
308 #include <errno.h>
309 #include <fcntl.h>
310 #include <signal.h>
311 #include <math.h>
312 #include <cups/raster.h>
313 #include <cups/cups.h>
314
315 #if STDC_HEADERS
316 # include <string.h>
317 #else
318 # if !HAVE_MEMCPY
319 # define memcpy(d, s, n) bcopy ((s), (d), (n))
320 # endif
321 #endif
322 #if HAVE_STDBOOL_H
323 # include <stdbool.h>
324 #else
325 # if ! HAVE__BOOL
326 # ifdef __cplusplus
327 typedef bool _Bool;
328 # else
329 typedef unsigned char _Bool;
330 # endif
331 # endif
332 # define bool _Bool
333 # define false 0
334 # define true 1
335 # define __bool_true_false_are_defined 1
336 #endif
337
338
339
340 #ifdef DEBUG
341 #include <sys/times.h>
342 /** Debug flag */
343 int debug = 0;
344 /** Number of emitted lines */
345 unsigned emitted_lines = 0;
346 #endif
347
348 /** Length of a PostScript point in mm */
349 #define MM_PER_PT (25.4 / 72.0)
350 /** Printer code: Eject */
351 #define PTC_EJECT 0x1a
352 /** Printer code: Form feed */
353 #define PTC_FORMFEED 0x0c
354
355 /** ASCII escape value */
356 #define ESC 0x1b
357
358 /**
359 * Pixel transfer mode type.
360 */
361 typedef enum {
362 ULP, /**< Uncompressed line printing */
363 RLE, /**< Run-length encoding */
364 BIP, /**< Bit image printing */
365 } xfer_t;
366
367 /**
368 * Pixel data alignment type.
369 */
370 typedef enum {RIGHT, CENTER} align_t;
371
372 /** Flag signalling whether any errors were encountered. */
373 int error_occurred;
374
375 /** CUPS Raster line buffer. */
376 unsigned char* buffer;
377 /** Buffer holding line data to emit to the printer. */
378 unsigned char* emit_line_buffer;
379 /** Buffer holding RLE line data to emit to the printer. */
380 unsigned char* rle_buffer = NULL;
381 /** Pointer to first free pos in rle_buffer. */
382 unsigned char* rle_buffer_next = NULL;
383 /** Size of rle_buffer. */
384 unsigned long rle_alloced = 0;
385 /** Number of empty lines (input data only zeros) waiting to be stored */
386 int empty_lines = 0;
387 /** Number of pixel lines waiting to be emitted. */
388 unsigned lines_waiting = 0;
389 /** Threshold for flushing waiting lines to printer. */
390 unsigned max_lines_waiting = INT_MAX;
391
392 /** Macro for obtaining integer option values. */
393 #define OBTAIN_INT_OPTION(name, var, min, max) \
394 cups_option \
395 = cupsGetOption (name, num_options, cups_options); \
396 if (cups_option) { \
397 errno = 0; \
398 char* rest; \
399 long int var = strtol (cups_option, &rest, 0); \
400 if (errno || *rest != '\0' || rest == cups_option \
401 || var < min || var > max) { \
402 fprintf (stderr, "ERROR: " name " '%s', " \
403 "must be an integer N, where %ld <= N <= %ld\n", \
404 cups_option, (long) min, (long) max); \
405 error_occurred = 1; \
406 } else \
407 options.var = var; \
408 }
409
410 /** Macro for obtaining boolean option values. */
411 #define OBTAIN_BOOL_OPTION(name, var) \
412 cups_option \
413 = cupsGetOption (name, num_options, cups_options); \
414 if (cups_option) options.var = true; \
415 cups_option \
416 = cupsGetOption ("no"name, num_options, cups_options); \
417 if (cups_option) options.var = false; \
418
419 /**
420 * Struct type for holding all the job options.
421 */
422 typedef struct {
423 xfer_t pixel_xfer; /**< pixel transfer mode */
424 cups_bool_t print_quality_high; /**< print quality is high */
425 bool half_cut; /**< half cut */
426 int bytes_per_line; /**< bytes per line (print head width) */
427 align_t align; /**< pixel data alignment */
428 int software_mirror; /**< mirror pixel data if mirror printing */
429 int print_density; /**< printing density (0=don't change) */
430 int xfer_mode; /**< transfer mode ??? */
431 int label_preamble; /**< emit ESC i z ... */
432 bool concat_pages; /**< remove interlabel margins */
433 unsigned long rle_alloc_max; /**< max bytes used for rle_buffer */
434 } job_options_t;
435
436 /**
437 * Struct type for holding current page options.
438 */
439 typedef struct {
440 cups_cut_t cut_media; /**< cut media mode */
441 cups_bool_t mirror; /**< mirror printing */
442 bool roll_fed_media; /**< continuous (not labels) roll media */
443 unsigned resolution [2]; /**< horiz & vertical resolution in DPI */
444 unsigned page_size [2]; /**< width & height of page in points */
445 unsigned image_height; /**< height of page image in pixels */
446 unsigned feed; /**< feed size in points */
447 cups_adv_t perform_feed; /**< When to feed */
448 } page_options_t;
449
450 /**
451 * Parse options given in command line argument 5.
452 * @param argc number of command line arguments plus one
453 * @param argv command line arguments
454 * @return options, where each option set to its default value if
455 * not specified in argv [5]
456 */
457 job_options_t
458 parse_options (int argc, const char* argv []) {
459 job_options_t options = {
460 PIXEL_XFER_DEFAULT,
461 PRINT_QUALITY_HIGH_DEFAULT,
462 HALF_CUT_DEFAULT,
463 BYTES_PER_LINE_DEFAULT,
464 ALIGN_DEFAULT,
465 SOFTWARE_MIRROR_DEFAULT,
466 PRINT_DENSITY_DEFAULT,
467 TRANSFER_MODE_DEFAULT,
468 LABEL_PREAMBLE_DEFAULT,
469 CONCAT_PAGES_DEFAULT,
470 RLE_ALLOC_MAX_DEFAULT,
471 };
472 if (argc < 6) return options;
473 int num_options = 0;
474 cups_option_t* cups_options = NULL;
475 num_options
476 = cupsParseOptions (argv [5], num_options, &cups_options);
477 const char* cups_option
478 = cupsGetOption ("PixelXfer", num_options, cups_options);
479 if (cups_option) {
480 if (strcasecmp (cups_option, "ULP") == 0)
481 options.pixel_xfer = ULP;
482 else if (strcasecmp (cups_option, "RLE") == 0)
483 options.pixel_xfer = RLE;
484 else if (strcasecmp (cups_option, "BIP") == 0)
485 options.pixel_xfer = BIP;
486 else {
487 fprintf (stderr, "ERROR: Unknown PicelXfer '%s', "
488 "must be RLE, BIP or ULP\n", cups_option);
489 error_occurred = 1;
490 }
491 }
492 cups_option
493 = cupsGetOption ("PrintQuality", num_options, cups_options);
494 if (cups_option) {
495 if (strcasecmp (cups_option, "High") == 0)
496 options.print_quality_high = true;
497 else if (strcasecmp (cups_option, "Fast") == 0)
498 options.print_quality_high = false;
499 else {
500 fprintf (stderr, "ERROR: Unknown PrintQuality '%s', "
501 "must be High or Fast\n", cups_option);
502 error_occurred = 1;
503 }
504 }
505 OBTAIN_BOOL_OPTION ("HalfCut", half_cut);
506 OBTAIN_INT_OPTION ("BytesPerLine", bytes_per_line,
507 1, BYTES_PER_LINE_MAX);
508 cups_option
509 = cupsGetOption ("Align", num_options, cups_options);
510 if (cups_option) {
511 if (strcasecmp (cups_option, "Right") == 0)
512 options.align = RIGHT;
513 else if (strcasecmp (cups_option, "Center") == 0)
514 options.align = CENTER;
515 else {
516 fprintf (stderr, "ERROR: Unknown Align '%s', "
517 "must be Right or Center\n", cups_option);
518 error_occurred = 1;
519 }
520 }
521 OBTAIN_INT_OPTION ("PrintDensity", print_density,
522 0, PRINT_DENSITY_MAX);
523 OBTAIN_BOOL_OPTION ("ConcatPages", concat_pages);
524 OBTAIN_INT_OPTION ("RLEMemMax", rle_alloc_max, 0, LONG_MAX);
525 OBTAIN_INT_OPTION ("TransferMode", xfer_mode, 0, 255);
526 OBTAIN_BOOL_OPTION ("SoftwareMirror", software_mirror);
527 OBTAIN_BOOL_OPTION ("LabelPreamble", label_preamble);
528 /* Release memory allocated for CUPS options struct */
529 cupsFreeOptions (num_options, cups_options);
530 return options;
531 }
532
533 /**
534 * Determine input stream and open it. If there are 6 command line
535 * arguments, argv[6] is taken to be the input file name
536 * otherwise stdin is used. This funtion exits the program on error.
537 * @param argc number of command line arguments plus one
538 * @param argv command line arguments
539 * @return file descriptor for the opened input stream
540 */
541 int
542 open_input_file (int argc, const char* argv []) {
543 int fd;
544 if (argc == 7) {
545 if ((fd = open (argv[6], O_RDONLY)) < 0) {
546 perror ("ERROR: Unable to open raster file - ");
547 sleep (1);
548 exit (1);
549 }
550 } else
551 fd = 0;
552 return fd;
553 }
554
555 /**
556 * Update page_options with information found in header.
557 * @param header CUPS page header
558 * @param page_options page options to be updated
559 */
560 void
561 update_page_options (cups_page_header_t* header,
562 page_options_t* page_options) {
563 page_options->cut_media = header->CutMedia;
564 page_options->mirror = header->MirrorPrint;
565 const char* media_type = header->MediaType;
566 page_options->roll_fed_media /* Default is continuous roll */
567 = (strcasecmp ("Labels", media_type) != 0);
568 page_options->resolution [0] = header->HWResolution [0];
569 page_options->resolution [1] = header->HWResolution [1];
570 page_options->page_size [0] = header->PageSize [0];
571 page_options->page_size [1] = header->PageSize [1];
572 page_options->image_height = header->cupsHeight;
573 page_options->feed = header->AdvanceDistance;
574 page_options->perform_feed = header->AdvanceMedia;
575 }
576
577 void cancel_job (int signal);
578 /**
579 * Prepare for a new page by setting up signalling infrastructure and
580 * memory allocation.
581 * @param cups_buffer_size Required size of CUPS raster line buffer
582 * @param device_buffer_size Required size of device pixel line buffer
583 */
584 void
585 page_prepare (unsigned cups_buffer_size, unsigned device_buffer_size) {
586 /* Set up signalling to handle print job cancelling */
587 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
588 struct sigaction action;
589 #endif
590
591 #ifdef HAVE_SIGSET
592 sigset (SIGTERM, cancel_job);
593 #elif defined(HAVE_SIGACTION)
594 memset (&action, 0, sizeof (action));
595 sigemptyset (&action.sa_mask);
596 action.sa_handler = cancel_job;
597 sigaction (SIGTERM, &action, NULL);
598 #else
599 signal (SIGTERM, cancel_job);
600 #endif
601
602 /* Allocate line buffer */
603 buffer = malloc (cups_buffer_size);
604 emit_line_buffer = malloc (device_buffer_size);
605 if (!buffer || !emit_line_buffer) {
606 fprintf
607 (stderr,
608 "ERROR: Cannot allocate memory for raster line buffer\n");
609 exit (1);
610 }
611 }
612
613 /**
614 * Clean up signalling and memory after emitting a page
615 */
616 void
617 page_end () {
618 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
619 struct sigaction action;
620 #endif
621
622 #ifdef HAVE_SIGSET
623 sigset (SIGTERM, SIG_IGN);
624 #elif defined(HAVE_SIGACTION)
625 memset (&action, 0, sizeof (action));
626 sigemptyset (&action.sa_mask);
627 action.sa_handler = SIG_IGN;
628 sigaction (SIGTERM, &action, NULL);
629 #else
630 signal (SIGTERM, SIG_IGN);
631 #endif
632 /* Release line buffer memory */
633 free (buffer);
634 free (emit_line_buffer);
635 }
636
637 /**
638 * Cancel print job.
639 */
640 void
641 cancel_job (int signal) {
642 /* Emit page end & eject marker */
643 putchar (PTC_EJECT);
644 page_end ();
645 if (rle_buffer) free (rle_buffer);
646 exit (0);
647 }
648
649 /**
650 * Emit printer command codes at start of print job.
651 * This function does not emit P-touch page specific codes.
652 * @param job_options Job options
653 */
654 void
655 emit_job_cmds (job_options_t* job_options) {
656 /* Initialise printer */
657 putchar (ESC); putchar ('@');
658 /* Emit print density selection command if required */
659 int density = job_options->print_density;
660 switch (density) {
661 case 1: case 2: case 3: case 4: case 5:
662 putchar (ESC); putchar ('i'); putchar ('D'); putchar (density);
663 break;
664 default: break;
665 }
666 /* Emit transfer mode selection command if required */
667 int xfer_mode = job_options->xfer_mode;
668 if (xfer_mode >= 0 && xfer_mode < 0x100) {
669 putchar (ESC); putchar ('i'); putchar ('R'); putchar (xfer_mode);
670 }
671 /* Emit half cut selection command if required */
672 if (job_options->half_cut) {
673 putchar (ESC); putchar ('i'); putchar ('K'); putchar (0x04);
674 }
675 }
676
677 /**
678 * Emit feed, cut and mirror command codes.
679 * @param do_feed Emit codes to actually feed
680 * @param feed Feed size
681 * @param do_cut Emit codes to actually cut
682 * @param do_mirror Emit codes to mirror print
683 */
684 inline void
685 emit_feed_cut_mirror (bool do_feed, unsigned feed,
686 bool do_cut,
687 bool do_mirror) {
688 /* Determine feed nibble */
689 unsigned feed_nibble;
690 if (do_feed) {
691 feed_nibble = lrint (feed / 2.6 + 2.4); /* one suggested conversion */
692 if (feed_nibble > 31) feed_nibble = 31;
693 } else
694 feed_nibble = 0;
695 /* Determine auto cut bit - we only handle after each page */
696 unsigned char auto_cut_bit = do_cut ? 0x40 : 0x00;
697 /* Determine mirror print bit*/
698 unsigned char mirror_bit = do_mirror ? 0x80 : 0x00;
699 /* Combine & emit printer command code */
700 putchar (ESC); putchar ('i'); putchar ('M');
701 putchar ((char) (feed & 0x1f) | auto_cut_bit | mirror_bit);
702 }
703
704 /**
705 * Emit quality, roll fed media, and label size command codes.
706 * @param job_options Current job options
707 * @param page_options Current page options
708 * @param page_size_y Page size (height) in pt
709 * @param image_height_px Number of pixel lines in current page
710 */
711 void
712 emit_quality_rollfed_size (job_options_t* job_options,
713 page_options_t* page_options,
714 unsigned page_size_y,
715 unsigned image_height_px) {
716 bool roll_fed_media = page_options->roll_fed_media;
717 /* Determine print quality bit */
718 unsigned char print_quality_bit
719 = (job_options->print_quality_high == CUPS_TRUE) ? 0x40 : 0x00;
720 unsigned char roll_fed_media_bit = roll_fed_media ? 0x00 : 0x01;
721 /* Get tape width in mm */
722 int tape_width_mm = lrint (page_options->page_size [0] * MM_PER_PT);
723 if (tape_width_mm > 0xff) {
724 fprintf (stderr,
725 "ERROR: Page width (%umm) exceeds 255mm\n",
726 tape_width_mm);
727 tape_width_mm = 0xff;
728 }
729 /* Get tape height in mm */
730 unsigned tape_height_mm;
731 if (roll_fed_media)
732 tape_height_mm = 0;
733 else
734 tape_height_mm = lrint (page_size_y * MM_PER_PT);
735 if (tape_height_mm > 0xff) {
736 fprintf (stderr,
737 "ERROR: Page height (%umm) exceeds 255mm; use continuous tape (MediaType=roll)\n",
738 tape_height_mm);
739 tape_height_mm = 0xff;
740 }
741 /* Combine & emit printer command code */
742 putchar (ESC); putchar ('i'); putchar ('z');
743 putchar (print_quality_bit); putchar (roll_fed_media_bit);
744 putchar (tape_width_mm & 0xff); putchar (tape_height_mm & 0xff);
745 putchar (image_height_px & 0xff);
746 putchar ((image_height_px >> 8) & 0xff);
747 putchar (0x00); putchar (0x00); putchar (0x00); putchar (0x00);
748 }
749 /**
750 * Emit printer command codes at start of page for options that have
751 * changed.
752 * @param job_options Job options
753 * @param old_page_options Page options for preceding page
754 * @param new_page_options Page options for page to be printed
755 * @param force Ignore old_page_options and emit commands
756 * for selecting all options in new_page_options
757 */
758 void
759 emit_page_cmds (job_options_t* job_options,
760 page_options_t* old_page_options,
761 page_options_t* new_page_options,
762 bool force) {
763 int tape_width_mm = -1;
764
765 /* Set width and resolution */
766 unsigned hres = new_page_options->resolution [0];
767 unsigned vres = new_page_options->resolution [1];
768 unsigned old_page_size_x = old_page_options->page_size [0];
769 unsigned new_page_size_x = new_page_options->page_size [0];
770 if (force
771 || hres != old_page_options->resolution [0]
772 || vres != old_page_options->resolution [1]
773 || new_page_size_x != old_page_size_x)
774 /* We only know how to select 360x360DPI or 360x720DPI */
775 if (hres == 360 && (vres == 360 || vres == 720)) {
776 /* Get tape width in mm */
777 tape_width_mm = lrint (new_page_size_x * MM_PER_PT);
778 if (tape_width_mm > 0xff) {
779 fprintf (stderr,
780 "ERROR: Page width (%umm) exceeds 255mm\n",
781 tape_width_mm);
782 tape_width_mm = 0xff;
783 }
784 /* Emit printer commands */
785 putchar (ESC); putchar ('i'); putchar ('c');
786 if (vres == 360) {
787 putchar (0x84); putchar (0x00); putchar (tape_width_mm & 0xff);
788 putchar (0x00); putchar (0x00);
789 } else {
790 putchar (0x86); putchar (0x09); putchar (tape_width_mm & 0xff);
791 putchar (0x00); putchar (0x01);
792 }
793 }
794
795 /* Set feed, auto cut and mirror print */
796 unsigned feed = new_page_options->feed;
797 cups_adv_t perform_feed = new_page_options->perform_feed;
798 cups_cut_t cut_media = new_page_options->cut_media;
799 cups_bool_t mirror = new_page_options->mirror;
800 if (force
801 || feed != old_page_options->feed
802 || perform_feed != old_page_options->perform_feed
803 || cut_media != old_page_options->cut_media
804 || mirror != old_page_options->mirror)
805 /* We only know how to feed after each page */
806 emit_feed_cut_mirror (perform_feed == CUPS_ADVANCE_PAGE, feed,
807 cut_media == CUPS_CUT_PAGE,
808 mirror == CUPS_TRUE);
809 /* Set media and quality if label preamble is requested */
810 unsigned page_size_y = new_page_options->page_size [1];
811 unsigned image_height_px = lrint (page_size_y * vres / 72.0);
812 if (job_options->label_preamble && !job_options->concat_pages
813 && (force
814 || (new_page_options->roll_fed_media
815 != old_page_options->roll_fed_media)
816 || new_page_size_x != old_page_size_x
817 || page_size_y != old_page_options->page_size [1]))
818 emit_quality_rollfed_size (job_options, new_page_options,
819 page_size_y, image_height_px);
820
821 /* WHY DON'T WE SET MARGIN (ESC i d ...)? */
822
823 /* Set pixel data transfer compression */
824 if (force) {
825 if (job_options->pixel_xfer == RLE) {
826 putchar ('M'); putchar (0x02);
827 }
828 }
829 /* Emit number of raster lines to follow if using BIP */
830 if (job_options->pixel_xfer == BIP) {
831 unsigned image_height_px = lrint (page_size_y * vres / 72.0);
832 putchar (ESC); putchar (0x2a); putchar (0x27);
833 putchar (image_height_px & 0xff);
834 putchar ((image_height_px >> 8) & 0xff);
835 }
836 }
837
838 /** mirror [i] = bit mirror image of i.
839 * I.e., (mirror [i] >> j) & 1 == (i >> (7 - j)) & 1 for 0 <= j <= 7
840 */
841 const unsigned char mirror [0x100] = {
842 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
843 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
844 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
845 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
846 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
847 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
848 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
849 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
850 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
851 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
852 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
853 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
854 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
855 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
856 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
857 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
858 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
859 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
860 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
861 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
862 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
863 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
864 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
865 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
866 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
867 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
868 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
869 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
870 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
871 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
872 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
873 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
874 };
875
876 /**
877 * Generate a buffer of pixel data ready to emit.
878 * Requirement: buflen + right_padding_bytes
879 * + (shift > 0 ? 1 : 0) <= bytes_per_line
880 * @param in_buffer Buffer containing raster data in
881 * left-to-right order
882 * @param out_buffer Buffer for returning generated line in
883 * right-to-left order; must be
884 * bytes_per_line long
885 * @param buflen in_buffer length
886 * @param bytes_per_line Number of pixel bytes to generate
887 * @param right_padding_bytes Number of zero bytes to pad
888 * with to the right of pixels
889 * @param shift Number of bits to shift left
890 * If do_mirror is false and shift < 0
891 * Then shift right -shift bits
892 * @param do_mirror Mirror in_buffer pixel data
893 * @param xormask The XOR mask for negative printing
894 * @return 0 if entire line is empty (zeros)
895 * nonzero if line contains nonzero pixels
896 */
897 inline int
898 generate_emit_line (unsigned char* in_buffer,
899 unsigned char* out_buffer,
900 int buflen,
901 unsigned char bytes_per_line,
902 int right_padding_bytes,
903 int shift,
904 int do_mirror,
905 unsigned char xormask) {
906 #ifdef DEBUG
907 if (debug)
908 fprintf (stderr, "DEBUG: generate_emit_line "
909 "(in_buffer=%0x, out_buffer=%0x, "
910 "buflen=%d, bytes_per_line=%d, right_padding_bytes=%d, "
911 "shift=%d, do_mirror=%d, xormask=%0x)\n",
912 in_buffer, out_buffer, buflen, bytes_per_line,
913 right_padding_bytes, shift, do_mirror, xormask);
914 #endif
915 /* Generate right padding zero bytes */
916 memset (out_buffer, xormask, right_padding_bytes);
917 unsigned int nonzero = 0;
918 int j = right_padding_bytes;
919 /* Copy pixel data from in_buffer to out_buffer, */
920 /* shifted and mirrored if required */
921 unsigned int box = 0; /* Box for shifting pixel data left */
922 int i;
923 if (do_mirror)
924 if (shift) {
925 for (i = 0; i < buflen; i++) {
926 unsigned int data = in_buffer [i]; nonzero |= data;
927 box |= data << shift;
928 out_buffer [j++] = (box & 0xff) ^ xormask;
929 box >>= 8;
930 }
931 out_buffer [j++] = box & 0xff;
932 } else
933 for (i = 0; i < buflen; i++) {
934 unsigned char data = in_buffer [i]; nonzero |= data;
935 out_buffer [j++] = data ^ xormask;
936 }
937 else
938 if (shift) {
939 if (buflen > 0) {
940 if (shift < 0) {
941 box = in_buffer [buflen - 1] >> -shift; nonzero |= box;
942 shift += 8;
943 } else {
944 box = in_buffer [buflen - 1] << shift; nonzero |= box;
945 out_buffer [j++] = (mirror [box & 0xff]) ^ xormask;
946 box >>= 8;
947 }
948 for (i = buflen - 2; i >= 0; i--) {
949 unsigned data = in_buffer [i]; nonzero |= data;
950 box |= data << shift;
951 out_buffer [j++] = (mirror [box & 0xff]) ^ xormask;
952 box >>= 8;
953 }
954 out_buffer [j++] = (mirror [box & 0xff]) ^ xormask;
955 }
956 } else
957 for (i = buflen - 1; i >= 0; i--) {
958 unsigned char data = in_buffer [i]; nonzero |= data;
959 out_buffer [j++] = (mirror [data]) ^ xormask;
960 }
961 /* Generate left padding bytes */
962 memset (out_buffer + j, xormask, bytes_per_line - j);
963 return nonzero != 0;
964 }
965
966 /**
967 * Emit lines waiting in RLE buffer.
968 * Resets global variable rle_buffer_next to rle_buffer,
969 * and lines_waiting to zero.
970 * @param job_options Job options
971 * @param page_options Page options
972 */
973 inline void
974 flush_rle_buffer (job_options_t* job_options,
975 page_options_t* page_options) {
976 #ifdef DEBUG
977 if (debug)
978 fprintf (stderr, "DEBUG: flush_rle_buffer (): "
979 "lines_waiting = %d\n",
980 lines_waiting);
981 #endif
982 if (lines_waiting > 0) {
983 if (job_options->label_preamble)
984 emit_quality_rollfed_size (job_options, page_options,
985 page_options->page_size [1],
986 lines_waiting);
987 xfer_t pixel_xfer = job_options->pixel_xfer;
988 int bytes_per_line = job_options->bytes_per_line;
989 switch (pixel_xfer) {
990 case RLE: {
991 size_t dummy
992 = fwrite (rle_buffer, sizeof (char), rle_buffer_next - rle_buffer, stdout);
993 break;
994 }
995 case ULP:
996 case BIP: {
997 unsigned char* p = rle_buffer;
998 unsigned emitted_lines = 0;
999 while (rle_buffer_next - p > 0) {
1000 if (pixel_xfer == ULP) {
1001 putchar ('g'); putchar (0x00); putchar (bytes_per_line);
1002 }
1003 int emitted = 0;
1004 int linelen;
1005 switch (*p++) {
1006 case 'G':
1007 linelen = *p++;
1008 linelen += ((int)(*p++)) << 8;
1009 while (linelen > 0) {
1010 signed char l = *p++; linelen--;
1011 if (l < 0) { /* emit repeated data */
1012 char data = *p++; linelen--;
1013 emitted -= l; emitted++;
1014 for (; l <= 0; l++) putchar (data);
1015 } else { /* emit the l + 1 following bytes of data */
1016 size_t dummy = fwrite (p, sizeof (char), l + 1, stdout);
1017 p += l; p++;
1018 linelen -= l; linelen--;
1019 emitted += l; emitted++;
1020 }
1021 }
1022 if (emitted > bytes_per_line)
1023 fprintf (stderr,
1024 "ERROR: Emitted %d > %d bytes for one pixel line!\n",
1025 emitted, bytes_per_line);
1026 /* No break; fall through to next case: */
1027 case 'Z':
1028 for (; emitted < bytes_per_line; emitted++) putchar (0x00);
1029 break;
1030 default:
1031 fprintf (stderr, "ERROR: Unknown RLE flag at %p: '0x%02x'\n",
1032 p - 1, (int)*(p - 1));
1033 }
1034 emitted_lines++;
1035 }
1036 #ifdef DEBUG
1037 if (debug)
1038 fprintf (stderr, "DEBUG: emitted %d lines\n", emitted_lines);
1039 #endif
1040 break;
1041 }
1042 default:
1043 fprintf (stderr, "ERROR: Unknown pixel transfer mode: '%d'\n",
1044 pixel_xfer);
1045 }
1046 rle_buffer_next = rle_buffer;
1047 lines_waiting = 0;
1048 }
1049 }
1050
1051 /**
1052 * Ensure sufficient memory available in rle buffer.
1053 * If rle buffer needs to be extended, global variables rle_buffer and
1054 * rle_buffer_next might be altered.
1055 * @param job_options Job options
1056 * @param page_options Page options
1057 * @param bytes Number of bytes required.
1058 */
1059 inline void
1060 ensure_rle_buf_space (job_options_t* job_options,
1061 page_options_t* page_options,
1062 unsigned bytes) {
1063 unsigned long nextpos = rle_buffer_next - rle_buffer;
1064 if (nextpos + bytes > rle_alloced) {
1065 /* Exponential size increase avoids too frequent reallocation */
1066 unsigned long new_alloced = rle_alloced * 2 + 0x4000;
1067 #ifdef DEBUG
1068 if (debug)
1069 fprintf (stderr, "DEBUG: ensure_rle_buf_space (bytes=%d): "
1070 "increasing rle_buffer from %d to %d\n",
1071 bytes,
1072 rle_alloced * sizeof (char),
1073 new_alloced * sizeof (char));
1074 #endif
1075 void* p = NULL;
1076 if (new_alloced <= job_options->rle_alloc_max) {
1077 if (rle_buffer)
1078 p = (unsigned char*) realloc (rle_buffer, new_alloced * sizeof (char));
1079 else
1080 p = (unsigned char*) malloc (new_alloced * sizeof (char));
1081 }
1082 if (p) {
1083 rle_buffer = p;
1084 rle_buffer_next = rle_buffer + nextpos;
1085 rle_alloced = new_alloced;
1086 } else { /* Gain memory by flushing buffer to printer */
1087 flush_rle_buffer (job_options, page_options);
1088 if (rle_buffer_next - rle_buffer + bytes > rle_alloced) {
1089 fprintf (stderr,
1090 "ERROR: Out of memory when attempting to increase RLE "
1091 "buffer from %ld to %ld bytes\n",
1092 rle_alloced * sizeof (char),
1093 new_alloced * sizeof (char));
1094 exit (-1);
1095 }
1096 }
1097 }
1098 }
1099
1100 /** @def APPEND_MIXED_BYTES
1101 * Macro for appending mixed-bytes run to rle_buffer */
1102 /** @def APPEND_REPEATED_BYTE
1103 * Macro for appending repeated-byte run to rle_buffer */
1104 /**
1105 * Store buffer data in rle buffer using run-length encoding.
1106 * @param job_options Job options
1107 * @param page_options Page options
1108 * @param buf Buffer containing data to store
1109 * @param buf_len Length of buffer
1110 *
1111 * Global variable rle_buffer_next is a pointer into buffer for holding RLE data.
1112 * Must have room for at least 3 + buf_len + buf_len/128 + 1
1113 * bytes (ensured by reallocation).
1114 * On return, rle_buffer_next points to first unused buffer byte.
1115 *
1116 * This implementation enjoys the property that
1117 * the resulting RLE is at most buf_len + buf_len/128 + 1 bytes
1118 * long, because:
1119 * # a repeated-byte run has a repeat factor of at least 3
1120 * # two mixed-bytes runs never follow directly after each other,
1121 * unless the first one is 128 bytes long
1122 * The first property ensures that a repeated-run output sequence is
1123 * always at least 1 byte shorter than the input sequence it
1124 * represents. This combined with the second property means that only
1125 * - a terminating mixed-bytes run, and
1126 * - a mixed-bytes run of 128 bytes
1127 * can cause the RLE representation to be longer (by 1 byte) than the
1128 * corresponding input sequence in buf.
1129 */
1130 inline void
1131 RLE_store_line (job_options_t* job_options,
1132 page_options_t* page_options,
1133 const unsigned char* buf, unsigned buf_len) {
1134 ensure_rle_buf_space (job_options, page_options,
1135 4 + buf_len + buf_len / 128);
1136 unsigned char* rle_next = rle_buffer_next + 3;
1137 /* Make room for 3 initial meta data bytes, */
1138 /* written when actual length is known */
1139 const unsigned char* buf_end = buf + buf_len; /* Buffer end */
1140 const unsigned char* mix_start; /* Start of mixed bytes run */
1141
1142 const unsigned char* rep_start; /* End + 1 of mixed bytes run,
1143 and start of repeated byte run */
1144 const unsigned char* next; /* Next byte pointer,
1145 and end + 1 of repeated byte run */
1146 unsigned char next_val; /* Next byte value to consider */
1147 unsigned char rep_val; /* Repeated byte value */
1148 unsigned char nonzero = 0; /* OR of all buffer bytes */
1149
1150 #define APPEND_MIXED_BYTES \
1151 if (mix_len > 128) mix_len = 128; \
1152 *rle_next++ = mix_len - 1; \
1153 memcpy (rle_next, mix_start, mix_len); \
1154 rle_next += mix_len;
1155 #define APPEND_REPEATED_BYTE \
1156 unsigned rep_len = next - rep_start; \
1157 *rle_next++ = (signed char)(1 - rep_len); \
1158 *rle_next++ = rep_val;
1159
1160 for (mix_start = rep_start = next = buf, rep_val = next_val = *next;
1161 next != buf_end;
1162 next++, next_val = *next) {
1163 /* Loop invariants at this point:
1164 * 1) [mix_start..rep_start - 1] contains mixed bytes waiting
1165 * to be appended to rle_buffer,
1166 * 2) [rep_start..next - 1] contains repeats of rep_val
1167 * waiting to be appended to rle_buffer
1168 * 3) If next - rep_start > 2 then mix_start == rep_start
1169 * 4) next - rep_start <= 129
1170 * 5) rep_start - mix_start < 128
1171 * 6) [rle_buffer_next..rle_next - 1] = RLE ([buf..mix_start - 1])
1172 * 7) rep_val = *rep_start
1173 * 8) next_val = *next
1174 */
1175 nonzero |= next_val;
1176 if (next - rep_start >= 129) {
1177 /* RLE cannot represent repeated runs longer than 129 bytes */
1178 APPEND_REPEATED_BYTE;
1179 rep_start += rep_len;
1180 rep_val = *rep_start;
1181 mix_start = rep_start;
1182 }
1183 if (next_val == rep_val) { /* Run of repeated byte values */
1184 if (next - rep_start == 2) {
1185 unsigned mix_len = rep_start - mix_start;
1186 if (mix_len > 0) {
1187 APPEND_MIXED_BYTES;
1188 mix_start = rep_start;
1189 }
1190 }
1191 } else {
1192 if (next - rep_start > 2) { /* End of repeated run found */
1193 APPEND_REPEATED_BYTE;
1194 mix_start = next;
1195 }
1196 rep_start = next;
1197 rep_val = next_val;
1198 unsigned mix_len = rep_start - mix_start;
1199 if (mix_len >= 128) {
1200 /* RLE cannot represent mixed runs longer than 128 bytes */
1201 APPEND_MIXED_BYTES;
1202 mix_start += mix_len;
1203 }
1204 }
1205 }
1206 /* Handle final bytes */
1207 if (next - rep_start > 2) { /* Handle final repeated byte run */
1208 APPEND_REPEATED_BYTE;
1209 mix_start = next;
1210 }
1211 rep_start = next;
1212 unsigned mix_len = rep_start - mix_start;
1213 if (mix_len > 0) { /* Handle any remaining final mixed run */
1214 APPEND_MIXED_BYTES;
1215 mix_start += mix_len;
1216 }
1217 mix_len = rep_start - mix_start;
1218 if (mix_len > 0) { /* Case where final mixed run is 129 bytes */
1219 APPEND_MIXED_BYTES;
1220 }
1221 unsigned rle_len = rle_next - rle_buffer_next - 3;
1222 /* Store rle line meta data (length and (non)zero status) */
1223 if (nonzero) { /* Check for nonempty (no black pixels) line */
1224 rle_buffer_next [0] = 'G';
1225 rle_buffer_next [1] = rle_len & 0xff;
1226 rle_buffer_next [2] = (rle_len >> 8) & 0xff;
1227 rle_buffer_next = rle_next;
1228 } else {
1229 rle_buffer_next [0] = 'Z';
1230 rle_buffer_next++;
1231 }
1232 lines_waiting++;
1233 if (lines_waiting >= max_lines_waiting)
1234 flush_rle_buffer (job_options, page_options);
1235 }
1236
1237 /**
1238 * Store a number of empty lines in rle_buffer using RLE.
1239 * @param job_options Job options
1240 * @param page_options Page options
1241 * @param empty_lines Number of empty lines to store
1242 * @param xormask The XOR mask for negative printing
1243 */
1244 inline void
1245 RLE_store_empty_lines (job_options_t* job_options,
1246 page_options_t* page_options,
1247 int empty_lines,
1248 unsigned char xormask) {
1249 int bytes_per_line = job_options->bytes_per_line;
1250 #ifdef DEBUG
1251 if (debug)
1252 fprintf (stderr, "DEBUG: RLE_store_empty_lines (empty_lines=%d, "
1253 "bytes_per_line=%d): lines_waiting = %d\n",
1254 empty_lines, bytes_per_line, lines_waiting);
1255 #endif
1256 lines_waiting += empty_lines;
1257 if (xormask) {
1258 int blocks = (bytes_per_line + 127) / 128;
1259 ensure_rle_buf_space (job_options, page_options,
1260 empty_lines * blocks);
1261 for (; empty_lines--; ) {
1262 *(rle_buffer_next++) = 'G';
1263 *(rle_buffer_next++) = 0x02;
1264 *(rle_buffer_next++) = 0x00;
1265 int rep_len;
1266 for (; bytes_per_line > 0; bytes_per_line -= rep_len) {
1267 rep_len = bytes_per_line;
1268 if (rep_len > 128) rep_len = 128;
1269 *(rle_buffer_next++) = (signed char) (1 - rep_len);
1270 *(rle_buffer_next++) = xormask;
1271 }
1272 }
1273 } else {
1274 ensure_rle_buf_space (job_options, page_options, empty_lines);
1275 for (; empty_lines--; ) *(rle_buffer_next++) = 'Z';
1276 }
1277 }
1278
1279 /**
1280 * Emit raster lines for current page.
1281 * @param page Page number of page to be emitted
1282 * @param job_options Job options
1283 * @param page_options Page options
1284 * @param ras Raster data stream
1285 * @param header Current page header
1286 * @return 0 on success, nonzero otherwise
1287 */
1288 int
1289 emit_raster_lines (int page,
1290 job_options_t* job_options,
1291 page_options_t* page_options,
1292 cups_raster_t* ras,
1293 cups_page_header_t* header) {
1294 unsigned char xormask = (header->NegativePrint ? ~0 : 0);
1295 /* Determine whether we need to mirror the pixel data */
1296 int do_mirror = job_options->software_mirror && page_options->mirror;
1297
1298 unsigned cupsBytesPerLine = header->cupsBytesPerLine;
1299 unsigned cupsHeight = header->cupsHeight;
1300 unsigned cupsWidth = header->cupsWidth;
1301 int bytes_per_line = job_options->bytes_per_line;
1302 unsigned buflen = cupsBytesPerLine;
1303 /* Make sure buflen can be written as a byte */
1304 if (buflen > 0xff) buflen = 0xff;
1305 /* Truncate buflen if greater than bytes_per_line */
1306 if (buflen >= bytes_per_line) buflen = bytes_per_line;
1307 /* Calculate extra horizontal spacing pixels if the right side of */
1308 /* ImagingBoundingBox doesn't touch the PageSize box */
1309 double scale_pt2xpixels = header->HWResolution [0] / 72.0;
1310 unsigned right_spacing_px = 0;
1311 if (header->ImagingBoundingBox [2] != 0) {
1312 unsigned right_distance_pt
1313 = header->PageSize [0] - header->ImagingBoundingBox [2];
1314 if (right_distance_pt != 0)
1315 right_spacing_px = right_distance_pt * scale_pt2xpixels;
1316 }
1317 /* Calculate right_padding_bytes and shift */
1318 int right_padding_bits;
1319 if (job_options->align == CENTER) {
1320 unsigned left_spacing_px = 0;
1321 if (header->ImagingBoundingBox [0] != 0)
1322 left_spacing_px
1323 = header->ImagingBoundingBox [0] * scale_pt2xpixels;
1324 right_padding_bits
1325 = (bytes_per_line * 8
1326 - (left_spacing_px + cupsWidth + right_spacing_px)) / 2
1327 + right_spacing_px;
1328 if (right_padding_bits < 0) right_padding_bits = 0;
1329 } else
1330 right_padding_bits = right_spacing_px;
1331 int right_padding_bytes = right_padding_bits / 8;
1332 int shift = right_padding_bits % 8;
1333 /* If width is not an integral number of bytes, we must shift */
1334 /* right if we don't mirror, to ensure printing starts leftmost */
1335 if (!do_mirror) shift -= (8 - cupsWidth % 8) % 8;
1336 int shift_positive = (shift > 0 ? 1 : 0);
1337 /* We cannot allow buffer+padding to exceed device width */
1338 if (buflen + right_padding_bytes + shift_positive > bytes_per_line) {
1339 #ifdef DEBUG
1340 if (debug) {
1341 fprintf (stderr, "DEBUG: Warning: buflen = %d, right_padding_bytes = %d, "
1342 "shift = %d, bytes_per_line = %d\n",
1343 buflen, right_padding_bytes, shift, bytes_per_line);
1344 }
1345 #endif
1346 /* We cannot allow padding to exceed device width */
1347 if (right_padding_bytes + shift_positive > bytes_per_line)
1348 right_padding_bytes = bytes_per_line - shift_positive;
1349 /* Truncate buffer to fit device width */
1350 buflen = bytes_per_line - right_padding_bytes - shift_positive;
1351 }
1352 /* Percentage of page emitted */
1353 int completed = -1;
1354 /* Generate and store empty lines if the top of ImagingBoundingBox */
1355 /* doesn't touch the PageSize box */
1356 double scale_pt2ypixels = header->HWResolution [1] / 72.0;
1357 unsigned top_empty_lines = 0;
1358 unsigned page_size_y = header->PageSize [1];
1359 if (header->ImagingBoundingBox [3] != 0
1360 && (!job_options->concat_pages || page == 1)) {
1361 unsigned top_distance_pt
1362 = page_size_y - header->ImagingBoundingBox [3];
1363 if (top_distance_pt != 0) {
1364 top_empty_lines = lrint (top_distance_pt * scale_pt2ypixels);
1365 empty_lines += top_empty_lines;
1366 }
1367 }
1368 /* Generate and store actual page data */
1369 int y;
1370 for (y = 0; y < cupsHeight; y++) {
1371 /* Feedback to the user */
1372 if ((y & 0x1f) == 0) {
1373 int now_completed = 100 * y / cupsHeight;
1374 if (now_completed > completed) {
1375 completed = now_completed;
1376 fprintf (stderr,
1377 "INFO: Printing page %d, %d%% complete...\n",
1378 page, completed);
1379 fflush (stderr);
1380 }
1381 }
1382 /* Read one line of pixels */
1383 if (cupsRasterReadPixels (ras, buffer, cupsBytesPerLine) < 1)
1384 break; /* Escape if no pixels read */
1385 bool nonempty_line =
1386 generate_emit_line (buffer, emit_line_buffer, buflen, bytes_per_line,
1387 right_padding_bytes, shift, do_mirror, xormask);
1388 if (nonempty_line) {
1389 if (empty_lines) {
1390 RLE_store_empty_lines
1391 (job_options, page_options, empty_lines, xormask);
1392 empty_lines = 0;
1393 }
1394 RLE_store_line (job_options, page_options,
1395 emit_line_buffer, bytes_per_line);
1396 } else
1397 empty_lines++;
1398 }
1399
1400 unsigned image_height_px = lrint (page_size_y * scale_pt2ypixels);
1401 unsigned bot_empty_lines;
1402 if (image_height_px >= top_empty_lines + y)
1403 bot_empty_lines = image_height_px - top_empty_lines - y;
1404 else
1405 bot_empty_lines = 0;
1406 if (bot_empty_lines != 0 && !job_options->concat_pages)
1407 empty_lines += bot_empty_lines;
1408 fprintf (stderr,
1409 "INFO: Printing page %d, 100%% complete.\n",
1410 page);
1411 fflush (stderr);
1412 return 0;
1413 }
1414 /**
1415 * Process CUPS raster data from input file, emitting printer data on
1416 * stdout.
1417 * @param fd File descriptor for input file
1418 * @param job_options Pointer to print options
1419 * @return 0 on success, nonzero otherwise
1420 */
1421 int
1422 process_rasterdata (int fd, job_options_t* job_options) {
1423 int page = 1; /* Page number */
1424 cups_raster_t* ras; /* Raster stream for printing */
1425 cups_page_header_t header; /* Current page header */
1426 int first_page = true; /* Is this the first page? */
1427 int more_pages; /* Are there more pages left? */
1428 int bytes_per_line = job_options->bytes_per_line;
1429 page_options_t page_options [2] = {{
1430 CUT_MEDIA_DEFAULT,
1431 MIRROR_DEFAULT,
1432 ROLL_FED_MEDIA_DEFAULT,
1433 RESOLUTION_DEFAULT,
1434 PAGE_SIZE_DEFAULT,
1435 IMAGE_HEIGHT_DEFAULT,
1436 FEED_DEFAULT,
1437 PERFORM_FEED_DEFAULT,}
1438 }; /* Current & preceding page opts */
1439 page_options_t* new_page_options
1440 = page_options + 0; /* Options for current page */
1441 page_options_t* old_page_options
1442 = page_options + 1; /* Options for preceding page */
1443 page_options_t* tmp_page_options;/* Temp variable for swapping */
1444 ras = cupsRasterOpen (fd, CUPS_RASTER_READ);
1445 for (more_pages = cupsRasterReadHeader (ras, &header);
1446 more_pages;
1447 tmp_page_options = old_page_options,
1448 old_page_options = new_page_options,
1449 new_page_options = tmp_page_options,
1450 first_page = false) {
1451 update_page_options (&header, new_page_options);
1452 #ifdef DEBUG
1453 if (debug) {
1454 fprintf (stderr, "DEBUG: pixel_xfer = %d\n", job_options->pixel_xfer);
1455 fprintf (stderr, "DEBUG: print_quality_high = %d\n", job_options->print_quality_high);
1456 fprintf (stderr, "DEBUG: half_cut = %d\n", job_options->half_cut);
1457 fprintf (stderr, "DEBUG: bytes_per_line = %d\n", job_options->bytes_per_line);
1458 fprintf (stderr, "DEBUG: align = %d\n", job_options->align);
1459 fprintf (stderr, "DEBUG: software_mirror = %d\n", job_options->software_mirror);
1460 fprintf (stderr, "DEBUG: label_preamble = %d\n", job_options->label_preamble);
1461 fprintf (stderr, "DEBUG: print_density = %d\n", job_options->print_density);
1462 fprintf (stderr, "DEBUG: xfer_mode = %d\n", job_options->xfer_mode);
1463 fprintf (stderr, "DEBUG: concat_pages = %d\n", job_options->concat_pages);
1464 fprintf (stderr, "DEBUG: cut_media = %d\n", new_page_options->cut_media);
1465 fprintf (stderr, "DEBUG: mirror = %d\n", new_page_options->mirror);
1466 fprintf (stderr, "DEBUG: roll_fed_media = %d\n", new_page_options->roll_fed_media);
1467 fprintf (stderr, "DEBUG: resolution = %d x %d\n", new_page_options->resolution [0], new_page_options->resolution [1]);
1468 fprintf (stderr, "DEBUG: page_size = %d x %d\n", new_page_options->page_size [0], new_page_options->page_size [1]);
1469 fprintf (stderr, "DEBUG: image_height = %d\n", new_page_options->image_height);
1470 fprintf (stderr, "DEBUG: feed = %d\n", new_page_options->feed);
1471 fprintf (stderr, "DEBUG: perform_feed = %d\n", new_page_options->perform_feed);
1472 fprintf (stderr, "DEBUG: header->ImagingBoundingBox = [%u, %u, %u, %u]\n",
1473 header.ImagingBoundingBox [0], header.ImagingBoundingBox [1],
1474 header.ImagingBoundingBox [2], header.ImagingBoundingBox [3]);
1475 fprintf (stderr, "DEBUG: header.Margins = [%u, %u]\n",
1476 header.Margins [0], header.Margins [1]);
1477 }
1478 #endif
1479 page_prepare (header.cupsBytesPerLine, bytes_per_line);
1480 if (first_page) {
1481 emit_job_cmds (job_options);
1482 emit_page_cmds (job_options, old_page_options,
1483 new_page_options, first_page);
1484 }
1485 emit_raster_lines (page, job_options, new_page_options, ras, &header);
1486 unsigned char xormask = (header.NegativePrint ? ~0 : 0);
1487 /* Determine whether this is the last page (fetch next) */
1488 more_pages = cupsRasterReadHeader (ras, &header);
1489 /* Do feeding or ejecting at the end of each page. */
1490 cups_adv_t perform_feed = new_page_options->perform_feed;
1491 if (more_pages) {
1492 if (!job_options->concat_pages) {
1493 RLE_store_empty_lines
1494 (job_options, page_options, empty_lines, xormask);
1495 empty_lines = 0;
1496 flush_rle_buffer (job_options, page_options);
1497 if (perform_feed == CUPS_ADVANCE_PAGE)
1498 putchar (PTC_EJECT); /* Emit eject marker to force feed */
1499 else
1500 putchar (PTC_FORMFEED); /* Emit page end marker without feed */
1501 }
1502 } else {
1503 if (!job_options->concat_pages) {
1504 RLE_store_empty_lines
1505 (job_options, page_options, empty_lines, xormask);
1506 empty_lines = 0;
1507 flush_rle_buffer (job_options, page_options);
1508 putchar (PTC_FORMFEED);
1509 } else {
1510 double scale_pt2ypixels = header.HWResolution [1] / 72.0;
1511 unsigned bot_empty_lines
1512 = lrint (header.ImagingBoundingBox [1] * scale_pt2ypixels);
1513 empty_lines = bot_empty_lines;
1514 RLE_store_empty_lines
1515 (job_options, page_options, empty_lines, xormask);
1516 empty_lines = 0;
1517 flush_rle_buffer (job_options, page_options);
1518 }
1519
1520 /* If special feed or cut at job end, emit commands to that effect */
1521 cups_cut_t cut_media = new_page_options->cut_media;
1522 if (perform_feed == CUPS_ADVANCE_JOB || cut_media == CUPS_CUT_JOB) {
1523 emit_feed_cut_mirror
1524 (perform_feed == CUPS_ADVANCE_PAGE ||
1525 perform_feed == CUPS_ADVANCE_JOB,
1526 new_page_options->feed,
1527 cut_media == CUPS_CUT_PAGE || cut_media == CUPS_CUT_JOB,
1528 new_page_options->mirror == CUPS_TRUE);
1529 /* Emit eject marker */
1530 putchar (PTC_EJECT);
1531 }
1532 }
1533 page_end ();
1534 /* Emit page count according to CUPS requirements */
1535 fprintf (stderr, "PAGE: %d 1\n", page);
1536 page++;
1537 }
1538 return 0;
1539 }
1540 /**
1541 * Main entry function.
1542 * @param argc number of command line arguments plus one
1543 * @param argv command line arguments
1544 * @return 0 if success, nonzero otherwise
1545 */
1546 int
1547 main (int argc, const char* argv []) {
1548 error_occurred = 0;
1549 #ifdef DEBUG
1550 int i;
1551 if (argc > 5)
1552 if (strcasestr (argv [5], "debug") == argv [5]
1553 || strcasestr (argv [5], " debug") != NULL)
1554 debug = true;
1555 struct tms time_start, time_end;
1556 if (debug) {
1557 fprintf (stderr, "DEBUG: args = ");
1558 for (i = 0; i < argc; i++) fprintf (stderr, "%d:'%s' ", i, argv [i]);
1559 fprintf (stderr, "\nDEBUG: environment =\n");
1560 char** envvarbind;
1561 for (envvarbind = environ; *envvarbind; envvarbind++)
1562 fprintf (stderr, "DEBUG: %s\n", *envvarbind);
1563 times (&time_start);
1564 }
1565 #endif
1566
1567 job_options_t job_options = parse_options (argc, argv);
1568
1569 int fd = open_input_file (argc, argv);
1570
1571 int rv = process_rasterdata (fd, &job_options);
1572
1573 #ifdef DEBUG
1574 if (debug) {
1575 times (&time_end);
1576 fprintf (stderr, "DEBUG: User time System time (usec)\n");
1577 fprintf (stderr, "DEBUG: %9.3g %9.3g\n",
1578 (time_end.tms_utime - time_start.tms_utime)
1579 * 1000000.0 / CLOCKS_PER_SEC,
1580 (time_end.tms_stime - time_start.tms_stime)
1581 * 1000000.0 / CLOCKS_PER_SEC);
1582 fprintf (stderr, "DEBUG: Emitted lines: %u\n", emitted_lines);
1583 }
1584 #endif
1585
1586 if (fd != 0) close (fd);
1587
1588 if (error_occurred) return error_occurred; else return rv;
1589 }
0 ptouch-driver (1.3-1) unstable; urgency=low
1
2 * Initial Debian release (Closes: #555892).
3
4 * Start from the Ubuntu packaging, thanks!
5
6 * Put under Debian Printing Team umbrella, with myself as uploader.
7 * Convert to 3.0 (quilt) source format.
8 * Add the Ubuntu apport hook conditionally
9 * Add VCS-* fields.
10 * Use dh-autoreconf to have a cleaner build.
11 * debian/watch: add.
12 * Use dh_pyppd trough the --with stanza.
13 * Drop explicit pyppd depends, they come trough dh_pyppd.
14 * Add DEP-3 headers to all patches.
15 * Rewrite debian/copyright DEP-5-style.
16 * Enable parallel building, including specifying the number of threads for
17 the foomatic compilation.
18 * Drop unneeded dh_auto_test override.
19 * Slightly rewrite the "long" description.
20 * Bump Standards-Version to 3.9.2 without changes needed.
21
22 -- Didier Raboud <odyx@debian.org> Mon, 29 Aug 2011 12:27:35 +0200
23
24 ptouch-driver (1.3-0ubuntu11) oneiric; urgency=low
25
26 * debian/control: Versioned build dependency on foomatic-db to assure that
27 the Ubuntu build server installs the physical package foomatic-db and
28 not foomatic-db-compressed-ppds which only provides foomatic-db
29 (LP: #829446).
30 * debian/rules, debian/control: Compress PPD files with pyppd.
31 * debian/rules, debian/control, debian/postinst,
32 debian/ptouch-driver.ppd-updater: Let automatic update of the PPDs of
33 already existing print queues be done by CUPS.
34
35 -- Till Kamppeter <till.kamppeter@gmail.com> Sat, 20 Aug 2011 00:37:23 +0200
36
37 ptouch-driver (1.3-0ubuntu10) oneiric; urgency=low
38
39 * debian/control: Changed build dependency on foomatic-db-xml back to
40 foomatic-db and added "Build-Conflicts: foomatic-db-compressed-ppds"
41 instead to assure that the Foomatic XML database is present during
42 package build and not only the compressed archive of the Foomatic PPD
43 files.
44
45 -- Till Kamppeter <till.kamppeter@gmail.com> Mon, 1 Aug 2011 19:07:23 +0200
46
47 ptouch-driver (1.3-0ubuntu9) oneiric; urgency=low
48
49 * debian/control: Changed build dependency on foomatic-db to foomatic-db-xml
50 to assure that the Foomatic XML database is present and not only the
51 compressed archive of the Foomatic PPD files.
52
53 -- Till Kamppeter <till.kamppeter@gmail.com> Thu, 28 Jul 2011 19:28:03 +0200
54
55 ptouch-driver (1.3-0ubuntu8) oneiric; urgency=low
56
57 * debian/patches/foomatic-data-fixes.patch: Added "-dNOINTERPOLATE" to the
58 Ghostscript command line. This makes the page rendering by Ghostscript
59 significantly faster.
60
61 * debian/rules, debian/control, debian/local/pyppd/: Use pyppd from
62 external package.
63
64 -- Till Kamppeter <till.kamppeter@gmail.com> Sun, 24 Jul 2011 22:34:03 +0200
65
66 ptouch-driver (1.3-0ubuntu7) maverick; urgency=low
67
68 * debian/local/pyppd/pyppd/: Updated to pyppd 0.4.9. Here we do not suppress
69 all runtime errors but only IOError and KeyboardInterrupt. This way we do
70 not suppress errors which are caused by an actual bug (LP: #618017).
71
72 -- Till Kamppeter <till.kamppeter@gmail.com> Wed, 23 Sep 2010 16:07:03 +0200
73
74 ptouch-driver (1.3-0ubuntu6) maverick; urgency=low
75
76 * debian/local/pyppd/pyppd/pyppd-ppdfile.in: Suppress any kind of runtime
77 error tracebacks by putting a "try: ... except: pass" construct around the
78 main function call. This avoids Apport pop-ups when the execution of the
79 self-extracting compressed PPD file archives gets stopped by the calling
80 process (LP: #618017).
81
82 -- Till Kamppeter <till.kamppeter@gmail.com> Tue, 21 Sep 2010 20:35:03 +0200
83
84 ptouch-driver (1.3-0ubuntu5) maverick; urgency=low
85
86 * debian/patches/send-esc-i-A.patch: The code "ESC i A \001" needs to be sent
87 to the printer so that cutting happens. Thanks to Matthias Urlichs for the
88 patch (LP: #635249).
89
90 -- Till Kamppeter <till.kamppeter@gmail.com> Mon, 13 Sep 2010 10:00:00 +0200
91
92 ptouch-driver (1.3-0ubuntu4) maverick; urgency=low
93
94 * debian/control: Added build and runtime dependencies for the compressed
95 PPD archive.
96
97 -- Till Kamppeter <till.kamppeter@gmail.com> Fri, 3 Sep 2010 20:25:53 +0200
98
99 ptouch-driver (1.3-0ubuntu3) maverick; urgency=low
100
101 * debian/rules: Make bin/pyppd executable before calling it and create the
102 empty file pyppd/__init__.py. These properties are not conveyed by the
103 .diff.gz file.
104
105 -- Till Kamppeter <till.kamppeter@gmail.com> Fri, 3 Sep 2010 17:14:53 +0200
106
107 ptouch-driver (1.3-0ubuntu2) maverick; urgency=low
108
109 * debian/control, debian/rules, debian/postinst: Provided the PPD files
110 pre-built in a compressed archive instead of providing Foomatic XML data,
111 to make the package not depending on foomatic-db. This way we can replace
112 foomatic-db by a compressed PPD archive.
113 * debian/local/pyppd/: Added pyppd scripts to generate compressed PPD
114 archives.
115
116 -- Till Kamppeter <till.kamppeter@gmail.com> Tue, 31 Aug 2010 22:35:53 +0200
117
0118 ptouch-driver (1.3-0ubuntu1) lucid; urgency=low
1119
2120 [ Till Kamppeter ]
00 Source: ptouch-driver
1 Maintainer: ubuntu-devel-discuss@lists.ubuntu.com
2 XSBC-Original-Maintainer: Lars Wirzenius <liw@liw.fi>
1 Maintainer: Debian Printing Team <debian-printing@lists.debian.org>
2 Uploaders: Didier Raboud <odyx@debian.org>
33 Section: text
44 Priority: optional
5 Standards-Version: 3.8.2
6 Build-Depends: debhelper (>= 7.3.8), quilt, libcups2-dev, libcupsimage2-dev
5 Standards-Version: 3.9.2
6 Build-Depends: debhelper (>= 7.3.8),
7 dh-autoreconf,
8 libcups2-dev,
9 libcupsimage2-dev,
10 foomatic-db-engine,
11 foomatic-db (>= 20000101),
12 pyppd (>= 0.4.9-5)
13 Build-Conflicts: foomatic-db-compressed-ppds
14 Vcs-Git: git://anonscm.debian.org/collab-maint/ptouch-driver.git
15 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/ptouch-driver.git
716 Homepage: http://www.diku.dk/hjemmesider/ansatte/panic/P-touch/
817
918 Package: ptouch-driver
1019 Architecture: any
11 Depends: ${shlibs:Depends}, ${misc:Depends}
20 Depends: ${shlibs:Depends}, ${misc:Depends}, ghostscript
1221 Description: CUPS/Foomatic driver for Brother P-touch label printers
13 A driver for CUPS/Foomatic for Brother P-touch label printers.
14
22 The ptouch driver is an open source driver for the Brother P-touch label
23 printers, from the QL-* and PT-* series.
0 Packaging by Lars Wirzenius, and probably should be reviewed before
1 uploaded. I only made this for myself.
0 Format: http://anonscm.debian.org/viewvc/dep/web/deps/dep5.mdwn?revision=174
1 Upstream-Name: ptouch-driver
2 Source: http://www.diku.dk/hjemmesider/ansatte/panic/P-touch/
23
3 Copyright (c) 2006 Arne John Glenstrup <panic@itu.dk>
4 Files: *
5 Copyright: 2006 Arne John Glenstrup <panic@itu.dk>
6 License: GPL-2+
47
5 This file is part of ptouch-driver.
8 Files: debian/*
9 Copyright: 2009 Lars Wirzenius <liw@debian.org>
10 Copyright: 2010-2011 Till Kamppeter <till.kamppeter@gmail.com>
11 Copyright: 2011 Didier Raboud <odyx@debian.org>
12 License: GPL-2+
613
7 ptouch-driver 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 (at
10 your option) any later version.
14 Files: debian/local/apport-hook.py
15 Copyright: 2009 Canonical Ltd.
16 Author: Brian Murray <brian@ubuntu.com>
17 License: GPL
1118
12 ptouch-driver is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with ptouch-driver; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 USA
21
22 On a Debian system, you can find a copy of the GPL version 2 in
23 /usr/share/common-licenses/GPL-2.
19 License: GPL-2+
20 This program is free software; you can redistribute it
21 and/or modify it under the terms of the GNU General Public
22 License as published by the Free Software Foundation; either
23 version 2 of the License, or (at your option) any later
24 version.
25 .
26 This program is distributed in the hope that it will be
27 useful, but WITHOUT ANY WARRANTY; without even the implied
28 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
29 PURPOSE. See the GNU General Public License for more
30 details.
31 .
32 You should have received a copy of the GNU General Public
33 License along with this package; if not, write to the Free
34 Software Foundation, Inc., 51 Franklin St, Fifth Floor,
35 Boston, MA 02110-1301 USA
36 .
37 On Debian systems, the full text of the GNU General Public
38 License version 2 can be found in the file
39 `/usr/share/common-licenses/GPL-2'.
0 --- ptouch-driver-1.3.orig/driver/ptouch.xml 2010-02-16 15:43:14.000000000 +0100
1 +++ ptouch-driver-1.3/driver/ptouch.xml 2010-02-16 15:43:59.000000000 +0100
2 @@ -25,6 +25,15 @@
0 Description: Fixes for foomatic "compliance". Also add -dNOINTERPOLATE to the
1 gs commandline, that makes it significantly faster.
2 Author: Till Kamppeter <till.kamppeter@gmail.com>
3 Last-Update: 2011-07-24
4 --- a/driver/ptouch.xml
5 +++ b/driver/ptouch.xml
6 @@ -24,7 +24,16 @@
7 <url></url>
38 <execution>
49 <filter />
5 <prototype>gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -sDEVICE=cups %A%Z -sOutputFile=- - | rastertoptch dummyjob dummyuser dummytitle 1 '%B'</prototype>
10 - <prototype>gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -sDEVICE=cups %A%Z -sOutputFile=- - | rastertoptch dummyjob dummyuser dummytitle 1 '%B'</prototype>
11 + <prototype>gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -dNOINTERPOLATE -sDEVICE=cups %A%Z -sOutputFile=- - | rastertoptch dummyjob dummyuser dummytitle 1 '%B'</prototype>
612 + <margins>
713 + <general>
814 + <unit>mm</unit>
1521 </execution>
1622 <comments>
1723 <en>
18 --- ptouch-driver-1.3.orig/printer/Brother-QL-550.xml 2010-02-16 15:46:11.000000000 +0100
19 +++ ptouch-driver-1.3/printer/Brother-QL-550.xml 2010-02-16 15:48:18.675274267 +0100
24 --- a/printer/Brother-QL-550.xml
25 +++ b/printer/Brother-QL-550.xml
2026 @@ -28,7 +28,7 @@
2127 <resolution>
2228 <dpi>
0 Description: The code "ESC i A \001" needs to be sent to the printer so that
1 cutting happens. Thanks to Matthias Urlichs for the patch.
2 Bugs-Ubuntu: LP: #635249.
3 Author: Till Kamppeter <till.kamppeter@gmail.com>
4 Last-Update: 2010-09-13
5 diff -ub ptouch-driver-1.3/rastertoptch.c ptouch-driver-1.3.new//rastertoptch.c
6 --- ptouch-driver-1.3.orig/rastertoptch.c 2009-02-04 09:47:44.000000000 +0100
7 +++ ptouch-driver-1.3/rastertoptch.c 2010-09-12 11:51:21.494421545 +0200
8 @@ -698,6 +698,7 @@
9 /* Determine mirror print bit*/
10 unsigned char mirror_bit = do_mirror ? 0x80 : 0x00;
11 /* Combine & emit printer command code */
12 + putchar (ESC); putchar ('i'); putchar ('A'); putchar ((char) (do_cut ? 0x01 : 0x00));
13 putchar (ESC); putchar ('i'); putchar ('M');
14 putchar ((char) (feed & 0x1f) | auto_cut_bit | mirror_bit);
15 }
00 foomatic-data-fixes.patch
1 send-esc-i-A.patch
+0
-84
debian/postinst less more
0 #! /bin/sh
1 # postinst script for ptouch-driver
2 # $Id: $
3 #
4 # see: dh_installdeb(1)
5
6 set -e
7
8 # summary of how this script can be called:
9 # * <postinst> `configure' <most-recently-configured-version>
10 # * <old-postinst> `abort-upgrade' <new version>
11 # * <conflictor's-postinst> `abort-remove' `in-favour' <package>
12 # <new-version>
13 # * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
14 # <failed-install-package> <version> `removing'
15 # <conflicting-package> <version>
16 # for details, see http://www.debian.org/doc/debian-policy/ or
17 # the debian-policy package
18 #
19 # quoting from the policy:
20 # Any necessary prompting should almost always be confined to the
21 # post-installation script, and should be protected with a conditional
22 # so that unnecessary prompting doesn't happen if a package's
23 # installation fails and the `postinst' is called with `abort-upgrade',
24 # `abort-remove' or `abort-deconfigure'.
25
26 case "$1" in
27 configure)
28 # Do the following only if CUPS is running and the needed CUPS tools
29 # are available
30 if which lpstat > /dev/null 2>&1 && \
31 which lpinfo > /dev/null 2>&1 && \
32 which lpadmin > /dev/null 2>&1 && \
33 LC_ALL=C lpstat -h /var/run/cups/cups.sock -r | grep -v not > /dev/null 2>&1; then
34 # Update the PPD files of all already installed print queues
35 driverregexp='^foomatic:.*-ptouch\.ppd\b'
36 gennicknameregexp=''
37 [ ! -z "$gennicknameregexp" ] && \
38 gennicknameregexp="; $gennicknameregexp"
39 gennicknameregexp='s/\s*\(recommended\)//'"$gennicknameregexp"
40 tempfiles=
41 trap 'rm -f $tempfiles; exit 0' 0 HUP INT QUIT ILL ABRT PIPE TERM
42 tmpfile1=`mktemp -t updateppds.XXXXXX`
43 tempfiles="$tempfiles $tmpfile1"
44 lpinfo -h /var/run/cups/cups.sock -m | grep -E $driverregexp > $tmpfile1
45 cd /etc/cups/ppd
46 for ppd in *.ppd; do
47 [ -r "$ppd" ] || continue
48 queue=${ppd%.ppd}
49 lpstat -h /var/run/cups/cups.sock -p "$queue" >/dev/null 2>&1 || continue
50 nickname=`grep '\*NickName:' "$ppd" | cut -d '"' -f 2 | perl -p -e 's/\n$//' | perl -p -e "$gennicknameregexp" | perl -p -e 's/(\W)/\\\\$1/g'`
51 lang=`grep '\*LanguageVersion:' "$ppd" | cut -d ' ' -f 2 | perl -e 'print lc(<>)' | perl -p -e 's/[\r\n]//gs'`
52 ppdfound="0"
53 englishppduri=""
54 tmpfile2=`mktemp -t updateppds.XXXXXX`
55 tempfiles="$tempfiles $tmpfile2"
56 cat $tmpfile1 | perl -p -e "$gennicknameregexp" | grep -E '^\S+\s+.*'"$nickname"'$' | cut -d ' ' -f 1 > $tmpfile2
57 while read newppduri; do
58 [ "$ppdfound" = "0" ] && lpadmin -h /var/run/cups/cups.sock -p "$queue" -m $newppduri 2>/dev/null || continue
59 newlang=`grep '\*LanguageVersion:' "$ppd" | cut -d ' ' -f 2 | perl -e 'print lc(<>)' | perl -p -e 's/[\r\n]//gs'`
60 [ "$newlang" = "$lang" ] && ppdfound="1"
61 [ "$newlang" = "english" ] && englishppduri="$newppduri"
62 done < $tmpfile2
63 [ "$ppdfound" = "0" ] && [ ! -z "$englishppduri" ] && lpadmin -h /var/run/cups/cups.sock -p "$queue" -m $englishppduri 2>/dev/null && ppdfound="1"
64 [ "$ppdfound" = "1" ] && echo PPD for printer $queue updated >&2
65 done
66 fi
67 ;;
68
69 abort-upgrade|abort-remove|abort-deconfigure)
70 ;;
71
72 *)
73 echo "postinst called with unknown argument \`$1'" >&2
74 exit 1
75 ;;
76 esac
77
78 # dh_installdeb will replace this with shell code automatically
79 # generated by other debhelper scripts.
80
81 #DEBHELPER#
82
83 exit 0
0 DRIVER_REGEXP='^ptouch-driver:'
1 GENNICKNAME_REGEXP=''
00 #!/usr/bin/make -f
1
2 derives_from_ubuntu := $(shell (dpkg-vendor --derives-from Ubuntu && echo "yes") || echo "no")
3
4 ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
5 NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
6 else
7 # Faster when testing on modern desktops, 1 task takes less than a full CPU
8 NUMJOBS = 4
9 endif
10
111 %:
2 dh --with quilt $@
12 dh $@ --with autoreconf --with pyppd --parallel
13
14 override_dh_auto_clean:
15 dh_auto_clean
16 rm -rf foomatic-db
317
418 override_dh_auto_install:
519 dh_auto_install
620 rm -rf debian/ptouch-driver/usr/share/foomatic/db/source/printer
21
22 # Pre-build PPD files
23 mkdir $(CURDIR)/foomatic-db
24 cp -r /usr/share/foomatic/* $(CURDIR)/foomatic-db
25 rm -f $(CURDIR)/foomatic-db/db/source/*/*ptouch*.xml
26 cp -r $(CURDIR)/debian/ptouch-driver/usr/share/foomatic/* $(CURDIR)/foomatic-db/
27 rm -rf $(CURDIR)/debian/ptouch-driver/usr/share/foomatic
28 mkdir -p $(CURDIR)/debian/ptouch-driver/usr/share/ppd
29 FOOMATICDB=$(CURDIR)/foomatic-db foomatic-compiledb -j $(NUMJOBS) -t ppd -d $(CURDIR)/debian/ptouch-driver/usr/share/ppd/ptouch-driver `ls -1 $(CURDIR)/foomatic-db/db/source/driver/*ptouch*.xml | perl -p -e 's:^.*db/source/driver/(\S*)\.xml\s*$$:\1\n:'`
30
31 # Install the ppd updater data file so that CUPS can update the
32 # PPDs of the already existing queues after each update of the
33 # ptouch-driver package
34 install -D -m 644 debian/ptouch-driver.ppd-updater $(CURDIR)/debian/ptouch-driver/usr/share/cups/ppd-updaters/ptouch-driver
35
36 ifeq ($(derives_from_ubuntu),yes)
37 # Install Apport hook
738 install -D -m 644 debian/local/apport-hook.py $(CURDIR)/debian/ptouch-driver/usr/share/apport/package-hooks/source_ptouch-driver.py
8
9 override_dh_auto_test:
39 endif
0 3.0 (quilt)
0 version=3
1 http://www.diku.dk/hjemmesider/ansatte/panic/P-touch/ptouch-driver-(.*)\.tar\.gz
2323 <url></url>
2424 <execution>
2525 <filter />
26 <prototype>gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -sDEVICE=cups %A%Z -sOutputFile=- - | rastertoptch dummyjob dummyuser dummytitle 1 '%B'</prototype>
26 <prototype>gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -dNOINTERPOLATE -sDEVICE=cups %A%Z -sOutputFile=- - | rastertoptch dummyjob dummyuser dummytitle 1 '%B'</prototype>
27 <margins>
28 <general>
29 <unit>mm</unit>
30 <left>0</left>
31 <right>0</right>
32 <top>0</top>
33 <bottom>0</bottom>
34 </general>
35 </margins>
2736 </execution>
2837 <comments>
2938 <en>
2727 <resolution>
2828 <dpi>
2929 <x>300</x>
30 <y>300</y>
30 <y>275</y>
3131 </dpi>
3232 </resolution>
3333 <consumables>
697697 /* Determine mirror print bit*/
698698 unsigned char mirror_bit = do_mirror ? 0x80 : 0x00;
699699 /* Combine & emit printer command code */
700 putchar (ESC); putchar ('i'); putchar ('A'); putchar ((char) (do_cut ? 0x01 : 0x00));
700701 putchar (ESC); putchar ('i'); putchar ('M');
701702 putchar ((char) (feed & 0x1f) | auto_cut_bit | mirror_bit);
702703 }