~ubuntu-branches/debian/experimental/cups-filters/experimental

« back to all changes in this revision

Viewing changes to filter/bannertopdf.c

  • Committer: Package Import Robot
  • Author(s): Didier Raboud
  • Date: 2015-01-15 18:06:05 UTC
  • mfrom: (1.2.25)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: package-import@ubuntu.com-20150115180605-fnfbqv85k3y5zggk
Tags: upstream-1.0.62
ImportĀ upstreamĀ versionĀ 1.0.62

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright 2012 Canonical Ltd.
 
3
 * Copyright 2013 ALT Linux, Andrew V. Stepanov <stanv@altlinux.com>
3
4
 *
4
5
 * This program is free software: you can redistribute it and/or modify it
5
6
 * under the terms of the GNU General Public License version 3, as published
27
28
 
28
29
#include <cups/cups.h>
29
30
#include <cups/ppd.h>
 
31
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
 
32
#define HAVE_CUPS_1_7 1
 
33
#endif
 
34
#ifdef HAVE_CUPS_1_7
 
35
#include <cups/pwg.h>
 
36
#endif /* HAVE_CUPS_1_7 */
30
37
 
31
38
#include "banner.h"
32
39
#include "pdf.h"
70
77
        756.0,      /* top */
71
78
    };
72
79
    const ppd_size_t *pagesize;
 
80
#ifdef HAVE_CUPS_1_7
 
81
    pwg_media_t      *size_found;          /* page size found for given name */
 
82
    const char       *val;                 /* Pointer into value */
 
83
    char             *ptr1, *ptr2,         /* Pointer into string */
 
84
                     s[255];               /* Temporary string */
 
85
#endif /* HAVE_CUPS_1_7 */
73
86
 
74
 
    if (!(pagesize = ppdPageSize(ppd, NULL)))
 
87
    if (!ppd || !(pagesize = ppdPageSize(ppd, NULL)))
75
88
        pagesize = &defaultsize;
76
89
 
77
90
    *width = pagesize->width;
89
102
    media_limits[3] = get_float_option("page-top",
90
103
                                       noptions, options,
91
104
                                       fabs(pagesize->top));
 
105
 
 
106
#ifdef HAVE_CUPS_1_7
 
107
    if (!ppd) {
 
108
      if ((val = cupsGetOption("media-size", noptions, options)) != NULL ||
 
109
          (val = cupsGetOption("MediaSize", noptions, options)) != NULL ||
 
110
          (val = cupsGetOption("page-size", noptions, options)) != NULL ||
 
111
          (val = cupsGetOption("PageSize", noptions, options)) != NULL ||
 
112
          (val = cupsGetOption("media", noptions, options)) != NULL) {
 
113
        for (ptr1 = (char *)val; *ptr1;) {
 
114
          for (ptr2 = s; *ptr1 && *ptr1 != ',' && (ptr2 - s) < (sizeof(s) - 1);)
 
115
            *ptr2++ = *ptr1++;
 
116
          *ptr2++ = '\0';
 
117
          if (*ptr1 == ',')
 
118
            ptr1 ++;
 
119
          size_found = NULL;
 
120
          if ((size_found = pwgMediaForPWG(s)) == NULL)
 
121
            if ((size_found = pwgMediaForPPD(s)) == NULL)
 
122
              size_found = pwgMediaForLegacy(s);
 
123
          if (size_found != NULL) {
 
124
            *width = size_found->width * 72.0 / 2540.0;
 
125
            *length = size_found->length * 72.0 / 2540.0;
 
126
            media_limits[2] += (*width - 612.0);
 
127
            media_limits[3] += (*length - 792.0);
 
128
          }
 
129
        }
 
130
      }
 
131
      if ((val = cupsGetOption("media-left-margin", noptions, options))
 
132
          != NULL)
 
133
        media_limits[0] = atol(val) * 72.0 / 2540.0; 
 
134
      if ((val = cupsGetOption("media-bottom-margin", noptions, options))
 
135
          != NULL)
 
136
        media_limits[1] = atol(val) * 72.0 / 2540.0; 
 
137
      if ((val = cupsGetOption("media-right-margin", noptions, options))
 
138
          != NULL)
 
139
        media_limits[2] = *width - atol(val) * 72.0 / 2540.0; 
 
140
      if ((val = cupsGetOption("media-top-margin", noptions, options))
 
141
          != NULL)
 
142
        media_limits[3] = *length - atol(val) * 72.0 / 2540.0; 
 
143
    }
 
