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