]> git.ipfire.org Git - thirdparty/cups.git/blob - doc/help/raster-driver.html
Merge changes from CUPS 1.5svn-r9352.
[thirdparty/cups.git] / doc / help / raster-driver.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <!-- SECTION: Programming -->
4 <head>
5 <title>Developing Raster Printer Drivers</title>
6 <meta name="keywords" content="Programming">
7 <meta name="creator" content="Mini-XML v2.6">
8 <style type="text/css"><!--
9 BODY {
10 font-family: lucida grande, geneva, helvetica, arial, sans-serif;
11 }
12
13 H1, H2, H3, H4, H5, H6, P, TD, TH {
14 font-family: lucida grande, geneva, helvetica, arial, sans-serif;
15 }
16
17 KBD {
18 font-family: monaco, courier, monospace;
19 font-weight: bold;
20 }
21
22 PRE {
23 font-family: monaco, courier, monospace;
24 }
25
26 PRE.command {
27 border: dotted thin #7f7f7f;
28 margin-left: 36pt;
29 padding: 10px;
30 }
31
32 P.compact {
33 margin: 0;
34 }
35
36 P.example {
37 font-style: italic;
38 margin-left: 36pt;
39 }
40
41 PRE.example {
42 background: #eeeeee;
43 border: dotted thin #999999;
44 margin-left: 36pt;
45 padding: 10pt;
46 }
47
48 PRE.command EM, PRE.example EM {
49 font-family: lucida grande, geneva, helvetica, arial, sans-serif;
50 }
51
52 P.command {
53 font-family: monaco, courier, monospace;
54 margin-left: 36pt;
55 }
56
57 P.formula {
58 font-style: italic;
59 margin-left: 36pt;
60 }
61
62 BLOCKQUOTE {
63 background: #eeeeee;
64 border: solid thin #999999;
65 padding: 10pt;
66 }
67
68 A IMG {
69 border: none;
70 }
71
72 A:link:hover IMG {
73 background: #f0f0f0;
74 border-radius: 10px;
75 -moz-border-radius: 10px;
76 }
77
78 A:link, A:visited {
79 font-weight: normal;
80 text-decoration: none;
81 }
82
83 A:link:hover, A:visited:hover, A:active {
84 text-decoration: underline;
85 }
86
87 SUB, SUP {
88 font-size: 50%;
89 }
90
91 TR.data, TD.data, TR.data TD {
92 margin-top: 10pt;
93 padding: 5pt;
94 border-bottom: solid 1pt #999999;
95 }
96
97 TR.data TH {
98 border-bottom: solid 1pt #999999;
99 padding-top: 10pt;
100 padding-left: 5pt;
101 text-align: left;
102 }
103
104 DIV.table TABLE {
105 border: solid thin #999999;
106 border-collapse: collapse;
107 border-spacing: 0;
108 margin-left: auto;
109 margin-right: auto;
110 }
111
112 DIV.table CAPTION {
113 caption-side: top;
114 font-size: 120%;
115 font-style: italic;
116 font-weight: bold;
117 margin-left: auto;
118 margin-right: auto;
119 }
120
121 DIV.table TABLE TD {
122 border: solid thin #cccccc;
123 padding-top: 5pt;
124 }
125
126 DIV.table TABLE TH {
127 background: #cccccc;
128 border: none;
129 border-bottom: solid thin #999999;
130 }
131
132 DIV.figure TABLE {
133 margin-left: auto;
134 margin-right: auto;
135 }
136
137 DIV.figure CAPTION {
138 caption-side: bottom;
139 font-size: 120%;
140 font-style: italic;
141 font-weight: bold;
142 margin-left: auto;
143 margin-right: auto;
144 }
145
146 TH.label {
147 text-align: right;
148 vertical-align: top;
149 }
150
151 TH.sublabel {
152 text-align: right;
153 font-weight: normal;
154 }
155
156 HR {
157 border: solid thin;
158 }
159
160 SPAN.info {
161 background: black;
162 border: thin solid black;
163 color: white;
164 font-size: 80%;
165 font-style: italic;
166 font-weight: bold;
167 white-space: nowrap;
168 }
169
170 H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
171 float: right;
172 font-size: 100%;
173 }
174
175 H1.title {
176 }
177
178 H2.title, H3.title {
179 border-bottom: solid 2pt #000000;
180 }
181
182 DIV.indent, TABLE.indent {
183 margin-top: 2em;
184 margin-left: auto;
185 margin-right: auto;
186 width: 90%;
187 }
188
189 TABLE.indent {
190 border-collapse: collapse;
191 }
192
193 TABLE.indent TD, TABLE.indent TH {
194 padding: 0;
195 }
196
197 TABLE.list {
198 border-collapse: collapse;
199 margin-left: auto;
200 margin-right: auto;
201 width: 90%;
202 }
203
204 TABLE.list TH {
205 background: white;
206 border-bottom: solid thin #cccccc;
207 color: #444444;
208 padding-top: 10pt;
209 padding-left: 5pt;
210 text-align: left;
211 vertical-align: bottom;
212 white-space: nowrap;
213 }
214
215 TABLE.list TH A {
216 color: #4444cc;
217 }
218
219 TABLE.list TD {
220 border-bottom: solid thin #eeeeee;
221 padding-top: 5pt;
222 padding-left: 5pt;
223 }
224
225 TABLE.list TR:nth-child(even) {
226 background: #f8f8f8;
227 }
228
229 TABLE.list TR:nth-child(odd) {
230 background: #f4f4f4;
231 }
232
233 DT {
234 margin-left: 36pt;
235 margin-top: 12pt;
236 }
237
238 DD {
239 margin-left: 54pt;
240 }
241
242 DL.category DT {
243 font-weight: bold;
244 }
245
246 P.summary {
247 margin-left: 36pt;
248 font-family: monaco, courier, monospace;
249 }
250
251 DIV.summary TABLE {
252 border: solid thin #999999;
253 border-collapse: collapse;
254 border-spacing: 0;
255 margin: 10px;
256 }
257
258 DIV.summary TABLE TD, DIV.summary TABLE TH {
259 border: solid thin #999999;
260 padding: 5px;
261 text-align: left;
262 vertical-align: top;
263 }
264
265 DIV.summary TABLE THEAD TH {
266 background: #eeeeee;
267 }
268
269 /* API documentation styles... */
270 div.body h1 {
271 margin: 0;
272 }
273 div.body h2 {
274 margin-top: 1.5em;
275 }
276 div.body h3, div.body h4, div.body h5 {
277 margin-bottom: 0.5em;
278 margin-top: 1.5em;
279 }
280 .class, .enumeration, .function, .struct, .typedef, .union {
281 border-bottom: solid thin #999999;
282 margin-bottom: 0;
283 margin-top: 2em;
284 }
285 .description {
286 margin-top: 0.5em;
287 }
288 code, p.code, pre, ul.code li {
289 font-family: monaco, courier, monospace;
290 font-size: 90%;
291 }
292 ul.code, ul.contents, ul.subcontents {
293 list-style-type: none;
294 margin: 0;
295 padding-left: 0;
296 }
297 ul.code li {
298 margin: 0;
299 }
300 ul.contents > li {
301 margin-top: 1em;
302 }
303 ul.contents li ul.code, ul.contents li ul.subcontents {
304 padding-left: 2em;
305 }
306 div.body dl {
307 margin-left: 0;
308 margin-top: 0;
309 }
310 div.body dt {
311 font-style: italic;
312 margin-left: 0;
313 margin-top: 0;
314 }
315 div.body dd {
316 margin-bottom: 0.5em;
317 }
318
319 /* This is just for the HTML files generated with the framedhelp target */
320 div.contents {
321 background: #e8e8e8;
322 border: solid thin black;
323 padding: 10px;
324 }
325 div.contents h1 {
326 font-size: 110%;
327 }
328 div.contents h2 {
329 font-size: 100%;
330 }
331 div.contents ul.contents {
332 font-size: 80%;
333 }
334 div.contents ul.subcontents li {
335 margin-left: 1em;
336 text-indent: -1em;
337 }
338 --></style>
339 </head>
340 <body>
341 <div class='body'>
342 <!--
343 "$Id$"
344
345 Raster printer driver documentation for CUPS.
346
347 Copyright 2007-2010 by Apple Inc.
348 Copyright 1997-2007 by Easy Software Products.
349
350 These coded instructions, statements, and computer programs are the
351 property of Apple Inc. and are protected by Federal copyright
352 law. Distribution and use rights are outlined in the file "LICENSE.txt"
353 which should have been included with this file. If this file is
354 file is missing or damaged, see the license at "http://www.cups.org/".
355 -->
356
357 <h1 class='title'>Developing Raster Printer Drivers</h1>
358
359 <p>This document describes how to develop printer drivers for raster printers. Topics include: <a href='#BASICS'>printer driver basics</a>, <a href='#CREATE'>creating new PPD files</a>, <a href='#FILTERS'>using filters</a>, <a href='#COLOR'>implementing color management</a>, and <a href='#MACOSX'>adding Mac OS X features</a>.</p>
360
361 <div class='summary'><table summary='General Information'>
362 <tbody>
363 <tr>
364 <th>See Also</th>
365 <td>Programming: <a href='postscript-driver.html'>Developing PostScript Printer Drivers</a><br>
366 Programming: <a href='api-filter.html'>Filter and Backend Programming</a><br>
367 Programming: <a href='ppd-compiler.html'>Introduction to the PPD Compiler</a><br>
368 Programming: <a href='api-raster.html'>Raster API</a><br>
369 References: <a href='ref-ppdcfile.html'>PPD Compiler Driver Information File Reference</a><br>
370 Specifications: <a href='spec-ppd.html'>CUPS PPD Extensions</a></td>
371 </tr>
372 </tbody>
373 </table></div>
374 <h2 class="title">Contents</h2>
375 <ul class="contents">
376 <ul class="subcontents">
377 <li><a href="#BASICS">Printer Driver Basics</a></li>
378 <li><a href="#CREATING">Creating New PPD Files</a></li>
379 <li><a href="#FILTERS">Using Filters</a></li>
380 <li><a href="#COLOR">Implementing Color Management</a></li>
381 <li><a href="#MACOSX">Adding Mac OS X Features</a></li>
382 <h2 class='title'><a name='BASICS'>Printer Driver Basics</a></h2>
383
384 <p>A CUPS raster printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, one or more <em>filter</em> programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.</p>
385
386 <p>Every time a user prints something the scheduler program, <a href='man-cupsd.html'>cupsd(8)</a>, determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into CUPS raster data. <a href='#FIGURE_1'>Figure 1</a> shows the data flow of a typical print job.</p>
387
388 <div class='figure'><table summary='Raster Filter Chain'>
389 <caption>Figure 1: <a name='FIGURE_1'>Raster Filter Chain</a></caption>
390 <tr><td><img src='../images/cups-raster-chain.png' width='700' height='150' alt='Raster Filter Chain'></td></tr>
391 </table></div>
392
393 <p>The raster filter converts CUPS raster data into a format the printer understands, for example HP-PCL. CUPS includes several sample raster filters supporting standard page description languages (PDLs). <a href='#TABLE_1'>Table 1</a> shows the raster filters that are bundled with CUPS and the languages they support.</p>
394
395 <div class='table'><table summary='Standard CUPS Raster Filters'>
396 <caption>Table 1: <a name='TABLE_1'>Standard CUPS Raster Filters</a></caption>
397 <thead>
398 <tr><th>Filter</th><th>PDLs</th><th>ppdc DriverType</th><th>ppdc #include file</th></tr>
399 </thead>
400 <tbody>
401 <tr><td>rastertoepson</td><td>ESC/P, ESC/P2</td><td>epson</td><td>epson.h</td></tr>
402 <tr><td>rastertoescpx</td><td>ESC/P, ESC/P2, EPSON Remote Mode</td><td>escp</td><td>escp.h</td></tr>
403 <tr><td>rastertohp</td><td>HP-PCL3, HP-PCL5</td><td>hp</td><td>hp.h</td></tr>
404 <tr><td>rastertolabel</td><td>CPCL, Dymo, EPL1, EPL2, Intellitech PCL, ZPL</td><td>label</td><td>label.h</td></tr>
405 <tr><td>rastertopclx</td><td>HP-RTL, HP-PCL3, HP-PCL3GUI, HP-PCL5, HP-PCL5c, HP-PCL5e</td><td>pcl</td><td>pcl.h</td></tr>
406 </tbody>
407 </table></div>
408
409 <p>The optional port monitor handles interface-specific protocol or encoding issues. For example, some raster printers use the 1284.4 communications protocol.</p>
410
411 <p>The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.</p>
412
413 <p>The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. <a href='#FIGURE_2'>Figure 2</a> shows the data flow of a typical command job.</p>
414
415 <div class='figure'><table summary='Command Filter Chain'>
416 <caption>Figure 2: <a name='FIGURE_2'>Command Filter Chain</a></caption>
417 <tr><td><img src='../images/cups-command-chain.png' width='575' height='150' alt='Command Filter Chain'></td></tr>
418 </table></div>
419
420 <p>Raster printer drivers must provide their own command filter.</p>
421
422
423 <h2 class='title'><a name='CREATING'>Creating New PPD Files</a></h2>
424
425 <p>We recommend using the CUPS PPD compiler, <a href='man-ppdc.html'>ppdc(1)</a>, to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "<a href='ppd-compiler.html'>Introduction to the PPD Compiler</a>" document. <a href='#LISTING_1'>Listing 1</a> shows a driver information file for several similar black-and-white HP-PCL5 laser printers.</p>
426
427 <p class='example'>Listing 1: <a name='LISTING_1'>"examples/laserjet-basic.drv"</a></p>
428
429 <pre class='example'>
430 <I>// Include standard font and media definitions</I>
431 <a href='ref-ppdcfile.html#_include'>#include</a> &lt;font.defs&gt;
432 <a href='ref-ppdcfile.html#_include'>#include</a> &lt;media.defs&gt;
433
434 <I>// Include HP-PCL driver definitions</I>
435 <a href='ref-ppdcfile.html#_include'>#include</a> &lt;pcl.h&gt;
436
437 <I>// Specify that this driver uses the HP-PCL driver...</I>
438 <a href='ref-ppdcfile.html#DriverType'>DriverType</a> pcl
439
440 <I>// Specify the driver options via the model number...</I>
441 <a href='ref-ppdcfile.html#ModelNumber'>ModelNumber</a> ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
442
443 <I>// List the fonts that are supported, in this case all standard fonts...</I>
444 <a href='ref-ppdcfile.html#Font'>Font</a> *
445
446 <I>// Manufacturer and driver version</I>
447 <a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "HP"
448 <a href='ref-ppdcfile.html#Version'>Version</a> 1.0
449
450 <I>// Supported page sizes and their margins</I>
451 <a href='ref-ppdcfile.html#HWMargins'>HWMargins</a> 18 12 18 12
452 *<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
453 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Legal
454 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Executive
455 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Monarch
456 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Statement
457 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> FanFoldGermanLegal
458
459 <a href='ref-ppdcfile.html#HWMargins'>HWMargins</a> 18 12.72 18 12.72
460 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Env10
461
462 <a href='ref-ppdcfile.html#HWMargins'>HWMargins</a> 9.72 12 9.72 12
463 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
464 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A5
465 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> B5
466 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> EnvC5
467 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> EnvDL
468 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> EnvISOB5
469 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Postcard
470 <a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> DoublePostcard
471
472 <I>// Only black-and-white output with mode 3 compression...</I>
473 <a href='ref-ppdcfile.html#ColorModel'>ColorModel</a> Gray k chunky 3
474
475 <I>// Supported resolutions</I>
476 <a href='ref-ppdcfile.html#Resolution'>Resolution</a> - 1 0 0 0 "300dpi/300 DPI"
477 *<a href='ref-ppdcfile.html#Resolution'>Resolution</a> - 8 0 0 0 "600dpi/600 DPI"
478
479 <I>// Supported input slots</I>
480 *<a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 7 "Auto/Automatic Selection"
481 <a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 2 "Manual/Tray 1 - Manual Feed"
482 <a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 4 "Upper/Tray 1"
483 <a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 1 "Lower/Tray 2"
484 <a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 5 "LargeCapacity/Tray 3"
485
486 <I>// Tray 3 is an option...</I>
487 <a href='ref-ppdcfile.html#Installable'>Installable</a> "OptionLargeCapacity/Tray 3 Installed"
488 <a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*OptionLargeCapacity False *InputSlot LargeCapacity"
489
490 {
491 <I>// HP LaserJet 2100 Series</I>
492 <a href='ref-ppdcfile.html#Throughput'>Throughput</a> 10
493 <a href='ref-ppdcfile.html#ModelName'>ModelName</a> "LaserJet 2100 Series"
494 <a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "hpljt211.ppd"
495 }
496
497 {
498 <I>// LaserJet 2200 and 2300 series have duplexer option...</I>
499 <a href='ref-ppdcfile.html#Duplex'>Duplex</a> normal
500 <a href='ref-ppdcfile.html#Installable'>Installable</a> "OptionDuplex/Duplexer Installed"
501 <a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*OptionDuplex False *Duplex"
502
503 {
504 <I>// HP LaserJet 2200 Series</I>
505 <a href='ref-ppdcfile.html#Throughput'>Throughput</a> 19
506 <a href='ref-ppdcfile.html#ModelName'>ModelName</a> "LaserJet 2200 Series"
507 <a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "hpljt221.ppd"
508 }
509
510 {
511 <I>// HP LaserJet 2300 Series</I>
512 <a href='ref-ppdcfile.html#Throughput'>Throughput</a> 25
513 <a href='ref-ppdcfile.html#ModelName'>ModelName</a> "LaserJet 2300 Series"
514 <a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "hpljt231.ppd"
515 }
516 }
517 </pre>
518
519
520 <h2 class='title'><a name='FILTERS'>Using Filters</a></h2>
521
522 <p>The standard CUPS raster filters can be specified using the
523 <a href='ref-ppdcfile.html#DriverType'><tt>DriverType</tt></a> directive, for example:</p>
524
525 <pre class='example'>
526 <I>// Specify that this driver uses the HP-PCL driver...</I>
527 <a href='ref-ppdcfile.html#DriverType'>DriverType</a> pcl
528 </pre>
529
530 <p><a href='#TABLE_1'>Table 1</a> shows the driver types for each of the standard CUPS raster filters. For drivers that do not use the standard raster filters, the "custom" type is used with <a href='ref-ppdcfile.html#Filter'><tt>Filter</tt></a> directives:</p>
531
532 <pre class='example'>
533 <a href='ref-ppdcfile.html#DriverType'>DriverType</a> custom
534 <a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 /path/to/raster/filter
535 <a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-command 100 /path/to/command/filter
536 </pre>
537
538
539 <h2 class='title'><a name='COLOR'>Implementing Color Management</a></h2>
540
541 <p>CUPS uses ICC color profiles to provide more accurate color reproduction. The <a href='spec-ppd.html#cupsICCProfile'><tt>cupsICCProfile</tt></a> attribute defines the color profiles that are available for a given printer, for example:</p>
542
543 <pre class='example'>
544 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
545 </pre>
546
547 <p>where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:</p>
548
549 <pre class='example'>
550 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
551 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
552 </pre>
553
554 <p>The options used for profile selection can be customized using the <tt>cupsICCQualifier2</tt> and <tt>cupsICCQualifier3</tt> attributes.</p>
555
556 <h3><span class='info'>Since Mac OS X 10.5</span>Custom Color Matching Support</h3>
557
558 <p>Mac OS X printer drivers that are based on an existing standard RGB colorspace can tell the system to use the corresponding colorspace instead of an arbitrary ICC color profile when doing color management. The <a href='#APCustom'><tt>APSupportsCustomColorMatching</tt></a> and <tt>APDefaultCustomColorMatchingProfile</tt> attributes can be used to enable this mode:</p>
559
560 <pre class='example'>
561 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> APSupportsCustomColorMatching "" true
562 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> APDefaultCustomColorMatchingProfile "" sRGB
563 </pre>
564
565
566 <h2 class='title'><a name='MACOSX'>Adding Mac OS X Features</a></h2>
567
568 <p>Mac OS X printer drivers can provide <a href='spec-ppd.html#MACOSX'>additional attributes</a> to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:</p>
569
570 <pre class='example'>
571 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> APDialogExtension "" /Library/Printers/Vendor/filename.plugin
572 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> APHelpBook "" /Library/Printers/Vendor/filename.bundle
573 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
574 <a href='ref-ppdcfile.html#Attribute'>Attribute</a> APPrinterPreset "name/text" "*option choice ..."
575 </pre>
576 </div>
577 </body>
578 </html>