1 // This file is part of the brlaser printer driver.
2 //
3 // Copyright 2013 Peter De Wachter
4 //
5 // brlaser is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // brlaser is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with brlaser.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #include "job.h"
19 #include <assert.h>
20 #include <algorithm>
21 #include <vector>
22 #include "line.h"
23 #include "block.h"
24 
25 
job(FILE * out,const std::string & job_name)26 job::job(FILE *out, const std::string &job_name)
27     : out_(out),
28       job_name_(job_name),
29       page_params_() {
30   // Delete dubious characters from job name
31   std::replace_if(job_name_.begin(), job_name_.end(), [](char c) {
32       return c < 32 || c >= 127 || c == '"' || c == '\\';
33     }, ' ');
34 
35   begin_job();
36 }
37 
~job()38 job::~job() {
39   end_job();
40 }
41 
begin_job()42 void job::begin_job() {
43   for (int i = 0; i < 128; ++i) {
44     putc(0, out_);
45   }
46   fprintf(out_, "\033%%-12345X@PJL\n");
47   fprintf(out_, "@PJL JOB NAME=\"%s\"\n", job_name_.c_str());
48 }
49 
end_job()50 void job::end_job() {
51   fprintf(out_, "\033%%-12345X@PJL\n");
52   fprintf(out_, "@PJL EOJ NAME=\"%s\"\n", job_name_.c_str());
53   fprintf(out_, "\033%%-12345X\n");
54 }
55 
write_page_header()56 void job::write_page_header() {
57   fprintf(out_, "\033%%-12345X@PJL\n");
58   if (page_params_.resolution != 1200) {
59     fprintf(out_, "@PJL SET RAS1200MODE = FALSE\n");
60     fprintf(out_, "@PJL SET RESOLUTION = %d\n", page_params_.resolution);
61   } else {
62     fprintf(out_, "@PJL SET RAS1200MODE = TRUE\n");
63     fprintf(out_, "@PJL SET RESOLUTION = 600\n");
64   }
65   fprintf(out_, "@PJL SET ECONOMODE = %s\n",
66           page_params_.economode ? "ON" : "OFF");
67   fprintf(out_, "@PJL SET SOURCETRAY = %s\n",
68           page_params_.sourcetray.c_str());
69   fprintf(out_, "@PJL SET MEDIATYPE = %s\n",
70           page_params_.mediatype.c_str());
71   fprintf(out_, "@PJL SET PAPER = %s\n",
72           page_params_.papersize.c_str());
73   fprintf(out_, "@PJL SET PAGEPROTECT = AUTO\n");
74   fprintf(out_, "@PJL SET ORIENTATION = PORTRAIT\n");
75   fprintf(out_, "@PJL ENTER LANGUAGE = PCL\n");
76 
77   fputs("\033E", out_);
78   fprintf(out_, "\033&l%dX", std::max(1, page_params_.num_copies));
79 
80   if (page_params_.duplex) {
81     fputs("\033&l2S", out_);
82   }
83 }
84 
encode_page(const page_params & page_params,int lines,int linesize,nextline_fn nextline)85 void job::encode_page(const page_params &page_params,
86                       int lines,
87                       int linesize,
88                       nextline_fn nextline) {
89   if (!(page_params_ == page_params)) {
90     page_params_ = page_params;
91     write_page_header();
92   }
93 
94   std::vector<uint8_t> line(linesize);
95   std::vector<uint8_t> reference(linesize);
96   block block;
97 
98   if (!nextline(line)) {
99     return;
100   }
101   block.add_line(encode_line(line));
102   std::swap(line, reference);
103 
104   fputs("\033*b1030m", out_);
105 
106   for (int i = 1; i < lines && nextline(line); ++i) {
107     std::vector<uint8_t> encoded = encode_line(line, reference);
108     if (block.line_fits(encoded.size())) {
109       block.add_line(std::move(encoded));
110     } else {
111       block.flush(out_);
112       block.add_line(encode_line(line));
113     }
114     std::swap(line, reference);
115   }
116 
117   block.flush(out_);
118   fputs("1030M\f", out_);
119   fflush(out_);
120 }
121