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