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