]> git.ipfire.org Git - thirdparty/cups.git/blame - ppdc/ppdc-driver.cxx
Merge changes from CUPS 1.4svn-r8606.
[thirdparty/cups.git] / ppdc / ppdc-driver.cxx
CommitLineData
ac884b6a
MS
1//
2// "$Id$"
3//
4// PPD file compiler definitions for the CUPS PPD Compiler.
5//
d2354e63 6// Copyright 2007-2009 by Apple Inc.
ac884b6a
MS
7// Copyright 2002-2006 by Easy Software Products.
8//
9// These coded instructions, statements, and computer programs are the
10// property of Apple Inc. and are protected by Federal copyright
11// law. Distribution and use rights are outlined in the file "LICENSE.txt"
12// which should have been included with this file. If this file is
13// file is missing or damaged, see the license at "http://www.cups.org/".
14//
15// Contents:
16//
94da7e34
MS
17// ppdcDriver::ppdcDriver() - Create a new printer driver.
18// ppdcDriver::~ppdcDriver() - Destroy a printer driver.
19// ppdcDriver::find_attr() - Find an attribute.
20// ppdcDriver::find_group() - Find a group.
21// ppdcDriver::find_option() - Find an option.
22// ppdcDriver::set_custom_size_code() - Set the custom page size code.
23// ppdcDriver::set_default_font() - Set the default font name.
24// ppdcDriver::set_default_size() - Set the default size name.
25// ppdcDriver::set_file_name() - Set the full filename.
26// ppdcDriver::set_manufacturer() - Set the manufacturer name.
27// ppdcDriver::set_model_name() - Set the model name.
28// ppdcDriver::set_pc_file_name() - Set the PC filename.
29// ppdcDriver::set_version() - Set the version string.
30// ppdcDriver::write_ppd_file() - Write a PPD file...
ac884b6a
MS
31//
32
33//
34// Include necessary headers...
35//
36
38e73f87 37#include "ppdc-private.h"
61cf44e2 38#include <cups/globals.h>
ac884b6a
MS
39
40
41//
42// 'ppdcDriver::ppdcDriver()' - Create a new printer driver.
43//
44
45ppdcDriver::ppdcDriver(ppdcDriver *d) // I - Printer driver template
94da7e34 46 : ppdcShared()
ac884b6a
MS
47{
48 ppdcGroup *g; // Current group
49
50
94da7e34
MS
51 PPDC_NEW;
52
ac884b6a
MS
53 if (d)
54 {
55 // Bump the use count of any strings we inherit...
56 if (d->manufacturer)
e4572d57 57 d->manufacturer->retain();
ac884b6a 58 if (d->version)
e4572d57 59 d->version->retain();
ac884b6a 60 if (d->default_font)
e4572d57 61 d->default_font->retain();
ac884b6a 62 if (d->default_size)
e4572d57 63 d->default_size->retain();
ac884b6a 64 if (d->custom_size_code)
e4572d57 65 d->custom_size_code->retain();
ac884b6a
MS
66
67 // Copy all of the data from the driver template...
68 copyright = new ppdcArray(d->copyright);
69 manufacturer = d->manufacturer;
70 model_name = 0;
bdd6c45b 71 file_name = 0;
ac884b6a
MS
72 pc_file_name = 0;
73 type = d->type;
74 version = d->version;
75 model_number = d->model_number;
76 manual_copies = d->manual_copies;
77 color_device = d->color_device;
78 throughput = d->throughput;
79 attrs = new ppdcArray(d->attrs);
80 constraints = new ppdcArray(d->constraints);
81 filters = new ppdcArray(d->filters);
82 fonts = new ppdcArray(d->fonts);
83 profiles = new ppdcArray(d->profiles);
84 sizes = new ppdcArray(d->sizes);
85 default_font = d->default_font;
86 default_size = d->default_size;
87 variable_paper_size = d->variable_paper_size;
88 custom_size_code = d->custom_size_code;
89 left_margin = d->left_margin;
90 bottom_margin = d->bottom_margin;
91 right_margin = d->right_margin;
92 top_margin = d->top_margin;
93 max_width = d->max_width;
94 max_length = d->max_length;
95 min_width = d->min_width;
96 min_length = d->min_length;
97
98 // Then copy the groups manually, since we want separate copies
99 // of the groups and options...
100 groups = new ppdcArray();
101
102 for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next())
103 groups->add(new ppdcGroup(g));
104 }
105 else
106 {
107 // Zero all of the data in the driver...
108 copyright = new ppdcArray();
109 manufacturer = 0;
110 model_name = 0;
bdd6c45b 111 file_name = 0;
ac884b6a
MS
112 pc_file_name = 0;
113 version = 0;
114 type = PPDC_DRIVER_CUSTOM;
115 model_number = 0;
116 manual_copies = 0;
117 color_device = 0;
118 throughput = 1;
119 attrs = new ppdcArray();
120 constraints = new ppdcArray();
121 fonts = new ppdcArray();
122 filters = new ppdcArray();
123 groups = new ppdcArray();
124 profiles = new ppdcArray();
125 sizes = new ppdcArray();
126 default_font = 0;
127 default_size = 0;
128 variable_paper_size = 0;
129 custom_size_code = 0;
130 left_margin = 0;
131 bottom_margin = 0;
132 right_margin = 0;
133 top_margin = 0;
134 max_width = 0;
135 max_length = 0;
136 min_width = 0;
137 min_length = 0;
138 }
139}
140
141
142//
143// 'ppdcDriver::~ppdcDriver()' - Destroy a printer driver.
144//
145
146ppdcDriver::~ppdcDriver()
147{
94da7e34
MS
148 PPDC_DELETE;
149
e4572d57 150 copyright->release();
ac884b6a
MS
151
152 if (manufacturer)
153 manufacturer->release();
154 if (model_name)
155 model_name->release();
bdd6c45b
MS
156 if (file_name)
157 file_name->release();
ac884b6a
MS
158 if (pc_file_name)
159 pc_file_name->release();
160 if (version)
161 version->release();
162 if (default_font)
163 default_font->release();
164 if (default_size)
165 default_size->release();
166 if (custom_size_code)
167 custom_size_code->release();
168
e4572d57
MS
169 attrs->release();
170 constraints->release();
171 filters->release();
172 fonts->release();
173 groups->release();
174 profiles->release();
175 sizes->release();
ac884b6a
MS
176}
177
178
179//
180// 'ppdcDriver::find_attr()' - Find an attribute.
181//
182
183ppdcAttr * // O - Attribute or NULL
184ppdcDriver::find_attr(const char *k, // I - Keyword string
185 const char *s) // I - Spec string
186{
187 ppdcAttr *a; // Current attribute
188
189
190 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
191 if (!strcmp(a->name->value, k) &&
192 ((!s && (!a->selector->value || !a->selector->value[0])) ||
f11a948a 193 (s && a->selector->value && !strcmp(a->selector->value, s))))
ac884b6a
MS
194 return (a);
195
196 return (NULL);
197}
198
199
200//
201// 'ppdcDriver::find_group()' - Find a group.
202//
203
204ppdcGroup * // O - Matching group or NULL
205ppdcDriver::find_group(const char *n) // I - Group name
206{
207 ppdcGroup *g; // Current group
208
209
210 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
211 if (!strcasecmp(n, g->name->value))
212 return (g);
213
214 return (0);
215}
216
217
218//
219// 'ppdcDriver::find_option()' - Find an option.
220//
221
222ppdcOption * // O - Matching option or NULL
223ppdcDriver::find_option(const char *n) // I - Option name
224{
225 ppdcGroup *g; // Current group
226 ppdcOption *o; // Current option
227
228
229 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
230 for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
231 if (!strcasecmp(n, o->name->value))
232 return (o);
233
234 return (0);
235}
236
237
238//
239// 'ppdcDriver::set_custom_size_code()' - Set the custom page size code.
240//
241
242void
bdd6c45b
MS
243ppdcDriver::set_custom_size_code(
244 const char *c) // I - CustomPageSize code
ac884b6a
MS
245{
246 if (custom_size_code)
247 custom_size_code->release();
248
249 custom_size_code = new ppdcString(c);
250}
251
252
253//
254// 'ppdcDriver::set_default_font()' - Set the default font name.
255//
256
257void
bdd6c45b
MS
258ppdcDriver::set_default_font(
259 ppdcFont *f) // I - Font
ac884b6a
MS
260{
261 if (default_font)
262 default_font->release();
263
264 if (f)
265 {
e4572d57 266 f->name->retain();
ac884b6a
MS
267 default_font = f->name;
268 }
269 else
270 default_font = 0;
271}
272
273
274//
275// 'ppdcDriver::set_default_size()' - Set the default size name.
276//
277
278void
bdd6c45b
MS
279ppdcDriver::set_default_size(
280 ppdcMediaSize *m) // I - Media size
ac884b6a
MS
281{
282 if (default_size)
283 default_size->release();
284
285 if (m)
286 {
e4572d57 287 m->name->retain();
ac884b6a
MS
288 default_size = m->name;
289 }
290 else
291 default_size = 0;
292}
293
294
bdd6c45b
MS
295//
296// 'ppdcDriver::set_file_name()' - Set the full filename.
297//
298
299void
300ppdcDriver::set_file_name(const char *f)// I - Filename
301{
302 if (file_name)
303 file_name->release();
304
305 file_name = new ppdcString(f);
306}
307
308
ac884b6a
MS
309//
310// 'ppdcDriver::set_manufacturer()' - Set the manufacturer name.
311//
312
313void
bdd6c45b
MS
314ppdcDriver::set_manufacturer(
315 const char *m) // I - Model name
ac884b6a
MS
316{
317 if (manufacturer)
318 manufacturer->release();
319
320 manufacturer = new ppdcString(m);
321}
322
323
324//
325// 'ppdcDriver::set_model_name()' - Set the model name.
326//
327
328void
bdd6c45b
MS
329ppdcDriver::set_model_name(
330 const char *m) // I - Model name
ac884b6a
MS
331{
332 if (model_name)
333 model_name->release();
334
335 model_name = new ppdcString(m);
336}
337
338
339//
340// 'ppdcDriver::set_pc_file_name()' - Set the PC filename.
341//
342
343void
bdd6c45b
MS
344ppdcDriver::set_pc_file_name(
345 const char *f) // I - Filename
ac884b6a
MS
346{
347 if (pc_file_name)
348 pc_file_name->release();
349
350 pc_file_name = new ppdcString(f);
351}
352
353
354//
355// 'ppdcDriver::set_version()' - Set the version string.
356//
357
358void
359ppdcDriver::set_version(const char *v) // I - Version
360{
361 if (version)
362 version->release();
363
364 version = new ppdcString(v);
365}
366
367
368//
369// 'ppdcDriver::write_ppd_file()' - Write a PPD file...
370//
371
372int // O - 0 on success, -1 on failure
373ppdcDriver::write_ppd_file(
374 cups_file_t *fp, // I - PPD file
375 ppdcCatalog *catalog, // I - Message catalog
376 ppdcArray *locales, // I - Additional languages to add
377 ppdcSource *src, // I - Driver source
378 ppdcLineEnding le) // I - Line endings to use
379{
380 bool delete_cat; // Delete the catalog when we are done?
f11a948a
MS
381 char query[42], // Query attribute
382 custom[42]; // Custom attribute
ac884b6a
MS
383 ppdcString *s; // Copyright string
384 ppdcGroup *g; // Current group
385 ppdcOption *o; // Current option
386 ppdcChoice *c; // Current choice
387 ppdcMediaSize *m; // Current media size
388 ppdcProfile *p; // Current color profile
389 ppdcFilter *f; // Current filter
390 ppdcFont *fn, // Current font
391 *bfn; // Current base font
392 ppdcConstraint *cn; // Current constraint
393 ppdcAttr *a; // Current attribute
394 const char *lf; // Linefeed character to use
395
396
397 // If we don't have a message catalog, use an empty (English) one...
398 if (!catalog)
399 {
400 catalog = new ppdcCatalog("en");
401 delete_cat = true;
402 }
403 else
404 delete_cat = false;
405
406 // Figure out the end-of-line string...
407 if (le == PPDC_LFONLY)
408 lf = "\n";
409 else if (le == PPDC_CRONLY)
410 lf = "\r";
411 else
412 lf = "\r\n";
413
414 // Write the standard header stuff...
415 cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf);
f11a948a
MS
416 cupsFilePrintf(fp, "*%%%%%%%% PPD file for %s with CUPS.%s",
417 model_name->value, lf);
ac884b6a 418 cupsFilePrintf(fp,
f11a948a
MS
419 "*%%%%%%%% Created by the CUPS PPD Compiler " CUPS_SVERSION
420 ".%s", lf);
ac884b6a
MS
421 for (s = (ppdcString *)copyright->first();
422 s;
423 s = (ppdcString *)copyright->next())
424 cupsFilePrintf(fp, "*%% %s%s", catalog->find_message(s->value), lf);
425 cupsFilePrintf(fp, "*FormatVersion: \"4.3\"%s", lf);
426 cupsFilePrintf(fp, "*FileVersion: \"%s\"%s", version->value, lf);
427
428 a = find_attr("LanguageVersion", NULL);
429 cupsFilePrintf(fp, "*LanguageVersion: %s%s",
430 catalog->find_message(a ? a->value->value : "English"), lf);
431
432 a = find_attr("LanguageEncoding", NULL);
433 cupsFilePrintf(fp, "*LanguageEncoding: %s%s",
434 catalog->find_message(a ? a->value->value : "ISOLatin1"), lf);
435
436 cupsFilePrintf(fp, "*PCFileName: \"%s\"%s", pc_file_name->value, lf);
437
438 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
439 if (!strcmp(a->name->value, "Product"))
440 break;
441
442 if (a)
443 {
444 for (; a; a = (ppdcAttr *)attrs->next())
445 if (!strcmp(a->name->value, "Product"))
446 cupsFilePrintf(fp, "*Product: \"%s\"%s", a->value->value, lf);
447 }
448 else
bdd6c45b 449 cupsFilePrintf(fp, "*Product: \"(%s)\"%s", model_name->value, lf);
ac884b6a
MS
450
451 cupsFilePrintf(fp, "*Manufacturer: \"%s\"%s",
452 catalog->find_message(manufacturer->value), lf);
453
454 if ((a = find_attr("ModelName", NULL)) != NULL)
455 cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
456 catalog->find_message(a->value->value), lf);
457 else if (strncasecmp(model_name->value, manufacturer->value,
458 strlen(manufacturer->value)))
459 cupsFilePrintf(fp, "*ModelName: \"%s %s\"%s",
460 catalog->find_message(manufacturer->value),
461 catalog->find_message(model_name->value), lf);
462 else
463 cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
464 catalog->find_message(model_name->value), lf);
465
466 if ((a = find_attr("ShortNickName", NULL)) != NULL)
467 cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
468 catalog->find_message(a->value->value), lf);
469 else if (strncasecmp(model_name->value, manufacturer->value,
470 strlen(manufacturer->value)))
471 cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"%s",
472 catalog->find_message(manufacturer->value),
473 catalog->find_message(model_name->value), lf);
474 else
475 cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
476 catalog->find_message(model_name->value), lf);
477
478 if ((a = find_attr("NickName", NULL)) != NULL)
479 cupsFilePrintf(fp, "*NickName: \"%s\"%s",
480 catalog->find_message(a->value->value), lf);
481 else if (strncasecmp(model_name->value, manufacturer->value,
482 strlen(manufacturer->value)))
483 cupsFilePrintf(fp, "*NickName: \"%s %s, %s\"%s",
484 catalog->find_message(manufacturer->value),
485 catalog->find_message(model_name->value), version->value,
486 lf);
487 else
488 cupsFilePrintf(fp, "*NickName: \"%s, %s\"%s",
489 catalog->find_message(model_name->value), version->value,
490 lf);
491
492 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
493 if (!strcmp(a->name->value, "PSVersion"))
494 break;
495
496 if (a)
497 {
498 for (; a; a = (ppdcAttr *)attrs->next())
499 if (!strcmp(a->name->value, "PSVersion"))
500 cupsFilePrintf(fp, "*PSVersion: \"%s\"%s", a->value->value, lf);
501 }
502 else
bdd6c45b 503 cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 0\"%s", lf);
ac884b6a
MS
504
505 if ((a = find_attr("LanguageLevel", NULL)) != NULL)
506 cupsFilePrintf(fp, "*LanguageLevel: \"%s\"%s", a->value->value, lf);
507 else
508 cupsFilePrintf(fp, "*LanguageLevel: \"3\"%s", lf);
509
510 cupsFilePrintf(fp, "*ColorDevice: %s%s", color_device ? "True" : "False", lf);
511
512 if ((a = find_attr("DefaultColorSpace", NULL)) != NULL)
513 cupsFilePrintf(fp, "*DefaultColorSpace: %s%s", a->value->value, lf);
514 else
515 cupsFilePrintf(fp, "*DefaultColorSpace: %s%s",
516 color_device ? "RGB" : "Gray", lf);
517
518 if ((a = find_attr("FileSystem", NULL)) != NULL)
519 cupsFilePrintf(fp, "*FileSystem: %s%s", a->value->value, lf);
520 else
521 cupsFilePrintf(fp, "*FileSystem: False%s", lf);
522
523 cupsFilePrintf(fp, "*Throughput: \"%d\"%s", throughput, lf);
524
525 if ((a = find_attr("LandscapeOrientation", NULL)) != NULL)
526 cupsFilePrintf(fp, "*LandscapeOrientation: %s%s", a->value->value, lf);
527 else
528 cupsFilePrintf(fp, "*LandscapeOrientation: Plus90%s", lf);
529
530 if ((a = find_attr("TTRasterizer", NULL)) != NULL)
531 cupsFilePrintf(fp, "*TTRasterizer: %s%s", a->value->value, lf);
532 else if (type != PPDC_DRIVER_PS)
533 cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf);
534
535 if (attrs->count)
536 {
537 // Write driver-defined attributes...
538 cupsFilePrintf(fp, "*%% Driver-defined attributes...%s", lf);
539 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
540 {
541 if (!strcmp(a->name->value, "Product") ||
542 !strcmp(a->name->value, "PSVersion") ||
543 !strcmp(a->name->value, "LanguageLevel") ||
544 !strcmp(a->name->value, "DefaultColorSpace") ||
545 !strcmp(a->name->value, "FileSystem") ||
546 !strcmp(a->name->value, "LandscapeOrientation") ||
547 !strcmp(a->name->value, "TTRasterizer") ||
548 !strcmp(a->name->value, "LanguageVersion") ||
549 !strcmp(a->name->value, "LanguageEncoding") ||
550 !strcmp(a->name->value, "ModelName") ||
551 !strcmp(a->name->value, "NickName") ||
552 !strcmp(a->name->value, "ShortNickName") ||
4509bb49 553 !strcmp(a->name->value, "cupsVersion"))
ac884b6a
MS
554 continue;
555
4509bb49
MS
556 if (a->name->value[0] == '?' &&
557 (find_option(a->name->value + 1) ||
558 !strcmp(a->name->value, "?ImageableArea") ||
559 !strcmp(a->name->value, "?PageRegion") ||
560 !strcmp(a->name->value, "?PageSize") ||
561 !strcmp(a->name->value, "?PaperDimension")))
562 continue;
563
f11a948a
MS
564 if (!strncmp(a->name->value, "Custom", 6) &&
565 find_option(a->name->value + 6))
566 continue;
567
568 if (!strncmp(a->name->value, "ParamCustom", 11) &&
569 find_option(a->name->value + 11))
570 continue;
571
ac884b6a
MS
572 if (!a->selector->value || !a->selector->value[0])
573 cupsFilePrintf(fp, "*%s", a->name->value);
574 else if (!a->text->value || !a->text->value[0])
575 cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
576 else
577 cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
578 a->text->value);
579
580 if (strcmp(a->value->value, "False") &&
581 strcmp(a->value->value, "True") &&
582 strcmp(a->name->value, "1284Modes") &&
583 strcmp(a->name->value, "InkName") &&
584 strcmp(a->name->value, "PageStackOrder") &&
585 strncmp(a->name->value, "ParamCustom", 11) &&
586 strcmp(a->name->value, "Protocols") &&
587 strcmp(a->name->value, "ReferencePunch") &&
588 strncmp(a->name->value, "Default", 7))
589 {
590 cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf);
591
f11a948a 592 if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
ac884b6a
MS
593 cupsFilePrintf(fp, "*End%s", lf);
594 }
595 else
596 cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
597 }
598 }
599
600 if (type != PPDC_DRIVER_PS || filters->count)
601 {
602 if ((a = find_attr("cupsVersion", NULL)) != NULL)
603 cupsFilePrintf(fp, "*cupsVersion: %s%s", a->value->value, lf);
604 else
605 cupsFilePrintf(fp, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR,
606 CUPS_VERSION_MINOR, lf);
607 cupsFilePrintf(fp, "*cupsModelNumber: %d%s", model_number, lf);
608 cupsFilePrintf(fp, "*cupsManualCopies: %s%s",
609 manual_copies ? "True" : "False", lf);
610
611 if (filters->count)
612 {
613 for (f = (ppdcFilter *)filters->first();
614 f;
615 f = (ppdcFilter *)filters->next())
616 cupsFilePrintf(fp, "*cupsFilter: \"%s %d %s\"%s", f->mime_type->value,
617 f->cost, f->program->value, lf);
618 }
619 else
620 {
621 switch (type)
622 {
623 case PPDC_DRIVER_LABEL :
624 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
625 "rastertolabel\"%s", lf);
626 break;
627
628 case PPDC_DRIVER_EPSON :
629 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
630 "rastertoepson\"%s", lf);
631 break;
632
633 case PPDC_DRIVER_ESCP :
634 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
635 "commandtoescpx\"%s", lf);
636 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
637 "rastertoescpx\"%s", lf);
638 break;
639
640 case PPDC_DRIVER_HP :
641 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
642 "rastertohp\"%s", lf);
643 break;
644
645 case PPDC_DRIVER_PCL :
646 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
647 "commandtopclx\"%s", lf);
648 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
649 "rastertopclx\"%s", lf);
650 break;
651
652 default :
653 break;
654 }
655 }
656
657 for (p = (ppdcProfile *)profiles->first();
658 p;
659 p = (ppdcProfile *)profiles->next())
660 cupsFilePrintf(fp,
661 "*cupsColorProfile %s/%s: \"%.3f %.3f %.3f %.3f %.3f %.3f "
662 "%.3f %.3f %.3f %.3f %.3f\"%s",
663 p->resolution->value, p->media_type->value,
664 p->density, p->gamma,
665 p->profile[0], p->profile[1],
666 p->profile[2], p->profile[3],
667 p->profile[4], p->profile[5],
668 p->profile[6], p->profile[7],
669 p->profile[8], lf);
670 }
671
672 if (locales)
673 {
674 // Add localizations for additional languages...
675 ppdcString *locale; // Locale name
676 ppdcCatalog *locatalog; // Message catalog for locale
677
678
679 // Write the list of languages...
680 cupsFilePrintf(fp, "*cupsLanguages: \"en");
681
682 for (locale = (ppdcString *)locales->first();
683 locale;
684 locale = (ppdcString *)locales->next())
685 {
686 // Skip (US) English...
687 if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
688 continue;
689
690 // See if we have a po file for this language...
691 if (!src->find_po(locale->value))
692 {
693 // No, see if we can use the base file?
694 locatalog = new ppdcCatalog(locale->value);
695
696 if (locatalog->messages->count == 0)
697 {
698 // No, skip this one...
61cf44e2
MS
699 _cupsLangPrintf(stderr,
700 _("ppdc: No message catalog provided for locale "
701 "%s!\n"), locale->value);
ac884b6a
MS
702 continue;
703 }
704
705 // Add the base file to the list...
706 src->po_files->add(locatalog);
707 }
708
709 cupsFilePrintf(fp, " %s", locale->value);
710 }
711
712 cupsFilePrintf(fp, "\"%s", lf);
713 }
714
715 for (cn = (ppdcConstraint *)constraints->first();
716 cn;
717 cn = (ppdcConstraint *)constraints->next())
718 {
719 // First constrain 1 against 2...
720 if (!strncmp(cn->option1->value, "*Custom", 7) ||
721 !strncmp(cn->option2->value, "*Custom", 7))
61cf44e2 722 cupsFilePuts(fp, "*NonUIConstraints: ");
ac884b6a 723 else
61cf44e2 724 cupsFilePuts(fp, "*UIConstraints: ");
ac884b6a
MS
725
726 if (cn->option1->value[0] != '*')
727 cupsFilePutChar(fp, '*');
728
61cf44e2 729 cupsFilePuts(fp, cn->option1->value);
ac884b6a
MS
730
731 if (cn->choice1->value)
732 cupsFilePrintf(fp, " %s", cn->choice1->value);
733
734 cupsFilePutChar(fp, ' ');
735
736 if (cn->option2->value[0] != '*')
737 cupsFilePutChar(fp, '*');
738
61cf44e2 739 cupsFilePuts(fp, cn->option2->value);
ac884b6a
MS
740
741 if (cn->choice2->value)
742 cupsFilePrintf(fp, " %s", cn->choice2->value);
743
61cf44e2 744 cupsFilePuts(fp, lf);
ac884b6a
MS
745
746 // Then constrain 2 against 1...
747 if (!strncmp(cn->option1->value, "*Custom", 7) ||
748 !strncmp(cn->option2->value, "*Custom", 7))
61cf44e2 749 cupsFilePuts(fp, "*NonUIConstraints: ");
ac884b6a 750 else
61cf44e2 751 cupsFilePuts(fp, "*UIConstraints: ");
ac884b6a
MS
752
753 if (cn->option2->value[0] != '*')
754 cupsFilePutChar(fp, '*');
755
61cf44e2 756 cupsFilePuts(fp, cn->option2->value);
ac884b6a
MS
757
758 if (cn->choice2->value)
759 cupsFilePrintf(fp, " %s", cn->choice2->value);
760
761 cupsFilePutChar(fp, ' ');
762
763 if (cn->option1->value[0] != '*')
764 cupsFilePutChar(fp, '*');
765
61cf44e2 766 cupsFilePuts(fp, cn->option1->value);
ac884b6a
MS
767
768 if (cn->choice1->value)
769 cupsFilePrintf(fp, " %s", cn->choice1->value);
770
771 cupsFilePuts(fp, lf);
772 }
773
774 // PageSize option...
775 cupsFilePrintf(fp, "*OpenUI *PageSize/Media Size: PickOne%s", lf);
776 cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageSize%s", lf);
777 cupsFilePrintf(fp, "*DefaultPageSize: %s%s",
778 default_size ? default_size->value : "Letter", lf);
779
780 for (m = (ppdcMediaSize *)sizes->first();
781 m;
782 m = (ppdcMediaSize *)sizes->next())
783 if (m->size_code->value)
784 {
785 cupsFilePrintf(fp, "*PageSize %s/%s: \"%s\"%s",
786 m->name->value, catalog->find_message(m->text->value),
787 m->size_code->value, lf);
788
789 if (strchr(m->size_code->value, '\n') ||
790 strchr(m->size_code->value, '\r'))
791 cupsFilePrintf(fp, "*End%s", lf);
792 }
793 else
794 cupsFilePrintf(fp,
795 "*PageSize %s/%s: \"<</PageSize[%.0f %.0f]"
796 "/ImagingBBox null>>setpagedevice\"%s",
797 m->name->value, catalog->find_message(m->text->value),
798 m->width, m->length, lf);
799
800 if ((a = find_attr("?PageSize", NULL)) != NULL)
801 {
802 cupsFilePrintf(fp, "*?PageSize: \"%s\"%s", a->value->value, lf);
803
804 if (strchr(a->value->value, '\n') ||
805 strchr(a->value->value, '\r'))
806 cupsFilePrintf(fp, "*End%s", lf);
807 }
808
809 cupsFilePrintf(fp, "*CloseUI: *PageSize%s", lf);
810
811 // PageRegion option...
812 cupsFilePrintf(fp, "*OpenUI *PageRegion/Media Size: PickOne%s", lf);
813 cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageRegion%s", lf);
814 cupsFilePrintf(fp, "*DefaultPageRegion: %s%s",
815 default_size ? default_size->value : "Letter", lf);
816
817 for (m = (ppdcMediaSize *)sizes->first();
818 m;
819 m = (ppdcMediaSize *)sizes->next())
820 if (m->region_code->value)
821 {
822 cupsFilePrintf(fp, "*PageRegion %s/%s: \"%s\"%s",
823 m->name->value, catalog->find_message(m->text->value),
824 m->region_code->value, lf);
825
826 if (strchr(m->region_code->value, '\n') ||
827 strchr(m->region_code->value, '\r'))
828 cupsFilePrintf(fp, "*End%s", lf);
829 }
830 else
831 cupsFilePrintf(fp,
832 "*PageRegion %s/%s: \"<</PageSize[%.0f %.0f]"
833 "/ImagingBBox null>>setpagedevice\"%s",
834 m->name->value, catalog->find_message(m->text->value),
835 m->width, m->length, lf);
836
837 if ((a = find_attr("?PageRegion", NULL)) != NULL)
838 {
839 cupsFilePrintf(fp, "*?PageRegion: \"%s\"%s", a->value->value, lf);
840
841 if (strchr(a->value->value, '\n') ||
842 strchr(a->value->value, '\r'))
843 cupsFilePrintf(fp, "*End%s", lf);
844 }
845
846 cupsFilePrintf(fp, "*CloseUI: *PageRegion%s", lf);
847
848 // ImageableArea info...
849 cupsFilePrintf(fp, "*DefaultImageableArea: %s%s",
850 default_size ? default_size->value : "Letter", lf);
851
852 for (m = (ppdcMediaSize *)sizes->first();
853 m;
854 m = (ppdcMediaSize *)sizes->next())
855 cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%.2f %.2f %.2f %.2f\"%s",
856 m->name->value, catalog->find_message(m->text->value),
857 m->left, m->bottom, m->width - m->right, m->length - m->top,
858 lf);
859
860 if ((a = find_attr("?ImageableArea", NULL)) != NULL)
861 {
862 cupsFilePrintf(fp, "*?ImageableArea: \"%s\"%s", a->value->value, lf);
863
864 if (strchr(a->value->value, '\n') ||
865 strchr(a->value->value, '\r'))
866 cupsFilePrintf(fp, "*End%s", lf);
867 }
868
869 // PaperDimension info...
870 cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s",
871 default_size ? default_size->value : "Letter", lf);
872
873 for (m = (ppdcMediaSize *)sizes->first();
874 m;
875 m = (ppdcMediaSize *)sizes->next())
876 cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%.2f %.2f\"%s",
877 m->name->value, catalog->find_message(m->text->value),
878 m->width, m->length, lf);
879
880 if ((a = find_attr("?PaperDimension", NULL)) != NULL)
881 {
882 cupsFilePrintf(fp, "*?PaperDimension: \"%s\"%s", a->value->value, lf);
883
884 if (strchr(a->value->value, '\n') ||
885 strchr(a->value->value, '\r'))
886 cupsFilePrintf(fp, "*End%s", lf);
887 }
888
889 // Custom size support...
890 if (variable_paper_size)
891 {
892 cupsFilePrintf(fp, "*MaxMediaWidth: \"%.2f\"%s", max_width, lf);
893 cupsFilePrintf(fp, "*MaxMediaHeight: \"%.2f\"%s", max_length, lf);
894 cupsFilePrintf(fp, "*HWMargins: %.2f %.2f %.2f %.2f\n",
895 left_margin, bottom_margin, right_margin, top_margin);
896
897 if (custom_size_code && custom_size_code->value)
898 {
899 cupsFilePrintf(fp, "*CustomPageSize True: \"%s\"%s",
900 custom_size_code->value, lf);
901
902 if (strchr(custom_size_code->value, '\n') ||
903 strchr(custom_size_code->value, '\r'))
904 cupsFilePrintf(fp, "*End%s", lf);
905 }
906 else
907 cupsFilePrintf(fp,
908 "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]"
909 "/ImagingBBox null>>setpagedevice\"%s", lf);
910
911 if ((a = find_attr("ParamCustomPageSize", "Width")) != NULL)
912 cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value,
913 lf);
914 else
915 cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %.2f %.2f%s",
916 min_width, max_width, lf);
917
918 if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL)
919 cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value,
920 lf);
921 else
922 cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %.2f %.2f%s",
923 min_length, max_length, lf);
924
925 if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL)
926 cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s",
927 a->value->value, lf);
928 else
929 cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0%s", lf);
930
931 if ((a = find_attr("ParamCustomPageSize", "HeightOffset")) != NULL)
932 cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: %s%s",
933 a->value->value, lf);
934 else
935 cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0%s", lf);
936
937 if ((a = find_attr("ParamCustomPageSize", "Orientation")) != NULL)
938 cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: %s%s",
939 a->value->value, lf);
940 else
941 cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf);
942 }
943
ac884b6a
MS
944 // All other options...
945 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
946 {
947 if (!g->options->count)
948 continue;
949
950 if (strcasecmp(g->name->value, "General"))
951 cupsFilePrintf(fp, "*OpenGroup: %s/%s%s", g->name->value,
952 catalog->find_message(g->text->value), lf);
953
954 for (o = (ppdcOption *)g->options->first();
955 o;
956 o = (ppdcOption *)g->options->next())
957 {
958 if (!o->choices->count)
959 continue;
960
961 if (!o->text->value || !strcmp(o->name->value, o->text->value))
d1c13e16 962 cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
d2354e63 963 catalog->find_message(o->name->value));
ac884b6a
MS
964 else
965 cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
966 catalog->find_message(o->text->value));
967
968 switch (o->type)
969 {
970 case PPDC_BOOLEAN :
971 cupsFilePrintf(fp, "Boolean%s", lf);
972 break;
973 default :
974 cupsFilePrintf(fp, "PickOne%s", lf);
975 break;
976 case PPDC_PICKMANY :
977 cupsFilePrintf(fp, "PickMany%s", lf);
978 break;
979 }
980
981 cupsFilePrintf(fp, "*OrderDependency: %.1f ", o->order);
982 switch (o->section)
983 {
984 default :
985 cupsFilePrintf(fp, "AnySetup");
986 break;
987 case PPDC_SECTION_DOCUMENT :
988 cupsFilePrintf(fp, "DocumentSetup");
989 break;
990 case PPDC_SECTION_EXIT :
991 cupsFilePrintf(fp, "ExitServer");
992 break;
993 case PPDC_SECTION_JCL :
994 cupsFilePrintf(fp, "JCLSetup");
995 break;
996 case PPDC_SECTION_PAGE :
997 cupsFilePrintf(fp, "PageSetup");
998 break;
999 case PPDC_SECTION_PROLOG :
1000 cupsFilePrintf(fp, "Prolog");
1001 break;
1002 }
1003
1004 cupsFilePrintf(fp, " *%s%s", o->name->value, lf);
1005
1006 if (o->defchoice)
1007 {
1008 // Use the programmer-supplied default...
1009 cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value,
1010 o->defchoice->value, lf);
1011 }
1012 else
1013 {
1014 // Make the first choice the default...
1015 c = (ppdcChoice *)o->choices->first();
1016 cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value, c->name->value,
1017 lf);
1018 }
1019
1020 for (c = (ppdcChoice *)o->choices->first();
1021 c;
1022 c = (ppdcChoice *)o->choices->next())
1023 {
1024 // Write this choice...
1025 if (!c->text->value || !strcmp(c->name->value, c->text->value))
d2354e63
MS
1026 cupsFilePrintf(fp, "*%s %s: \"%s\"%s", o->name->value,
1027 catalog->find_message(c->name->value),
ac884b6a
MS
1028 c->code->value, lf);
1029 else
1030 cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value,
1031 c->name->value, catalog->find_message(c->text->value),
1032 c->code->value, lf);
1033
1034 // Multi-line commands need a *End line to terminate them.
1035 if (strchr(c->code->value, '\n') ||
1036 strchr(c->code->value, '\r'))
1037 cupsFilePrintf(fp, "*End%s", lf);
1038 }
1039
1040 snprintf(query, sizeof(query), "?%s", o->name->value);
1041
1042 if ((a = find_attr(query, NULL)) != NULL)
1043 {
f11a948a 1044 cupsFilePrintf(fp, "*%s: \"%s\"%s", query, a->value->value, lf);
ac884b6a
MS
1045
1046 if (strchr(a->value->value, '\n') ||
1047 strchr(a->value->value, '\r'))
1048 cupsFilePrintf(fp, "*End%s", lf);
1049 }
1050
1051 cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf);
f11a948a
MS
1052
1053 snprintf(custom, sizeof(custom), "Custom%s", o->name->value);
1054 if ((a = find_attr(custom, "True")) != NULL)
1055 {
1056 // Output custom option information...
1057 cupsFilePrintf(fp, "*%s True: \"%s\"%s", custom, a->value->value, lf);
1058 if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
1059 cupsFilePrintf(fp, "*End%s", lf);
1060
1061 snprintf(custom, sizeof(custom), "ParamCustom%s", o->name->value);
1062 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
1063 {
1064 if (strcmp(a->name->value, custom))
1065 continue;
1066
1067 if (!a->selector->value || !a->selector->value[0])
1068 cupsFilePrintf(fp, "*%s", a->name->value);
1069 else if (!a->text->value || !a->text->value[0])
1070 cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
1071 else
1072 cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
1073 a->text->value);
1074
1075 cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
1076 }
1077 }
ac884b6a
MS
1078 }
1079
1080 if (strcasecmp(g->name->value, "General"))
1081 cupsFilePrintf(fp, "*CloseGroup: %s%s", g->name->value, lf);
1082 }
1083
1084 if (locales)
1085 {
1086 // Add localizations for additional languages...
1087 ppdcString *locale; // Locale name
1088 ppdcCatalog *locatalog; // Message catalog for locale
1089
1090
1091 // Write the translation strings for each language...
1092 for (locale = (ppdcString *)locales->first();
1093 locale;
1094 locale = (ppdcString *)locales->next())
1095 {
1096 // Skip (US) English...
1097 if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
1098 continue;
1099
1100 // Skip missing languages...
1101 if ((locatalog = src->find_po(locale->value)) == NULL)
1102 continue;
1103
1104 // Do the core stuff first...
1105 cupsFilePrintf(fp, "*%s.Translation Manufacturer/%s: \"\"%s",
1106 locale->value,
1107 locatalog->find_message(manufacturer->value), lf);
1108
1109 if ((a = find_attr("ModelName", NULL)) != NULL)
1110 cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
1111 locale->value,
1112 locatalog->find_message(a->value->value), lf);
1113 else if (strncasecmp(model_name->value, manufacturer->value,
1114 strlen(manufacturer->value)))
1115 cupsFilePrintf(fp, "*%s.Translation ModelName/%s %s: \"\"%s",
1116 locale->value,
1117 locatalog->find_message(manufacturer->value),
1118 locatalog->find_message(model_name->value), lf);
1119 else
1120 cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
1121 locale->value,
1122 locatalog->find_message(model_name->value), lf);
1123
1124 if ((a = find_attr("ShortNickName", NULL)) != NULL)
1125 cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
1126 locale->value,
1127 locatalog->find_message(a->value->value), lf);
1128 else if (strncasecmp(model_name->value, manufacturer->value,
1129 strlen(manufacturer->value)))
1130 cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s %s: \"\"%s",
1131 locale->value,
1132 locatalog->find_message(manufacturer->value),
1133 locatalog->find_message(model_name->value), lf);
1134 else
1135 cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
1136 locale->value,
1137 locatalog->find_message(model_name->value), lf);
1138
1139 if ((a = find_attr("NickName", NULL)) != NULL)
1140 cupsFilePrintf(fp, "*%s.Translation NickName/%s: \"\"%s",
1141 locale->value,
1142 locatalog->find_message(a->value->value), lf);
1143 else if (strncasecmp(model_name->value, manufacturer->value,
1144 strlen(manufacturer->value)))
1145 cupsFilePrintf(fp, "*%s.Translation NickName/%s %s, %s: \"\"%s",
1146 locale->value,
1147 locatalog->find_message(manufacturer->value),
1148 locatalog->find_message(model_name->value),
1149 version->value, lf);
1150 else
1151 cupsFilePrintf(fp, "*%s.Translation NickName/%s, %s: \"\"%s",
1152 locale->value,
1153 locatalog->find_message(model_name->value),
1154 version->value, lf);
1155
1156 // Then the page sizes...
1157 cupsFilePrintf(fp, "*%s.Translation PageSize/%s: \"\"%s", locale->value,
1158 locatalog->find_message("Media Size"), lf);
1159
1160 for (m = (ppdcMediaSize *)sizes->first();
1161 m;
1162 m = (ppdcMediaSize *)sizes->next())
1163 {
1164 cupsFilePrintf(fp, "*%s.PageSize %s/%s: \"\"%s", locale->value,
1165 m->name->value, locatalog->find_message(m->text->value),
1166 lf);
1167 }
1168
1169 // Next the groups and options...
1170 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
1171 {
1172 if (!g->options->count)
1173 continue;
1174
1175 if (strcasecmp(g->name->value, "General"))
1176 cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
1177 g->name->value,
1178 locatalog->find_message(g->text->value), lf);
1179
1180 for (o = (ppdcOption *)g->options->first();
1181 o;
1182 o = (ppdcOption *)g->options->next())
1183 {
1184 if (!o->choices->count)
1185 continue;
1186
1187 cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
1188 o->name->value,
1189 locatalog->find_message(o->text->value ?
1190 o->text->value :
1191 o->name->value), lf);
1192
1193 for (c = (ppdcChoice *)o->choices->first();
1194 c;
1195 c = (ppdcChoice *)o->choices->next())
1196 {
1197 // Write this choice...
1198 cupsFilePrintf(fp, "*%s.%s %s/%s: \"\"%s", locale->value,
1199 o->name->value, c->name->value,
1200 locatalog->find_message(c->text->value ?
1201 c->text->value :
1202 c->name->value), lf);
1203 }
1204 }
1205 }
1206
1207 // Finally the localizable attributes...
1208 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
1209 {
1210 if ((!a->text || !a->text->value || !a->text->value[0]) &&
1211 strncmp(a->name->value, "Custom", 6) &&
1212 strncmp(a->name->value, "ParamCustom", 11))
1213 continue;
1214
bdd6c45b
MS
1215 if (!a->localizable &&
1216 strcmp(a->name->value, "APCustomColorMatchingName") &&
ac884b6a
MS
1217 strcmp(a->name->value, "APPrinterPreset") &&
1218 strcmp(a->name->value, "cupsICCProfile") &&
1219 strcmp(a->name->value, "cupsIPPReason") &&
bdd6c45b 1220 strcmp(a->name->value, "cupsMarkerName") &&
ac884b6a
MS
1221 strncmp(a->name->value, "Custom", 6) &&
1222 strncmp(a->name->value, "ParamCustom", 11))
1223 continue;
1224
1225 cupsFilePrintf(fp, "*%s.%s %s/%s: \"%s\"%s", locale->value,
1226 a->name->value, a->selector->value,
1227 locatalog->find_message(a->text && a->text->value ?
1228 a->text->value : a->name->value),
bdd6c45b
MS
1229 ((a->localizable && a->value->value[0]) ||
1230 !strcmp(a->name->value, "cupsIPPReason")) ?
ac884b6a
MS
1231 locatalog->find_message(a->value->value) : "",
1232 lf);
1233 }
1234 }
1235 }
1236
1237 if (default_font && default_font->value)
1238 cupsFilePrintf(fp, "*DefaultFont: %s%s", default_font->value, lf);
1239 else
1240 cupsFilePrintf(fp, "*DefaultFont: Courier%s", lf);
1241
1242 for (fn = (ppdcFont *)fonts->first(); fn; fn = (ppdcFont *)fonts->next())
1243 if (!strcmp(fn->name->value, "*"))
1244 {
1245 for (bfn = (ppdcFont *)src->base_fonts->first();
1246 bfn;
1247 bfn = (ppdcFont *)src->base_fonts->next())
1248 cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
1249 bfn->name->value, bfn->encoding->value,
1250 bfn->version->value, bfn->charset->value,
1251 bfn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
1252 }
1253 else
1254 cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
1255 fn->name->value, fn->encoding->value, fn->version->value,
1256 fn->charset->value,
1257 fn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
1258
1259 cupsFilePrintf(fp, "*%% End of %s, %05d bytes.%s", pc_file_name->value,
1260 (int)(cupsFileTell(fp) + 25 + strlen(pc_file_name->value)),
1261 lf);
1262
1263 if (delete_cat)
e4572d57 1264 catalog->release();
ac884b6a
MS
1265
1266 return (0);
1267}
1268
1269
1270//
1271// End of "$Id$".
1272//