1// 2// "$Id: ppdc-driver.cxx 3942 2012-10-15 21:05:33Z msweet $" 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 45ppdcDriver::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 146ppdcDriver::~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 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])) || 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 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 (!_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 222ppdcOption * // O - Matching option or NULL 223ppdcDriver::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 233ppdcOption * // O - Matching option or NULL 234ppdcDriver::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 263void 264ppdcDriver::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 278void 279ppdcDriver::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 299void 300ppdcDriver::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 320void 321ppdcDriver::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 334void 335ppdcDriver::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 349void 350ppdcDriver::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 364void 365ppdcDriver::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 379void 380ppdcDriver::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 393int // O - 0 on success, -1 on failure 394ppdcDriver::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: ppdc-driver.cxx 3942 2012-10-15 21:05:33Z msweet $". 1348// 1349