144
#endif /* HAVE_CUPS_1_7 */
92
145
}
93
146
 
94
147
 
95
 
static int duplex_marked(ppd_file_t *ppd)
 
148
static int duplex_marked(ppd_file_t *ppd,
 
149
                         int noptions,
 
150
                         cups_option_t *options)
96
151
{
 
152
    const char       *val;                 /* Pointer into value */
97
153
    return
98
 
        ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
 
154
      (ppd &&
 
155
       (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
99
156
        ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
100
157
        ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
101
158
        ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
102
159
        ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
103
160
        ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
104
161
        ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
105
 
        ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble");
 
162
        ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))) ||
 
163
      ((val = cupsGetOption("Duplex", noptions, options))
 
164
       != NULL &&
 
165
       (!strcasecmp(val, "DuplexNoTumble") ||
 
166
        !strcasecmp(val, "DuplexTumble"))) ||
 
167
      ((val = cupsGetOption("sides", noptions, options))
 
168
       != NULL &&
 
169
       (!strcasecmp(val, "two-sided-long-edge") ||
 
170
        !strcasecmp(val, "two-sided-short-edge")));
106
171
}
107
172
 
108
173
 
144
209
        info_line(s, key, "unknown");
145
210
}
146
211
 
 
212
static const char *human_time(const char *timestamp)
 
213
{
 
214
    time_t time;
 
215
    int size = sizeof(char) * 40;
 
216
    char *buf = malloc(size);
 
217
    strcpy(buf, "unknown");
 
218
 
 
219
    if (timestamp) {
 
220
        time = (time_t)atoll(timestamp);
 
221
        strftime(buf, size, "%c", localtime(&time));
 
222
    }
 
223
 
 
224
    return buf;
 
225
}
 
226
 
 
227
/*
 
228
 * Add new key & value.
 
229
 */
 
230
static opt_t* add_opt(opt_t *in_opt, const char *key, const char *val) {
 
231
    if ( ! key || ! val ) {
 
232
        return in_opt;
 
233
    }
 
234
 
 
235
    if ( !strlen(key) || !strlen(val) ) {
 
236
        return in_opt;
 
237
    }
 
238
 
 
239
    opt_t *entry = malloc(sizeof(opt_t));
 
240
    if ( ! entry ) {
 
241
        return in_opt;
 
242
    }
 
243
 
 
244
    entry->key = key;
 
245
    entry->val = val;
 
246
    entry->next = in_opt;
 
247
 
 
248
    return entry;
 
249
}
 
250
 
 
251
/*
 
252
 * Collect all known info about current task.
 
253
 * Bond PDF form field name with collected info.
 
254
 *
 
255
 * Create PDF form's field names according above.
 
256
 */
 
