]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/pwg-ppd.c
Merge changes from CUPS 1.5svn-r9049 (private header support)
[thirdparty/cups.git] / cups / pwg-ppd.c
CommitLineData
54afec33
MS
1/*
2 * "$Id$"
3 *
4 * PWG PPD mapping API implementation for CUPS.
5 *
6 * Copyright 2010 by Apple Inc.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
13 *
14 * This file is subject to the Apple OS-Developed Software exception.
15 *
16 * Contents:
17 *
18 * _pwgCreateWithPPD() - Create PWG mapping data from a PPD file.
19 * _pwgGetInputSlot() - Get the PPD InputSlot associated with the job
20 * attributes or a keyword string.
21 * _pwgGetMediaType() - Get the PPD MediaType associated with the job
22 * attributes or a keyword string.
23 * _pwgGetPageSize() - Get the PPD PageSize associated with the job
24 * attributes or a keyword string.
25 * _pwgGetSize() - Get the PWG size associated with a PPD PageSize.
26 * _pwgGetSource() - Get the PWG media-source associated with a PPD
27 * InputSlot.
28 * _pwgGetType() - Get the PWG media-type associated with a PPD
29 * MediaType.
30 * _pwgInputSlotForSource() - Get the InputSlot name for the given PWG source.
31 * _pwgMediaTypeForType() - Get the MediaType name for the given PWG type.
32 * _pwgPageSizeForMedia() - Get the PageSize name for the given media.
33 * pwg_ppdize_name() - Convert an IPP keyword to a PPD keyword.
34 * pwg_unppdize_name() - Convert a PPD keyword to a lowercase IPP
35 * keyword.
36 */
37
38/*
39 * Include necessary headers...
40 */
41
71e16022 42#include "cups-private.h"
54afec33
MS
43#include <math.h>
44
45
46/*
47 * Local functions...
48 */
49
50static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
51static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize);
52
53
54/*
55 * '_pwgCreateWithPPD()' - Create PWG mapping data from a PPD file.
56 */
57
58_pwg_t * /* O - PWG mapping data */
59_pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
60{
61 int i, j; /* Looping vars */
62 _pwg_t *pwg; /* PWG mapping data */
63 ppd_option_t *input_slot, /* InputSlot option */
64 *media_type; /* MediaType option */
65 ppd_choice_t *choice; /* Current InputSlot/MediaType */
66 _pwg_map_t *map; /* Current source/type map */
67 ppd_size_t *ppd_size; /* Current PPD size */
68 _pwg_size_t *pwg_size; /* Current PWG size */
69 char pwg_keyword[3 + PPD_MAX_NAME + 1 + 12 + 1 + 12 + 3],
70 /* PWG keyword string */
71 ppd_name[PPD_MAX_NAME]; /* Normalized PPD name */
72 const char *pwg_name; /* Standard PWG media name */
73 _pwg_media_t *pwg_media; /* PWG media data */
74 struct lconv *loc; /* Locale conversion data */
75
76
77 DEBUG_printf(("_pwgCreateWithPPD(ppd=%p)", ppd));
78
79 /*
80 * Range check input...
81 */
82
83 if (!ppd)
84 return (NULL);
85
86 /*
87 * Allocate memory...
88 */
89
90 if ((pwg = calloc(1, sizeof(_pwg_t))) == NULL)
91 {
92 DEBUG_puts("_pwgCreateWithPPD: Unable to allocate _pwg_t.");
93 goto create_error;
94 }
95
96 /*
97 * Copy and convert size data...
98 */
99
100 if (ppd->num_sizes == 0)
101 {
102 DEBUG_puts("_pwgCreateWithPPD: No page sizes in PPD.");
103 goto create_error;
104 }
105
106 if ((pwg->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
107 {
108 DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_size_t's.",
109 ppd->num_sizes));
110 goto create_error;
111 }
112
113 loc = localeconv();
114
115 for (i = ppd->num_sizes, pwg_size = pwg->sizes, ppd_size = ppd->sizes;
116 i > 0;
117 i --, ppd_size ++)
118 {
119 /*
120 * Don't copy over custom size...
121 */
122
123 if (!strcasecmp(ppd_size->name, "Custom"))
124 continue;
125
126 /*
127 * Convert the PPD size name to the corresponding PWG keyword name.
128 */
129
130 if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL)
131 {
132 /*
133 * Standard name, do we have conflicts?
134 */
135
136 for (j = 0; j < pwg->num_sizes; j ++)
137 if (!strcmp(pwg->sizes[j].map.pwg, pwg_media->pwg))
138 {
139 pwg_media = NULL;
140 break;
141 }
142 }
143
144 if (pwg_media)
145 {
146 /*
147 * Standard name and no conflicts, use it!
148 */
149
150 pwg_name = pwg_media->pwg;
151 }
152 else
153 {
154 /*
155 * Not a standard name; convert it to a PWG vendor name of the form:
156 *
157 * pp_lowerppd_WIDTHxHEIGHTuu
158 */
159
160 pwg_name = pwg_keyword;
161
162 pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name));
163 _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
164 _PWG_FROMPTS(ppd_size->width),
165 _PWG_FROMPTS(ppd_size->length));
166 }
167
168 /*
169 * Save this size...
170 */
171
172 pwg_size->map.ppd = _cupsStrAlloc(ppd_size->name);
173 pwg_size->map.pwg = _cupsStrAlloc(pwg_name);
174 pwg_size->width = _PWG_FROMPTS(ppd_size->width);
175 pwg_size->length = _PWG_FROMPTS(ppd_size->length);
176 pwg_size->left = _PWG_FROMPTS(ppd_size->left);
177 pwg_size->bottom = _PWG_FROMPTS(ppd_size->bottom);
178 pwg_size->right = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
179 pwg_size->top = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
180
181 pwg->num_sizes ++;
182 pwg_size ++;
183 }
184
185 if (ppd->variable_sizes)
186 {
187 /*
188 * Generate custom size data...
189 */
190
191 _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
192 _PWG_FROMPTS(ppd->custom_max[0]),
193 _PWG_FROMPTS(ppd->custom_max[1]));
194 pwg->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
195 pwg->custom_max_width = _PWG_FROMPTS(ppd->custom_max[0]);
196 pwg->custom_max_length = _PWG_FROMPTS(ppd->custom_max[1]);
197
198 _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
199 _PWG_FROMPTS(ppd->custom_min[0]),
200 _PWG_FROMPTS(ppd->custom_min[1]));
201 pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
202 pwg->custom_min_width = _PWG_FROMPTS(ppd->custom_min[0]);
203 pwg->custom_min_length = _PWG_FROMPTS(ppd->custom_min[1]);
204
205 pwg->custom_size.left = _PWG_FROMPTS(ppd->custom_margins[0]);
206 pwg->custom_size.bottom = _PWG_FROMPTS(ppd->custom_margins[1]);
207 pwg->custom_size.right = _PWG_FROMPTS(ppd->custom_margins[2]);
208 pwg->custom_size.top = _PWG_FROMPTS(ppd->custom_margins[3]);
209 }
210
211 /*
212 * Copy and convert InputSlot data...
213 */
214
215 if ((input_slot = ppdFindOption(ppd, "InputSlot")) != NULL)
216 {
217 if ((pwg->sources = calloc(input_slot->num_choices,
218 sizeof(_pwg_map_t))) == NULL)
219 {
220 DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's "
221 "for InputSlot.", input_slot->num_choices));
222 goto create_error;
223 }
224
225 pwg->num_sources = input_slot->num_choices;
226
227 for (i = input_slot->num_choices, choice = input_slot->choices,
228 map = pwg->sources;
229 i > 0;
230 i --, choice ++, map ++)
231 {
232 if (!strncasecmp(choice->choice, "Auto", 4) ||
233 !strcasecmp(choice->choice, "Default"))
234 pwg_name = "auto";
235 else if (!strcasecmp(choice->choice, "Cassette"))
236 pwg_name = "main-tray";
237 else if (!strncasecmp(choice->choice, "Multipurpose", 12) ||
238 !strcasecmp(choice->choice, "MP") ||
239 !strcasecmp(choice->choice, "MPTray"))
240 pwg_name = "alternate-tray";
241 else if (!strcasecmp(choice->choice, "LargeCapacity"))
242 pwg_name = "large-capacity-tray";
243 else if (!strncasecmp(choice->choice, "Lower", 5))
244 pwg_name = "bottom-tray";
245 else if (!strncasecmp(choice->choice, "Middle", 6))
246 pwg_name = "middle-tray";
247 else if (!strncasecmp(choice->choice, "Upper", 5))
248 pwg_name = "top-tray";
249 else if (!strcasecmp(choice->choice, "Rear"))
250 pwg_name = "rear-feed";
251 else if (!strncasecmp(choice->choice, "Side", 4))
252 pwg_name = "side-feed";
253 else if (!strcasecmp(choice->choice, "Envelope"))
254 pwg_name = "envelope-feed";
255 else if (!strcasecmp(choice->choice, "Manual"))
256 pwg_name = "manual-feed";
257 else if (!strcasecmp(choice->choice, "Roll") ||
258 !strcasecmp(choice->choice, "Roll"))
259 pwg_name = "main-roll";
260 else if (!strcasecmp(choice->choice, "Roll2"))
261 pwg_name = "alternate-roll";
262 else
263 {
264 /*
265 * Convert PPD name to lowercase...
266 */
267
268 pwg_name = pwg_keyword;
269 pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword));
270 }
271
272 map->pwg = _cupsStrAlloc(pwg_name);
273 map->ppd = _cupsStrAlloc(choice->choice);
274 }
275 }
276
277 /*
278 * Copy and convert MediaType data...
279 */
280
281 if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
282 {
283 if ((pwg->types = calloc(media_type->num_choices,
284 sizeof(_pwg_map_t))) == NULL)
285 {
286 DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's "
287 "for MediaType.", input_slot->num_choices));
288 goto create_error;
289 }
290
291 pwg->num_types = media_type->num_choices;
292
293 for (i = media_type->num_choices, choice = media_type->choices,
294 map = pwg->types;
295 i > 0;
296 i --, choice ++, map ++)
297 {
298 if (!strncasecmp(choice->choice, "Auto", 4) ||
299 !strcasecmp(choice->choice, "Any") ||
300 !strcasecmp(choice->choice, "Default"))
301 pwg_name = "auto";
302 else if (!strncasecmp(choice->choice, "Card", 4))
303 pwg_name = "cardstock";
304 else if (!strncasecmp(choice->choice, "Env", 3))
305 pwg_name = "envelope";
306 else if (!strncasecmp(choice->choice, "Gloss", 5))
307 pwg_name = "photographic-glossy";
308 else if (!strcasecmp(choice->choice, "HighGloss"))
309 pwg_name = "photographic-high-gloss";
310 else if (!strcasecmp(choice->choice, "Matte"))
311 pwg_name = "photographic-matte";
312 else if (!strncasecmp(choice->choice, "Plain", 5))
313 pwg_name = "stationery";
314 else if (!strncasecmp(choice->choice, "Coated", 6))
315 pwg_name = "stationery-coated";
316 else if (!strcasecmp(choice->choice, "Inkjet"))
317 pwg_name = "stationery-inkjet";
318 else if (!strcasecmp(choice->choice, "Letterhead"))
319 pwg_name = "stationery-letterhead";
320 else if (!strncasecmp(choice->choice, "Preprint", 8))
321 pwg_name = "stationery-preprinted";
322 else if (!strncasecmp(choice->choice, "Transparen", 10))
323 pwg_name = "transparency";
324 else
325 {
326 /*
327 * Convert PPD name to lowercase...
328 */
329
330 pwg_name = pwg_keyword;
331 pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword));
332 }
333
334 map->pwg = _cupsStrAlloc(pwg_name);
335 map->ppd = _cupsStrAlloc(choice->choice);
336 }
337 }
338
339 return (pwg);
340
341 /*
342 * If we get here we need to destroy the PWG mapping data and return NULL...
343 */
344
345 create_error:
346
347 _cupsSetError(IPP_INTERNAL_ERROR, _("Out of memory."), 1);
348 _pwgDestroy(pwg);
349
350 return (NULL);
351}
352
353
354/*
355 * '_pwgGetInputSlot()' - Get the PPD InputSlot associated with the job
356 * attributes or a keyword string.
357 */
358
359const char * /* O - PPD InputSlot or NULL */
360_pwgGetInputSlot(_pwg_t *pwg, /* I - PWG mapping data */
361 ipp_t *job, /* I - Job attributes or NULL */
362 const char *keyword) /* I - Keyword string or NULL */
363{
364 /*
365 * Range check input...
366 */
367
368 if (!pwg || pwg->num_sources == 0 || (!job && !keyword))
369 return (NULL);
370
371 if (job && !keyword)
372 {
373 /*
374 * Lookup the media-col attribute and any media-source found there...
375 */
376
377 ipp_attribute_t *media_col, /* media-col attribute */
378 *media_source; /* media-source attribute */
379
380 media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION);
381 if (media_col &&
382 (media_source = ippFindAttribute(media_col->values[0].collection,
383 "media-source",
384 IPP_TAG_KEYWORD)) != NULL)
385 keyword = media_source->values[0].string.text;
386 }
387
388 if (keyword)
389 {
390 int i; /* Looping var */
391
392 for (i = 0; i < pwg->num_sources; i ++)
393 if (!strcasecmp(keyword, pwg->sources[i].pwg))
394 return (pwg->sources[i].ppd);
395 }
396
397 return (NULL);
398}
399
400
401/*
402 * '_pwgGetMediaType()' - Get the PPD MediaType associated with the job
403 * attributes or a keyword string.
404 */
405
406const char * /* O - PPD MediaType or NULL */
407_pwgGetMediaType(_pwg_t *pwg, /* I - PWG mapping data */
408 ipp_t *job, /* I - Job attributes or NULL */
409 const char *keyword) /* I - Keyword string or NULL */
410{
411 /*
412 * Range check input...
413 */
414
415 if (!pwg || pwg->num_types == 0 || (!job && !keyword))
416 return (NULL);
417
418 if (job && !keyword)
419 {
420 /*
421 * Lookup the media-col attribute and any media-source found there...
422 */
423
424 ipp_attribute_t *media_col, /* media-col attribute */
425 *media_type; /* media-type attribute */
426
427 media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION);
428 if (media_col)
429 {
430 if ((media_type = ippFindAttribute(media_col->values[0].collection,
431 "media-type",
432 IPP_TAG_KEYWORD)) == NULL)
433 media_type = ippFindAttribute(media_col->values[0].collection,
434 "media-type", IPP_TAG_NAME);
435
436 if (media_type)
437 keyword = media_type->values[0].string.text;
438 }
439 }
440
441 if (keyword)
442 {
443 int i; /* Looping var */
444
445 for (i = 0; i < pwg->num_types; i ++)
446 if (!strcasecmp(keyword, pwg->types[i].pwg))
447 return (pwg->types[i].ppd);
448 }
449
450 return (NULL);
451}
452
453
454/*
455 * '_pwgGetPageSize()' - Get the PPD PageSize associated with the job
456 * attributes or a keyword string.
457 */
458
459const char * /* O - PPD PageSize or NULL */
460_pwgGetPageSize(_pwg_t *pwg, /* I - PWG mapping data */
461 ipp_t *job, /* I - Job attributes or NULL */
462 const char *keyword, /* I - Keyword string or NULL */
463 int *exact) /* I - 1 if exact match, 0 otherwise */
464{
465 int i; /* Looping var */
466 _pwg_size_t *size, /* Current size */
467 *closest, /* Closest size */
468 jobsize; /* Size data from job */
469 int margins_set, /* Were the margins set? */
470 dwidth, /* Difference in width */
471 dlength, /* Difference in length */
472 dleft, /* Difference in left margins */
473 dright, /* Difference in right margins */
474 dbottom, /* Difference in bottom margins */
475 dtop, /* Difference in top margins */
476 dmin, /* Minimum difference */
477 dclosest; /* Closest difference */
478
479
480 /*
481 * Range check input...
482 */
483
484 if (!pwg || (!job && !keyword))
485 return (NULL);
486
487 if (exact)
488 *exact = 0;
489
490 if (job && !keyword)
491 {
492 /*
493 * Get the size using media-col or media, with the preference being
494 * media-col.
495 */
496
497 if (!_pwgInitSize(&jobsize, job, &margins_set))
498 return (NULL);
499 }
500 else
501 {
502 /*
503 * Get the size using a media keyword...
504 */
505
506 _pwg_media_t *media; /* Media definition */
507
508
509 if ((media = _pwgMediaForPWG(keyword)) == NULL)
510 if ((media = _pwgMediaForLegacy(keyword)) == NULL)
511 return (NULL);
512
513 jobsize.width = media->width;
514 jobsize.length = media->length;
515 margins_set = 0;
516 }
517
518 /*
519 * Now that we have the dimensions and possibly the margins, look at the
520 * available sizes and find the match...
521 */
522
523 closest = NULL;
524 dclosest = 999999999;
525
526 for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
527 {
528 /*
529 * Adobe uses a size matching algorithm with an epsilon of 5 points, which
530 * is just about 176/2540ths...
531 */
532
533 dwidth = size->width - jobsize.width;
534 dlength = size->length - jobsize.length;
535
536 if (dwidth <= -176 || dwidth >= 176 || dlength <= -176 || dlength >= 176)
537 continue;
538
539 if (margins_set)
540 {
541 /*
542 * Use a tighter epsilon of 1 point (35/2540ths) for margins...
543 */
544
545 dleft = size->left - jobsize.left;
546 dright = size->right - jobsize.right;
547 dtop = size->top - jobsize.top;
548 dbottom = size->bottom - jobsize.bottom;
549
550 if (dleft <= -35 || dleft >= 35 || dright <= -35 || dright >= 35 ||
551 dtop <= -35 || dtop >= 35 || dbottom <= -35 || dbottom >= 35)
552 {
553 dleft = dleft < 0 ? -dleft : dleft;
554 dright = dright < 0 ? -dright : dright;
555 dbottom = dbottom < 0 ? -dbottom : dbottom;
556 dtop = dtop < 0 ? -dtop : dtop;
557 dmin = dleft + dright + dbottom + dtop;
558
559 if (dmin < dclosest)
560 {
561 dclosest = dmin;
562 closest = size;
563 }
564
565 continue;
566 }
567 }
568
569 if (exact)
570 *exact = 1;
571
572 return (size->map.ppd);
573 }
574
575 if (closest)
576 return (closest->map.ppd);
577
578 /*
579 * If we get here we need to check for custom page size support...
580 */
581
582 if (jobsize.width >= pwg->custom_min_width &&
583 jobsize.width <= pwg->custom_max_width &&
584 jobsize.length >= pwg->custom_min_length &&
585 jobsize.length <= pwg->custom_max_length)
586 {
587 /*
588 * In range, format as Custom.WWWWxLLLL (points).
589 */
590
591 snprintf(pwg->custom_ppd_size, sizeof(pwg->custom_ppd_size), "Custom.%dx%d",
592 (int)_PWG_TOPTS(jobsize.width), (int)_PWG_TOPTS(jobsize.length));
593
594 if (margins_set && exact)
595 {
596 dleft = pwg->custom_size.left - jobsize.left;
597 dright = pwg->custom_size.right - jobsize.right;
598 dtop = pwg->custom_size.top - jobsize.top;
599 dbottom = pwg->custom_size.bottom - jobsize.bottom;
600
601 if (dleft > -35 && dleft < 35 && dright > -35 && dright < 35 &&
602 dtop > -35 && dtop < 35 && dbottom > -35 && dbottom < 35)
603 *exact = 1;
604 }
605 else if (exact)
606 *exact = 1;
607
608 return (pwg->custom_ppd_size);
609 }
610
611 /*
612 * No custom page size support or the size is out of range - return NULL.
613 */
614
615 return (NULL);
616}
617
618
619/*
620 * '_pwgGetSize()' - Get the PWG size associated with a PPD PageSize.
621 */
622
623_pwg_size_t * /* O - PWG size or NULL */
624_pwgGetSize(_pwg_t *pwg, /* I - PWG mapping data */
625 const char *page_size) /* I - PPD PageSize */
626{
627 int i;
628 _pwg_size_t *size; /* Current size */
629
630
631 if (!strncasecmp(page_size, "Custom.", 7))
632 {
633 /*
634 * Custom size; size name can be one of the following:
635 *
636 * Custom.WIDTHxLENGTHin - Size in inches
637 * Custom.WIDTHxLENGTHft - Size in feet
638 * Custom.WIDTHxLENGTHcm - Size in centimeters
639 * Custom.WIDTHxLENGTHmm - Size in millimeters
640 * Custom.WIDTHxLENGTHm - Size in meters
641 * Custom.WIDTHxLENGTH[pt] - Size in points
642 */
643
644 double w, l; /* Width and length of page */
645 char *ptr; /* Pointer into PageSize */
646 struct lconv *loc; /* Locale data */
647
648 loc = localeconv();
649 w = (float)_cupsStrScand(page_size + 7, &ptr, loc);
650 if (!ptr || *ptr != 'x')
651 return (NULL);
652
653 l = (float)_cupsStrScand(ptr + 1, &ptr, loc);
654 if (!ptr)
655 return (NULL);
656
657 if (!strcasecmp(ptr, "in"))
658 {
659 w *= 2540.0;
660 l *= 2540.0;
661 }
662 else if (!strcasecmp(ptr, "ft"))
663 {
664 w *= 12.0 * 2540.0;
665 l *= 12.0 * 2540.0;
666 }
667 else if (!strcasecmp(ptr, "mm"))
668 {
669 w *= 100.0;
670 l *= 100.0;
671 }
672 else if (!strcasecmp(ptr, "cm"))
673 {
674 w *= 1000.0;
675 l *= 1000.0;
676 }
677 else if (!strcasecmp(ptr, "m"))
678 {
679 w *= 100000.0;
680 l *= 100000.0;
681 }
682 else
683 {
684 w *= 2540.0 / 72.0;
685 l *= 2540.0 / 72.0;
686 }
687
688 pwg->custom_size.width = (int)w;
689 pwg->custom_size.length = (int)l;
690
691 return (&(pwg->custom_size));
692 }
693
694 /*
695 * Not a custom size - look it up...
696 */
697
698 for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
699 if (!strcasecmp(page_size, size->map.ppd))
700 return (size);
701
702 return (NULL);
703}
704
705
706/*
707 * '_pwgGetSource()' - Get the PWG media-source associated with a PPD InputSlot.
708 */
709
710const char * /* O - PWG media-source keyword */
711_pwgGetSource(_pwg_t *pwg, /* I - PWG mapping data */
712 const char *input_slot) /* I - PPD InputSlot */
713{
714 int i; /* Looping var */
715 _pwg_map_t *source; /* Current source */
716
717
718 for (i = pwg->num_sources, source = pwg->sources; i > 0; i --, source ++)
719 if (!strcasecmp(input_slot, source->ppd))
720 return (source->pwg);
721
722 return (NULL);
723}
724
725
726/*
727 * '_pwgGetType()' - Get the PWG media-type associated with a PPD MediaType.
728 */
729
730const char * /* O - PWG media-type keyword */
731_pwgGetType(_pwg_t *pwg, /* I - PWG mapping data */
732 const char *media_type) /* I - PPD MediaType */
733{
734 int i; /* Looping var */
735 _pwg_map_t *type; /* Current type */
736
737
738 for (i = pwg->num_types, type = pwg->types; i > 0; i --, type ++)
739 if (!strcasecmp(media_type, type->ppd))
740 return (type->pwg);
741
742 return (NULL);
743}
744
745
746/*
747 * '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG source.
748 */
749
750const char * /* O - InputSlot name */
751_pwgInputSlotForSource(
752 const char *media_source, /* I - PWG media-source */
753 char *name, /* I - Name buffer */
754 size_t namesize) /* I - Size of name buffer */
755{
756 if (strcasecmp(media_source, "main-tray"))
757 strlcpy(name, "Cassette", namesize);
758 else if (strcasecmp(media_source, "alternate-tray"))
759 strlcpy(name, "Multipurpose", namesize);
760 else if (strcasecmp(media_source, "large-capacity-tray"))
761 strlcpy(name, "LargeCapacity", namesize);
762 else if (strcasecmp(media_source, "bottom-tray"))
763 strlcpy(name, "Lower", namesize);
764 else if (strcasecmp(media_source, "middle-tray"))
765 strlcpy(name, "Middle", namesize);
766 else if (strcasecmp(media_source, "top-tray"))
767 strlcpy(name, "Upper", namesize);
768 else if (strcasecmp(media_source, "rear-feed"))
769 strlcpy(name, "Rear", namesize);
770 else if (strcasecmp(media_source, "side-feed"))
771 strlcpy(name, "Side", namesize);
772 else if (strcasecmp(media_source, "envelope-feed"))
773 strlcpy(name, "Envelope", namesize);
774 else if (strcasecmp(media_source, "main-roll"))
775 strlcpy(name, "Roll", namesize);
776 else if (strcasecmp(media_source, "alternate-roll"))
777 strlcpy(name, "Roll2", namesize);
778 else
779 pwg_ppdize_name(media_source, name, namesize);
780
781 return (name);
782}
783
784
785/*
786 * '_pwgMediaTypeForType()' - Get the MediaType name for the given PWG type.
787 */
788
789const char * /* O - MediaType name */
790_pwgMediaTypeForType(
791 const char *media_type, /* I - PWG media-source */
792 char *name, /* I - Name buffer */
793 size_t namesize) /* I - Size of name buffer */
794{
795 if (strcasecmp(media_type, "auto"))
796 strlcpy(name, "Auto", namesize);
797 else if (strcasecmp(media_type, "cardstock"))
798 strlcpy(name, "Cardstock", namesize);
799 else if (strcasecmp(media_type, "envelope"))
800 strlcpy(name, "Envelope", namesize);
801 else if (strcasecmp(media_type, "photographic-glossy"))
802 strlcpy(name, "Glossy", namesize);
803 else if (strcasecmp(media_type, "photographic-high-gloss"))
804 strlcpy(name, "HighGloss", namesize);
805 else if (strcasecmp(media_type, "photographic-matte"))
806 strlcpy(name, "Matte", namesize);
807 else if (strcasecmp(media_type, "stationery"))
808 strlcpy(name, "Plain", namesize);
809 else if (strcasecmp(media_type, "stationery-coated"))
810 strlcpy(name, "Coated", namesize);
811 else if (strcasecmp(media_type, "stationery-inkjet"))
812 strlcpy(name, "Inkjet", namesize);
813 else if (strcasecmp(media_type, "stationery-letterhead"))
814 strlcpy(name, "Letterhead", namesize);
815 else if (strcasecmp(media_type, "stationery-preprinted"))
816 strlcpy(name, "Preprinted", namesize);
817 else if (strcasecmp(media_type, "transparency"))
818 strlcpy(name, "Transparency", namesize);
819 else
820 pwg_ppdize_name(media_type, name, namesize);
821
822 return (name);
823}
824
825
826/*
827 * '_pwgPageSizeForMedia()' - Get the PageSize name for the given media.
828 */
829
830const char * /* O - PageSize name */
831_pwgPageSizeForMedia(
832 _pwg_media_t *media, /* I - Media */
833 char *name, /* I - PageSize name buffer */
834 size_t namesize) /* I - Size of name buffer */
835{
836 const char *sizeptr, /* Pointer to size in PWG name */
837 *dimptr; /* Pointer to dimensions in PWG name */
838
839
840 /*
841 * Range check input...
842 */
843
844 if (!media || !name || namesize < PPD_MAX_NAME)
845 return (NULL);
846
847 /*
848 * Copy or generate a PageSize name...
849 */
850
851 if (media->ppd)
852 {
853 /*
854 * Use a standard Adobe name...
855 */
856
857 strlcpy(name, media->ppd, namesize);
858 }
859 else if (!media->pwg || !strncmp(media->pwg, "custom_", 7) ||
860 (sizeptr = strchr(media->pwg, '_')) == NULL ||
861 (dimptr = strchr(sizeptr + 1, '_')) == NULL ||
862 (dimptr - sizeptr) > namesize)
863 {
864 /*
865 * Use a name of the form "wNNNhNNN"...
866 */
867
868 snprintf(name, namesize, "w%dh%d", (int)_PWG_TOPTS(media->width),
869 (int)_PWG_TOPTS(media->length));
870 }
871 else
872 {
873 /*
874 * Copy the size name from class_sizename_dimensions...
875 */
876
877 memcpy(name, sizeptr + 1, dimptr - sizeptr - 1);
878 name[dimptr - sizeptr - 1] = '\0';
879 }
880
881 return (name);
882}
883
884
885/*
886 * 'pwg_ppdize_name()' - Convert an IPP keyword to a PPD keyword.
887 */
888
889static void
890pwg_ppdize_name(const char *ipp, /* I - IPP keyword */
891 char *name, /* I - Name buffer */
892 size_t namesize) /* I - Size of name buffer */
893{
894 char *ptr, /* Pointer into name buffer */
895 *end; /* End of name buffer */
896
897
898 *name = toupper(*ipp++);
899
900 for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;)
901 {
902 if (*ipp == '-' && isalpha(ipp[1] & 255))
903 {
904 ipp ++;
905 *ptr++ = toupper(*ipp++ & 255);
906 }
907 else
908 *ptr++ = *ipp++;
909 }
910
911 *ptr = '\0';
912}
913
914
915/*
916 * 'pwg_unppdize_name()' - Convert a PPD keyword to a lowercase IPP keyword.
917 */
918
919static void
920pwg_unppdize_name(const char *ppd, /* I - PPD keyword */
921 char *name, /* I - Name buffer */
922 size_t namesize) /* I - Size of name buffer */
923{
924 char *ptr, /* Pointer into name buffer */
925 *end; /* End of name buffer */
926
927
928 for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++)
929 {
930 if (isalnum(*ppd & 255) || *ppd == '-' || *ppd == '.')
931 *ptr++ = tolower(*ppd & 255);
932 else if (*ppd == '_')
933 *ptr++ = '-';
934
935 if (!isupper(*ppd & 255) && isalnum(*ppd & 255) &&
936 isupper(ppd[1] & 255) && ptr < end)
937 *ptr++ = '-';
938 }
939
940 *ptr = '\0';
941}
942
943
944/*
945 * End of "$Id$".
946 */