257
opt_t *get_known_opts(
 
258
        ppd_file_t *ppd,
 
259
        const char *jobid,
 
260
        const char *user,
 
261
        const char *jobtitle,
 
262
        int noptions,
 
263
        cups_option_t *options) {
 
264
 
 
265
    ppd_attr_t *attr;
 
266
    opt_t *opt = NULL;
 
267
 
 
268
    /* Job ID */
 
269
    opt = add_opt(opt, "job-id", jobid);
 
270
 
 
271
    /* Job title */
 
272
    opt = add_opt(opt, "job-title", jobtitle);
 
273
 
 
274
    /* Printer by */
 
275
    opt = add_opt(opt, "user", user);
 
276
 
 
277
    /* Printer name */
 
278
    opt = add_opt(opt, "printer-name", getenv("PRINTER"));
 
279
 
 
280
    /* Printer info */
 
281
    opt = add_opt(opt, "printer-info", getenv("PRINTER_INFO"));
 
282
 
 
283
    /* Time at creation */
 
284
    opt = add_opt(opt, "time-at-creation",
 
285
            human_time(cupsGetOption("time-at-creation", noptions, options)));
 
286
 
 
287
    /* Processing time */
 
288
    opt = add_opt(opt, "time-at-processing",
 
289
            human_time(cupsGetOption("time-at-processing", noptions, options)));
 
290
 
 
291
    /* Billing information */
 
292
    opt = add_opt(opt, "job-billing",
 
293
            cupsGetOption("job-billing", noptions, options));
 
294
 
 
295
    /* Source hostname */
 
296
    opt = add_opt(opt, "job-originating-host-name",
 
297
            cupsGetOption("job-originating-host-name", noptions, options));
 
298
 
 
299
    /* Banner font */
 
300
    opt = add_opt(opt, "banner-font",
 
301
            cupsGetOption("banner-font", noptions, options));
 
302
 
 
303
    /* Banner font size */
 
304
    opt = add_opt(opt, "banner-font-size",
 
305
            cupsGetOption("banner-font-size", noptions, options));
 
306
 
 
307
    /* Job UUID */
 
308
    opt = add_opt(opt, "job-uuid",
 
309
            cupsGetOption("job-uuid", noptions, options));
 
310
 
 
311
    /* Security context */
 
312
    opt = add_opt(opt, "security-context",
 
313
            cupsGetOption("security-context", noptions, options));
 
314
 
 
315
    /* Security context range part */
 
316
    opt = add_opt(opt, "security-context-range",
 
317
            cupsGetOption("security-context-range", noptions, options));
 
318
 
 
319
    /* Security context current range part */
 
320
    const char * full_range = cupsGetOption("security-context-range", noptions, options);
 
321
    if ( full_range ) {
 
322
        size_t cur_size = strcspn(full_range, "-");
 
323
        char * cur_range = strndup(full_range, cur_size);
 
324
        opt = add_opt(opt, "security-context-range-cur", cur_range);
 
325
    }
 
326
 
 
327
    /* Security context type part */
 
328
    opt = add_opt(opt, "security-context-type",
 
329
            cupsGetOption("security-context-type", noptions, options));
 
330
 
 
331
    /* Security context role part */
 
332
    opt = add_opt(opt, "security-context-role",
 
333
            cupsGetOption("security-context-role", noptions, options));
 
334
 
 
335
    /* Security context user part */
 
336
    opt = add_opt(opt, "security-context-user",
 
337
            cupsGetOption("security-context-user", noptions, options));
 
338
 
 
339
    if (ppd) {
 
340
      /* Driver */
 
341
      opt = add_opt(opt, "driver", ppd->pcfilename);
 
342
 
 
343
      /* Driver version */
 
344
      opt = add_opt(opt, "driver-version", 
 
345
                    (attr = ppdFindAttr(ppd, "FileVersion", NULL)) ? 
 
346
                    attr->value : "");
 
347
 
 
348
      /* Make and model */
 
349
      opt = add_opt(opt, "make-and-model", ppd->nickname);
 
350
    }
 
351
 
 
352
    return opt;
 
353
}
147
354
 
148
355
static int generate_banner_pdf(banner_t *banner,
149
356
                               ppd_file_t *ppd,
223
430
 
224
431
    if (banner->infos & INFO_JOB_ORIGINATING_HOST_NAME)
225
432
        info_line(s, "Printed from",
226
 
                  cupsGetOption("jobs-originating-host-name",
 
433
                  cupsGetOption("job-originating-host-name",
227
434
                                noptions, options));
228
435
 
229
436
    if (banner->infos & INFO_JOB_ORIGINATING_USER_NAME)
233
440
        info_line(s, "Job UUID",
234
441
                  cupsGetOption("job-uuid", noptions, options));
235
442
 
236
 
    if (banner->infos & INFO_PRINTER_DRIVER_NAME)
 
443
    if (ppd && banner->infos & INFO_PRINTER_DRIVER_NAME)
237
444
        info_line(s, "Driver", ppd->pcfilename);
238
445
 
239
 
    if (banner->infos & INFO_PRINTER_DRIVER_VERSION)
 
446
    if (ppd && banner->infos & INFO_PRINTER_DRIVER_VERSION)
240
447
        info_line(s, "Driver Version",
241
448
                  (attr = ppdFindAttr(ppd, "FileVersion", NULL)) ? attr->value : "");
242
449
 
244
451
        info_line(s, "Description", getenv("PRINTER_INFO"));
245
452
 
246
453
    if (banner->infos & INFO_PRINTER_LOCATION)
247
 
        info_line(s, "Driver Version", getenv("PRINTER_INFO"));
 
454
        info_line(s, "Printer Location", getenv("PRINTER_LOCATION"));
248
455
 
249
 
    if (banner->infos & INFO_PRINTER_MAKE_AND_MODEL)
 
456
    if (ppd && banner->infos & INFO_PRINTER_MAKE_AND_MODEL)
250
457
        info_line(s, "Make and Model", ppd->nickname);
251
458
 
252
459
    if (banner->infos & INFO_PRINTER_NAME)
278
485
#endif /* !HAVE_OPEN_MEMSTREAM */
279
486
    fclose(s);
280
487
 
281
 
    pdf_prepend_stream(doc, 1, buf, len);
 
488
    opt_t * known_opts = get_known_opts(ppd,
 
489
            jobid,
 
490
            user,
 
491
            jobtitle,
 
492
            noptions,
 
493
            options);
 
494
 
 
495
    /*
 
496
     * Try to find a PDF form in PDF template and fill it.
 
497
     */
 
498
    int ret = pdf_fill_form(doc, known_opts);
 
499
 
 
500
    /*
 
501
     * Could we fill a PDF form? If no, just add PDF stream.
 
502
     */
 
503
    if ( ! ret ) {
 
504
        pdf_prepend_stream(doc, 1, buf, len);
 
505
    }
282
506
 
283
507
    copies = get_int_option("number-up", noptions, options, 1);
284
 
    if (duplex_marked(ppd))
 
508
    if (duplex_marked(ppd, noptions, options))
285
509
        copies *= 2;
286
510
 
287
511
    if (copies > 1)
310
534
    }
311
535
 
312
536
    ppd = ppdOpenFile(getenv("PPD"));
313
 
    if (!ppd) {
314
 
        fprintf(stderr, "Error: could not open PPD file '%s'\n", getenv("PPD"));
315
 
        return 1;
316
 
    }
 
537
    if (!ppd)
 
538
      fprintf(stderr, "DEBUG: Could not open PPD file '%s'\n", getenv("PPD"));
317
539
 
318
540
    noptions = cupsParseOptions(argv[5], 0, &options);
319
 
    ppdMarkDefaults(ppd);
320
 
    cupsMarkOptions(ppd, noptions, options);
 
541
    if (ppd) {
 
542
      ppdMarkDefaults(ppd);
 
543
      cupsMarkOptions(ppd, noptions, options);
 
544
    }
321
545
 
322
 
    banner = banner_new_from_file(argc == 7 ? argv[6] : "-");
 
546
    banner = banner_new_from_file(argc == 7 ? argv[6] : "-", &noptions, &options);
323
547
    if (!banner) {
324
548
        fprintf(stderr, "Error: could not read banner file\n");
325
549
        return 1;
337
561
    cupsFreeOptions(noptions, options);
338
562
    return ret;
339
563
}
340