Mercurial > vim
annotate src/hardcopy.c @ 16150:b23048205589 v8.1.1080
patch 8.1.1080: when a screendump test fails, moving the file is a hassle
commit https://github.com/vim/vim/commit/ef7f0e367eeaf6fb31b1caa0e3de1a4b07e86af3
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 30 15:59:51 2019 +0100
patch 8.1.1080: when a screendump test fails, moving the file is a hassle
Problem: When a screendump test fails, moving the file is a hassle.
Solution: Instead of appending ".failed" to the file name, keep the same
file name but put the screendump in the "failed" directory.
Then the file name only needs to be typed once when moving a
screendump.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 30 Mar 2019 16:00:06 +0100 |
parents | 536dd2bc5ac9 |
children | 7ad3fc329e08 |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
9027
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
442 | 2 * |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * hardcopy.c: printing to paper | |
12 */ | |
13 | |
14 #include "vim.h" | |
15 #include "version.h" | |
16 | |
17 #if defined(FEAT_PRINTER) || defined(PROTO) | |
18 /* | |
19 * To implement printing on a platform, the following functions must be | |
20 * defined: | |
21 * | |
22 * int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) | |
23 * Called once. Code should display printer dialogue (if appropriate) and | |
24 * determine printer font and margin settings. Reset has_color if the printer | |
25 * doesn't support colors at all. | |
26 * Returns FAIL to abort. | |
27 * | |
28 * int mch_print_begin(prt_settings_T *settings) | |
29 * Called to start the print job. | |
30 * Return FALSE to abort. | |
31 * | |
32 * int mch_print_begin_page(char_u *msg) | |
33 * Called at the start of each page. | |
34 * "msg" indicates the progress of the print job, can be NULL. | |
35 * Return FALSE to abort. | |
36 * | |
37 * int mch_print_end_page() | |
38 * Called at the end of each page. | |
39 * Return FALSE to abort. | |
40 * | |
41 * int mch_print_blank_page() | |
42 * Called to generate a blank page for collated, duplex, multiple copy | |
43 * document. Return FALSE to abort. | |
44 * | |
45 * void mch_print_end(prt_settings_T *psettings) | |
46 * Called at normal end of print job. | |
47 * | |
48 * void mch_print_cleanup() | |
49 * Called if print job ends normally or is abandoned. Free any memory, close | |
50 * devices and handles. Also called when mch_print_begin() fails, but not | |
51 * when mch_print_init() fails. | |
52 * | |
53 * void mch_print_set_font(int Bold, int Italic, int Underline); | |
54 * Called whenever the font style changes. | |
55 * | |
843 | 56 * void mch_print_set_bg(long_u bgcol); |
442 | 57 * Called to set the background color for the following text. Parameter is an |
58 * RGB value. | |
59 * | |
843 | 60 * void mch_print_set_fg(long_u fgcol); |
442 | 61 * Called to set the foreground color for the following text. Parameter is an |
62 * RGB value. | |
63 * | |
64 * mch_print_start_line(int margin, int page_line) | |
65 * Sets the current position at the start of line "page_line". | |
66 * If margin is TRUE start in the left margin (for header and line number). | |
67 * | |
68 * int mch_print_text_out(char_u *p, int len); | |
69 * Output one character of text p[len] at the current position. | |
70 * Return TRUE if there is no room for another character in the same line. | |
71 * | |
72 * Note that the generic code has no idea of margins. The machine code should | |
73 * simply make the page look smaller! The header and the line numbers are | |
74 * printed in the margin. | |
75 */ | |
76 | |
77 #ifdef FEAT_SYN_HL | |
78 static const long_u cterm_color_8[8] = | |
79 { | |
80 (long_u)0x000000L, (long_u)0xff0000L, (long_u)0x00ff00L, (long_u)0xffff00L, | |
81 (long_u)0x0000ffL, (long_u)0xff00ffL, (long_u)0x00ffffL, (long_u)0xffffffL | |
82 }; | |
83 | |
84 static const long_u cterm_color_16[16] = | |
85 { | |
86 (long_u)0x000000L, (long_u)0x0000c0L, (long_u)0x008000L, (long_u)0x004080L, | |
87 (long_u)0xc00000L, (long_u)0xc000c0L, (long_u)0x808000L, (long_u)0xc0c0c0L, | |
88 (long_u)0x808080L, (long_u)0x6060ffL, (long_u)0x00ff00L, (long_u)0x00ffffL, | |
89 (long_u)0xff8080L, (long_u)0xff40ffL, (long_u)0xffff00L, (long_u)0xffffffL | |
90 }; | |
91 | |
92 static int current_syn_id; | |
93 #endif | |
94 | |
95 #define PRCOLOR_BLACK (long_u)0 | |
96 #define PRCOLOR_WHITE (long_u)0xFFFFFFL | |
97 | |
98 static int curr_italic; | |
99 static int curr_bold; | |
100 static int curr_underline; | |
101 static long_u curr_bg; | |
102 static long_u curr_fg; | |
103 static int page_count; | |
104 | |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
105 #if defined(FEAT_POSTSCRIPT) |
442 | 106 # define OPT_MBFONT_USECOURIER 0 |
107 # define OPT_MBFONT_ASCII 1 | |
108 # define OPT_MBFONT_REGULAR 2 | |
856 | 109 # define OPT_MBFONT_BOLD 3 |
442 | 110 # define OPT_MBFONT_OBLIQUE 4 |
111 # define OPT_MBFONT_BOLDOBLIQUE 5 | |
112 # define OPT_MBFONT_NUM_OPTIONS 6 | |
113 | |
114 static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] = | |
115 { | |
116 {"c", FALSE, 0, NULL, 0, FALSE}, | |
117 {"a", FALSE, 0, NULL, 0, FALSE}, | |
118 {"r", FALSE, 0, NULL, 0, FALSE}, | |
119 {"b", FALSE, 0, NULL, 0, FALSE}, | |
120 {"i", FALSE, 0, NULL, 0, FALSE}, | |
121 {"o", FALSE, 0, NULL, 0, FALSE}, | |
122 }; | |
123 #endif | |
124 | |
125 /* | |
126 * These values determine the print position on a page. | |
127 */ | |
128 typedef struct | |
129 { | |
130 int lead_spaces; /* remaining spaces for a TAB */ | |
131 int print_pos; /* virtual column for computing TABs */ | |
132 colnr_T column; /* byte column */ | |
133 linenr_T file_line; /* line nr in the buffer */ | |
134 long_u bytes_printed; /* bytes printed so far */ | |
135 int ff; /* seen form feed character */ | |
136 } prt_pos_T; | |
137 | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
138 static char *parse_list_options(char_u *option_str, option_table_T *table, int table_size); |
442 | 139 |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
6759
diff
changeset
|
140 static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos); |
442 | 141 |
142 /* | |
143 * Parse 'printoptions' and set the flags in "printer_opts". | |
144 * Returns an error message or NULL; | |
145 */ | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
146 char * |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
147 parse_printoptions(void) |
442 | 148 { |
149 return parse_list_options(p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS); | |
150 } | |
151 | |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
152 #if defined(FEAT_POSTSCRIPT) || defined(PROTO) |
442 | 153 /* |
8969
c83e2c1e7f2b
commit https://github.com/vim/vim/commit/8a633e3427b47286869aa4b96f2bfc1fe65b25cd
Christian Brabandt <cb@256bit.org>
parents:
8829
diff
changeset
|
154 * Parse 'printmbfont' and set the flags in "mbfont_opts". |
442 | 155 * Returns an error message or NULL; |
156 */ | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
157 char * |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
158 parse_printmbfont(void) |
442 | 159 { |
160 return parse_list_options(p_pmfn, mbfont_opts, OPT_MBFONT_NUM_OPTIONS); | |
161 } | |
162 #endif | |
163 | |
164 /* | |
165 * Parse a list of options in the form | |
166 * option:value,option:value,option:value | |
167 * | |
168 * "value" can start with a number which is parsed out, e.g. margin:12mm | |
169 * | |
170 * Returns an error message for an illegal option, NULL otherwise. | |
171 * Only used for the printer at the moment... | |
172 */ | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
173 static char * |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
174 parse_list_options( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
175 char_u *option_str, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
176 option_table_T *table, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
177 int table_size) |
442 | 178 { |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
179 option_table_T *old_opts; |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
180 char *ret = NULL; |
442 | 181 char_u *stringp; |
182 char_u *colonp; | |
183 char_u *commap; | |
184 char_u *p; | |
185 int idx = 0; /* init for GCC */ | |
186 int len; | |
187 | |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
188 /* Save the old values, so that they can be restored in case of an error. */ |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
189 old_opts = (option_table_T *)alloc(sizeof(option_table_T) * table_size); |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
190 if (old_opts == NULL) |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
191 return NULL; |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
192 |
442 | 193 for (idx = 0; idx < table_size; ++idx) |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
194 { |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
195 old_opts[idx] = table[idx]; |
442 | 196 table[idx].present = FALSE; |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
197 } |
442 | 198 |
199 /* | |
200 * Repeat for all comma separated parts. | |
201 */ | |
202 stringp = option_str; | |
203 while (*stringp) | |
204 { | |
205 colonp = vim_strchr(stringp, ':'); | |
206 if (colonp == NULL) | |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
207 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
208 ret = N_("E550: Missing colon"); |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
209 break; |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
210 } |
442 | 211 commap = vim_strchr(stringp, ','); |
212 if (commap == NULL) | |
213 commap = option_str + STRLEN(option_str); | |
214 | |
215 len = (int)(colonp - stringp); | |
216 | |
217 for (idx = 0; idx < table_size; ++idx) | |
218 if (STRNICMP(stringp, table[idx].name, len) == 0) | |
219 break; | |
220 | |
221 if (idx == table_size) | |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
222 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
223 ret = N_("E551: Illegal component"); |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
224 break; |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
225 } |
442 | 226 p = colonp + 1; |
227 table[idx].present = TRUE; | |
228 | |
229 if (table[idx].hasnum) | |
230 { | |
231 if (!VIM_ISDIGIT(*p)) | |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
232 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
233 ret = N_("E552: digit expected"); |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
234 break; |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
235 } |
442 | 236 |
237 table[idx].number = getdigits(&p); /*advances p*/ | |
238 } | |
239 | |
240 table[idx].string = p; | |
241 table[idx].strlen = (int)(commap - p); | |
242 | |
243 stringp = commap; | |
244 if (*stringp == ',') | |
245 ++stringp; | |
246 } | |
247 | |
8829
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
248 if (ret != NULL) |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
249 { |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
250 /* Restore old options in case of error */ |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
251 for (idx = 0; idx < table_size; ++idx) |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
252 table[idx] = old_opts[idx]; |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
253 } |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
254 vim_free(old_opts); |
a2c27f6aaf3a
commit https://github.com/vim/vim/commit/4afc7c5d4a73340831077a02bfe1f74935e7f4a1
Christian Brabandt <cb@256bit.org>
parents:
8524
diff
changeset
|
255 return ret; |
442 | 256 } |
257 | |
258 | |
259 #ifdef FEAT_SYN_HL | |
260 /* | |
261 * If using a dark background, the colors will probably be too bright to show | |
262 * up well on white paper, so reduce their brightness. | |
263 */ | |
264 static long_u | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
265 darken_rgb(long_u rgb) |
442 | 266 { |
267 return ((rgb >> 17) << 16) | |
268 + (((rgb & 0xff00) >> 9) << 8) | |
269 + ((rgb & 0xff) >> 1); | |
270 } | |
271 | |
272 static long_u | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
273 prt_get_term_color(int colorindex) |
442 | 274 { |
275 /* TODO: Should check for xterm with 88 or 256 colors. */ | |
276 if (t_colors > 8) | |
277 return cterm_color_16[colorindex % 16]; | |
278 return cterm_color_8[colorindex % 8]; | |
279 } | |
280 | |
281 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
282 prt_get_attr( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
283 int hl_id, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
284 prt_text_attr_T *pattr, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
285 int modec) |
442 | 286 { |
287 int colorindex; | |
288 long_u fg_color; | |
289 long_u bg_color; | |
290 char *color; | |
291 | |
292 pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL); | |
293 pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL); | |
294 pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL); | |
295 pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL); | |
296 | |
9027
773d627cac0b
commit https://github.com/vim/vim/commit/61be73bb0f965a895bfb064ea3e55476ac175162
Christian Brabandt <cb@256bit.org>
parents:
8969
diff
changeset
|
297 # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) |
8969
c83e2c1e7f2b
commit https://github.com/vim/vim/commit/8a633e3427b47286869aa4b96f2bfc1fe65b25cd
Christian Brabandt <cb@256bit.org>
parents:
8829
diff
changeset
|
298 if (USE_24BIT) |
442 | 299 { |
300 bg_color = highlight_gui_color_rgb(hl_id, FALSE); | |
301 if (bg_color == PRCOLOR_BLACK) | |
302 bg_color = PRCOLOR_WHITE; | |
303 | |
304 fg_color = highlight_gui_color_rgb(hl_id, TRUE); | |
305 } | |
306 else | |
307 # endif | |
308 { | |
309 bg_color = PRCOLOR_WHITE; | |
310 | |
311 color = (char *)highlight_color(hl_id, (char_u *)"fg", modec); | |
312 if (color == NULL) | |
313 colorindex = 0; | |
314 else | |
315 colorindex = atoi(color); | |
316 | |
317 if (colorindex >= 0 && colorindex < t_colors) | |
318 fg_color = prt_get_term_color(colorindex); | |
319 else | |
320 fg_color = PRCOLOR_BLACK; | |
321 } | |
322 | |
323 if (fg_color == PRCOLOR_WHITE) | |
324 fg_color = PRCOLOR_BLACK; | |
325 else if (*p_bg == 'd') | |
326 fg_color = darken_rgb(fg_color); | |
327 | |
328 pattr->fg_color = fg_color; | |
329 pattr->bg_color = bg_color; | |
330 } | |
331 #endif /* FEAT_SYN_HL */ | |
332 | |
333 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
334 prt_set_fg(long_u fg) |
442 | 335 { |
336 if (fg != curr_fg) | |
337 { | |
338 curr_fg = fg; | |
339 mch_print_set_fg(fg); | |
340 } | |
341 } | |
342 | |
343 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
344 prt_set_bg(long_u bg) |
442 | 345 { |
346 if (bg != curr_bg) | |
347 { | |
348 curr_bg = bg; | |
349 mch_print_set_bg(bg); | |
350 } | |
351 } | |
352 | |
353 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
354 prt_set_font(int bold, int italic, int underline) |
442 | 355 { |
356 if (curr_bold != bold | |
357 || curr_italic != italic | |
358 || curr_underline != underline) | |
359 { | |
360 curr_underline = underline; | |
361 curr_italic = italic; | |
362 curr_bold = bold; | |
363 mch_print_set_font(bold, italic, underline); | |
364 } | |
365 } | |
366 | |
367 /* | |
368 * Print the line number in the left margin. | |
369 */ | |
370 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
371 prt_line_number( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
372 prt_settings_T *psettings, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
373 int page_line, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
374 linenr_T lnum) |
442 | 375 { |
376 int i; | |
377 char_u tbuf[20]; | |
378 | |
379 prt_set_fg(psettings->number.fg_color); | |
380 prt_set_bg(psettings->number.bg_color); | |
381 prt_set_font(psettings->number.bold, psettings->number.italic, psettings->number.underline); | |
382 mch_print_start_line(TRUE, page_line); | |
383 | |
384 /* Leave two spaces between the number and the text; depends on | |
385 * PRINT_NUMBER_WIDTH. */ | |
386 sprintf((char *)tbuf, "%6ld", (long)lnum); | |
387 for (i = 0; i < 6; i++) | |
388 (void)mch_print_text_out(&tbuf[i], 1); | |
389 | |
390 #ifdef FEAT_SYN_HL | |
391 if (psettings->do_syntax) | |
392 /* Set colors for next character. */ | |
393 current_syn_id = -1; | |
394 else | |
395 #endif | |
396 { | |
397 /* Set colors and font back to normal. */ | |
398 prt_set_fg(PRCOLOR_BLACK); | |
399 prt_set_bg(PRCOLOR_WHITE); | |
400 prt_set_font(FALSE, FALSE, FALSE); | |
401 } | |
402 } | |
403 | |
404 /* | |
405 * Get the currently effective header height. | |
406 */ | |
407 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
408 prt_header_height(void) |
442 | 409 { |
410 if (printer_opts[OPT_PRINT_HEADERHEIGHT].present) | |
411 return printer_opts[OPT_PRINT_HEADERHEIGHT].number; | |
412 return 2; | |
413 } | |
414 | |
415 /* | |
416 * Return TRUE if using a line number for printing. | |
417 */ | |
418 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
419 prt_use_number(void) |
442 | 420 { |
421 return (printer_opts[OPT_PRINT_NUMBER].present | |
422 && TOLOWER_ASC(printer_opts[OPT_PRINT_NUMBER].string[0]) == 'y'); | |
423 } | |
424 | |
425 /* | |
426 * Return the unit used in a margin item in 'printoptions'. | |
427 * Returns PRT_UNIT_NONE if not recognized. | |
428 */ | |
429 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
430 prt_get_unit(int idx) |
442 | 431 { |
432 int u = PRT_UNIT_NONE; | |
433 int i; | |
434 static char *(units[4]) = PRT_UNIT_NAMES; | |
435 | |
436 if (printer_opts[idx].present) | |
437 for (i = 0; i < 4; ++i) | |
438 if (STRNICMP(printer_opts[idx].string, units[i], 2) == 0) | |
439 { | |
440 u = i; | |
441 break; | |
442 } | |
443 return u; | |
444 } | |
445 | |
446 /* | |
447 * Print the page header. | |
448 */ | |
449 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
450 prt_header( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
451 prt_settings_T *psettings, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
452 int pagenum, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
453 linenr_T lnum UNUSED) |
442 | 454 { |
455 int width = psettings->chars_per_line; | |
456 int page_line; | |
457 char_u *tbuf; | |
458 char_u *p; | |
459 int l; | |
460 | |
461 /* Also use the space for the line number. */ | |
462 if (prt_use_number()) | |
463 width += PRINT_NUMBER_WIDTH; | |
464 | |
465 tbuf = alloc(width + IOSIZE); | |
466 if (tbuf == NULL) | |
467 return; | |
468 | |
469 #ifdef FEAT_STL_OPT | |
470 if (*p_header != NUL) | |
471 { | |
472 linenr_T tmp_lnum, tmp_topline, tmp_botline; | |
677 | 473 int use_sandbox = FALSE; |
442 | 474 |
475 /* | |
476 * Need to (temporarily) set current line number and first/last line | |
477 * number on the 'window'. Since we don't know how long the page is, | |
478 * set the first and current line number to the top line, and guess | |
479 * that the page length is 64. | |
480 */ | |
481 tmp_lnum = curwin->w_cursor.lnum; | |
482 tmp_topline = curwin->w_topline; | |
483 tmp_botline = curwin->w_botline; | |
484 curwin->w_cursor.lnum = lnum; | |
485 curwin->w_topline = lnum; | |
486 curwin->w_botline = lnum + 63; | |
487 printer_page_num = pagenum; | |
488 | |
677 | 489 # ifdef FEAT_EVAL |
681 | 490 use_sandbox = was_set_insecurely((char_u *)"printheader", 0); |
677 | 491 # endif |
442 | 492 build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE), |
677 | 493 p_header, use_sandbox, |
681 | 494 ' ', width, NULL, NULL); |
442 | 495 |
496 /* Reset line numbers */ | |
497 curwin->w_cursor.lnum = tmp_lnum; | |
498 curwin->w_topline = tmp_topline; | |
499 curwin->w_botline = tmp_botline; | |
500 } | |
501 else | |
502 #endif | |
503 sprintf((char *)tbuf, _("Page %d"), pagenum); | |
504 | |
505 prt_set_fg(PRCOLOR_BLACK); | |
506 prt_set_bg(PRCOLOR_WHITE); | |
507 prt_set_font(TRUE, FALSE, FALSE); | |
508 | |
509 /* Use a negative line number to indicate printing in the top margin. */ | |
510 page_line = 0 - prt_header_height(); | |
511 mch_print_start_line(TRUE, page_line); | |
512 for (p = tbuf; *p != NUL; ) | |
513 { | |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
514 if (mch_print_text_out(p, (l = (*mb_ptr2len)(p)))) |
442 | 515 { |
516 ++page_line; | |
517 if (page_line >= 0) /* out of room in header */ | |
518 break; | |
519 mch_print_start_line(TRUE, page_line); | |
520 } | |
521 p += l; | |
522 } | |
523 | |
524 vim_free(tbuf); | |
525 | |
526 #ifdef FEAT_SYN_HL | |
527 if (psettings->do_syntax) | |
528 /* Set colors for next character. */ | |
529 current_syn_id = -1; | |
530 else | |
531 #endif | |
532 { | |
533 /* Set colors and font back to normal. */ | |
534 prt_set_fg(PRCOLOR_BLACK); | |
535 prt_set_bg(PRCOLOR_WHITE); | |
536 prt_set_font(FALSE, FALSE, FALSE); | |
537 } | |
538 } | |
539 | |
540 /* | |
541 * Display a print status message. | |
542 */ | |
543 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
544 prt_message(char_u *s) |
442 | 545 { |
546 screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); | |
11158
501f46f7644c
patch 8.0.0466: still macros that should be all-caps
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
547 screen_puts(s, (int)Rows - 1, 0, HL_ATTR(HLF_R)); |
442 | 548 out_flush(); |
549 } | |
550 | |
551 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
552 ex_hardcopy(exarg_T *eap) |
442 | 553 { |
554 linenr_T lnum; | |
555 int collated_copies, uncollated_copies; | |
556 prt_settings_T settings; | |
557 long_u bytes_to_print = 0; | |
558 int page_line; | |
559 int jobsplit; | |
560 | |
2215
cccb71c2c5c1
Fix uninit memory read in undo code. Fix uint32_t in proto file.
Bram Moolenaar <bram@vim.org>
parents:
1880
diff
changeset
|
561 vim_memset(&settings, 0, sizeof(prt_settings_T)); |
442 | 562 settings.has_color = TRUE; |
563 | |
564 # ifdef FEAT_POSTSCRIPT | |
565 if (*eap->arg == '>') | |
566 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
567 char *errormsg = NULL; |
442 | 568 |
569 /* Expand things like "%.ps". */ | |
570 if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) | |
571 { | |
572 if (errormsg != NULL) | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
573 emsg(errormsg); |
442 | 574 return; |
575 } | |
576 settings.outfile = skipwhite(eap->arg + 1); | |
577 } | |
578 else if (*eap->arg != NUL) | |
579 settings.arguments = eap->arg; | |
580 # endif | |
581 | |
582 /* | |
583 * Initialise for printing. Ask the user for settings, unless forceit is | |
584 * set. | |
585 * The mch_print_init() code should set up margins if applicable. (It may | |
586 * not be a real printer - for example the engine might generate HTML or | |
587 * PS.) | |
588 */ | |
589 if (mch_print_init(&settings, | |
590 curbuf->b_fname == NULL | |
591 ? (char_u *)buf_spname(curbuf) | |
592 : curbuf->b_sfname == NULL | |
593 ? curbuf->b_fname | |
594 : curbuf->b_sfname, | |
595 eap->forceit) == FAIL) | |
596 return; | |
597 | |
598 #ifdef FEAT_SYN_HL | |
599 # ifdef FEAT_GUI | |
600 if (gui.in_use) | |
601 settings.modec = 'g'; | |
602 else | |
603 # endif | |
604 if (t_colors > 1) | |
605 settings.modec = 'c'; | |
606 else | |
607 settings.modec = 't'; | |
608 | |
2250
1bac28a53fae
Add the conceal patch from Vince Negri.
Bram Moolenaar <bram@vim.org>
parents:
2215
diff
changeset
|
609 if (!syntax_present(curwin)) |
442 | 610 settings.do_syntax = FALSE; |
611 else if (printer_opts[OPT_PRINT_SYNTAX].present | |
612 && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a') | |
613 settings.do_syntax = | |
614 (TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) == 'y'); | |
615 else | |
616 settings.do_syntax = settings.has_color; | |
617 #endif | |
618 | |
619 /* Set up printing attributes for line numbers */ | |
620 settings.number.fg_color = PRCOLOR_BLACK; | |
621 settings.number.bg_color = PRCOLOR_WHITE; | |
622 settings.number.bold = FALSE; | |
623 settings.number.italic = TRUE; | |
624 settings.number.underline = FALSE; | |
625 #ifdef FEAT_SYN_HL | |
626 /* | |
627 * Syntax highlighting of line numbers. | |
628 */ | |
629 if (prt_use_number() && settings.do_syntax) | |
630 { | |
744 | 631 int id; |
632 | |
442 | 633 id = syn_name2id((char_u *)"LineNr"); |
634 if (id > 0) | |
635 id = syn_get_final_id(id); | |
636 | |
637 prt_get_attr(id, &settings.number, settings.modec); | |
638 } | |
744 | 639 #endif |
442 | 640 |
641 /* | |
642 * Estimate the total lines to be printed | |
643 */ | |
644 for (lnum = eap->line1; lnum <= eap->line2; lnum++) | |
645 bytes_to_print += (long_u)STRLEN(skipwhite(ml_get(lnum))); | |
646 if (bytes_to_print == 0) | |
647 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
648 msg(_("No text to be printed")); |
442 | 649 goto print_fail_no_begin; |
650 } | |
651 | |
652 /* Set colors and font to normal. */ | |
653 curr_bg = (long_u)0xffffffffL; | |
654 curr_fg = (long_u)0xffffffffL; | |
655 curr_italic = MAYBE; | |
656 curr_bold = MAYBE; | |
657 curr_underline = MAYBE; | |
658 | |
659 prt_set_fg(PRCOLOR_BLACK); | |
660 prt_set_bg(PRCOLOR_WHITE); | |
661 prt_set_font(FALSE, FALSE, FALSE); | |
662 #ifdef FEAT_SYN_HL | |
663 current_syn_id = -1; | |
664 #endif | |
665 | |
666 jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present | |
667 && TOLOWER_ASC(printer_opts[OPT_PRINT_JOBSPLIT].string[0]) == 'y'); | |
668 | |
669 if (!mch_print_begin(&settings)) | |
670 goto print_fail_no_begin; | |
671 | |
672 /* | |
673 * Loop over collated copies: 1 2 3, 1 2 3, ... | |
674 */ | |
675 page_count = 0; | |
676 for (collated_copies = 0; | |
677 collated_copies < settings.n_collated_copies; | |
678 collated_copies++) | |
679 { | |
680 prt_pos_T prtpos; /* current print position */ | |
681 prt_pos_T page_prtpos; /* print position at page start */ | |
682 int side; | |
683 | |
2215
cccb71c2c5c1
Fix uninit memory read in undo code. Fix uint32_t in proto file.
Bram Moolenaar <bram@vim.org>
parents:
1880
diff
changeset
|
684 vim_memset(&page_prtpos, 0, sizeof(prt_pos_T)); |
442 | 685 page_prtpos.file_line = eap->line1; |
686 prtpos = page_prtpos; | |
687 | |
688 if (jobsplit && collated_copies > 0) | |
689 { | |
690 /* Splitting jobs: Stop a previous job and start a new one. */ | |
691 mch_print_end(&settings); | |
692 if (!mch_print_begin(&settings)) | |
693 goto print_fail_no_begin; | |
694 } | |
695 | |
696 /* | |
697 * Loop over all pages in the print job: 1 2 3 ... | |
698 */ | |
699 for (page_count = 0; prtpos.file_line <= eap->line2; ++page_count) | |
700 { | |
701 /* | |
702 * Loop over uncollated copies: 1 1 1, 2 2 2, 3 3 3, ... | |
703 * For duplex: 12 12 12 34 34 34, ... | |
704 */ | |
705 for (uncollated_copies = 0; | |
706 uncollated_copies < settings.n_uncollated_copies; | |
707 uncollated_copies++) | |
708 { | |
709 /* Set the print position to the start of this page. */ | |
710 prtpos = page_prtpos; | |
711 | |
712 /* | |
713 * Do front and rear side of a page. | |
714 */ | |
715 for (side = 0; side <= settings.duplex; ++side) | |
716 { | |
717 /* | |
718 * Print one page. | |
719 */ | |
720 | |
721 /* Check for interrupt character every page. */ | |
722 ui_breakcheck(); | |
723 if (got_int || settings.user_abort) | |
724 goto print_fail; | |
725 | |
726 sprintf((char *)IObuff, _("Printing page %d (%d%%)"), | |
727 page_count + 1 + side, | |
728 prtpos.bytes_printed > 1000000 | |
729 ? (int)(prtpos.bytes_printed / | |
730 (bytes_to_print / 100)) | |
731 : (int)((prtpos.bytes_printed * 100) | |
732 / bytes_to_print)); | |
733 if (!mch_print_begin_page(IObuff)) | |
734 goto print_fail; | |
735 | |
736 if (settings.n_collated_copies > 1) | |
737 sprintf((char *)IObuff + STRLEN(IObuff), | |
738 _(" Copy %d of %d"), | |
739 collated_copies + 1, | |
740 settings.n_collated_copies); | |
741 prt_message(IObuff); | |
742 | |
743 /* | |
744 * Output header if required | |
745 */ | |
746 if (prt_header_height() > 0) | |
747 prt_header(&settings, page_count + 1 + side, | |
748 prtpos.file_line); | |
749 | |
750 for (page_line = 0; page_line < settings.lines_per_page; | |
751 ++page_line) | |
752 { | |
753 prtpos.column = hardcopy_line(&settings, | |
754 page_line, &prtpos); | |
755 if (prtpos.column == 0) | |
756 { | |
757 /* finished a file line */ | |
758 prtpos.bytes_printed += | |
759 STRLEN(skipwhite(ml_get(prtpos.file_line))); | |
760 if (++prtpos.file_line > eap->line2) | |
761 break; /* reached the end */ | |
762 } | |
763 else if (prtpos.ff) | |
764 { | |
765 /* Line had a formfeed in it - start new page but | |
766 * stay on the current line */ | |
767 break; | |
768 } | |
769 } | |
770 | |
771 if (!mch_print_end_page()) | |
772 goto print_fail; | |
773 if (prtpos.file_line > eap->line2) | |
774 break; /* reached the end */ | |
775 } | |
776 | |
777 /* | |
778 * Extra blank page for duplexing with odd number of pages and | |
779 * more copies to come. | |
780 */ | |
781 if (prtpos.file_line > eap->line2 && settings.duplex | |
782 && side == 0 | |
783 && uncollated_copies + 1 < settings.n_uncollated_copies) | |
784 { | |
785 if (!mch_print_blank_page()) | |
786 goto print_fail; | |
787 } | |
788 } | |
789 if (settings.duplex && prtpos.file_line <= eap->line2) | |
790 ++page_count; | |
791 | |
792 /* Remember the position where the next page starts. */ | |
793 page_prtpos = prtpos; | |
794 } | |
795 | |
796 vim_snprintf((char *)IObuff, IOSIZE, _("Printed: %s"), | |
797 settings.jobname); | |
798 prt_message(IObuff); | |
799 } | |
800 | |
801 print_fail: | |
802 if (got_int || settings.user_abort) | |
803 { | |
804 sprintf((char *)IObuff, "%s", _("Printing aborted")); | |
805 prt_message(IObuff); | |
806 } | |
807 mch_print_end(&settings); | |
808 | |
809 print_fail_no_begin: | |
810 mch_print_cleanup(); | |
811 } | |
812 | |
813 /* | |
814 * Print one page line. | |
815 * Return the next column to print, or zero if the line is finished. | |
816 */ | |
817 static colnr_T | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
818 hardcopy_line( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
819 prt_settings_T *psettings, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
820 int page_line, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
821 prt_pos_T *ppos) |
442 | 822 { |
823 colnr_T col; | |
824 char_u *line; | |
825 int need_break = FALSE; | |
826 int outputlen; | |
827 int tab_spaces; | |
828 long_u print_pos; | |
829 #ifdef FEAT_SYN_HL | |
830 prt_text_attr_T attr; | |
831 int id; | |
832 #endif | |
833 | |
834 if (ppos->column == 0 || ppos->ff) | |
835 { | |
836 print_pos = 0; | |
837 tab_spaces = 0; | |
838 if (!ppos->ff && prt_use_number()) | |
839 prt_line_number(psettings, page_line, ppos->file_line); | |
840 ppos->ff = FALSE; | |
841 } | |
842 else | |
843 { | |
844 /* left over from wrap halfway a tab */ | |
845 print_pos = ppos->print_pos; | |
846 tab_spaces = ppos->lead_spaces; | |
847 } | |
848 | |
849 mch_print_start_line(0, page_line); | |
850 line = ml_get(ppos->file_line); | |
851 | |
852 /* | |
853 * Loop over the columns until the end of the file line or right margin. | |
854 */ | |
855 for (col = ppos->column; line[col] != NUL && !need_break; col += outputlen) | |
856 { | |
857 outputlen = 1; | |
474 | 858 if (has_mbyte && (outputlen = (*mb_ptr2len)(line + col)) < 1) |
442 | 859 outputlen = 1; |
860 #ifdef FEAT_SYN_HL | |
861 /* | |
862 * syntax highlighting stuff. | |
863 */ | |
864 if (psettings->do_syntax) | |
865 { | |
1504 | 866 id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE); |
442 | 867 if (id > 0) |
868 id = syn_get_final_id(id); | |
869 else | |
870 id = 0; | |
871 /* Get the line again, a multi-line regexp may invalidate it. */ | |
872 line = ml_get(ppos->file_line); | |
873 | |
874 if (id != current_syn_id) | |
875 { | |
876 current_syn_id = id; | |
877 prt_get_attr(id, &attr, psettings->modec); | |
878 prt_set_font(attr.bold, attr.italic, attr.underline); | |
879 prt_set_fg(attr.fg_color); | |
880 prt_set_bg(attr.bg_color); | |
881 } | |
882 } | |
744 | 883 #endif |
442 | 884 |
885 /* | |
886 * Appropriately expand any tabs to spaces. | |
887 */ | |
888 if (line[col] == TAB || tab_spaces != 0) | |
889 { | |
890 if (tab_spaces == 0) | |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14077
diff
changeset
|
891 #ifdef FEAT_VARTABS |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14077
diff
changeset
|
892 tab_spaces = tabstop_padding(print_pos, curbuf->b_p_ts, |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14077
diff
changeset
|
893 curbuf->b_p_vts_array); |
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14077
diff
changeset
|
894 #else |
835 | 895 tab_spaces = (int)(curbuf->b_p_ts - (print_pos % curbuf->b_p_ts)); |
14175
2ad722003b36
patch 8.1.0105: all tab stops are the same
Christian Brabandt <cb@256bit.org>
parents:
14077
diff
changeset
|
896 #endif |
442 | 897 |
898 while (tab_spaces > 0) | |
899 { | |
900 need_break = mch_print_text_out((char_u *)" ", 1); | |
901 print_pos++; | |
902 tab_spaces--; | |
903 if (need_break) | |
904 break; | |
905 } | |
906 /* Keep the TAB if we didn't finish it. */ | |
907 if (need_break && tab_spaces > 0) | |
908 break; | |
909 } | |
910 else if (line[col] == FF | |
911 && printer_opts[OPT_PRINT_FORMFEED].present | |
912 && TOLOWER_ASC(printer_opts[OPT_PRINT_FORMFEED].string[0]) | |
913 == 'y') | |
914 { | |
915 ppos->ff = TRUE; | |
916 need_break = 1; | |
917 } | |
918 else | |
919 { | |
920 need_break = mch_print_text_out(line + col, outputlen); | |
921 if (has_mbyte) | |
922 print_pos += (*mb_ptr2cells)(line + col); | |
923 else | |
924 print_pos++; | |
925 } | |
926 } | |
927 | |
928 ppos->lead_spaces = tab_spaces; | |
835 | 929 ppos->print_pos = (int)print_pos; |
442 | 930 |
931 /* | |
932 * Start next line of file if we clip lines, or have reached end of the | |
933 * line, unless we are doing a formfeed. | |
934 */ | |
935 if (!ppos->ff | |
936 && (line[col] == NUL | |
937 || (printer_opts[OPT_PRINT_WRAP].present | |
938 && TOLOWER_ASC(printer_opts[OPT_PRINT_WRAP].string[0]) | |
939 == 'n'))) | |
940 return 0; | |
941 return col; | |
942 } | |
943 | |
944 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) | |
945 | |
946 /* | |
947 * PS printer stuff. | |
948 * | |
949 * Sources of information to help maintain the PS printing code: | |
950 * | |
951 * 1. PostScript Language Reference, 3rd Edition, | |
952 * Addison-Wesley, 1999, ISBN 0-201-37922-8 | |
953 * 2. PostScript Language Program Design, | |
954 * Addison-Wesley, 1988, ISBN 0-201-14396-8 | |
955 * 3. PostScript Tutorial and Cookbook, | |
956 * Addison Wesley, 1985, ISBN 0-201-10179-3 | |
957 * 4. PostScript Language Document Structuring Conventions Specification, | |
958 * version 3.0, | |
959 * Adobe Technote 5001, 25th September 1992 | |
960 * 5. PostScript Printer Description File Format Specification, Version 4.3, | |
961 * Adobe technote 5003, 9th February 1996 | |
962 * 6. Adobe Font Metrics File Format Specification, Version 4.1, | |
963 * Adobe Technote 5007, 7th October 1998 | |
964 * 7. Adobe CMap and CIDFont Files Specification, Version 1.0, | |
965 * Adobe Technote 5014, 8th October 1996 | |
966 * 8. Adobe CJKV Character Collections and CMaps for CID-Keyed Fonts, | |
967 * Adoboe Technote 5094, 8th September, 2001 | |
968 * 9. CJKV Information Processing, 2nd Edition, | |
969 * O'Reilly, 2002, ISBN 1-56592-224-7 | |
970 * | |
971 * Some of these documents can be found in PDF form on Adobe's web site - | |
972 * http://www.adobe.com | |
973 */ | |
974 | |
975 #define NUM_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0])) | |
976 | |
977 #define PRT_PS_DEFAULT_DPI (72) /* Default user space resolution */ | |
978 #define PRT_PS_DEFAULT_FONTSIZE (10) | |
979 #define PRT_PS_DEFAULT_BUFFER_SIZE (80) | |
980 | |
981 struct prt_mediasize_S | |
982 { | |
983 char *name; | |
984 float width; /* width and height in points for portrait */ | |
985 float height; | |
986 }; | |
987 | |
988 #define PRT_MEDIASIZE_LEN (sizeof(prt_mediasize) / sizeof(struct prt_mediasize_S)) | |
989 | |
990 static struct prt_mediasize_S prt_mediasize[] = | |
991 { | |
992 {"A4", 595.0, 842.0}, | |
993 {"letter", 612.0, 792.0}, | |
994 {"10x14", 720.0, 1008.0}, | |
995 {"A3", 842.0, 1191.0}, | |
996 {"A5", 420.0, 595.0}, | |
997 {"B4", 729.0, 1032.0}, | |
998 {"B5", 516.0, 729.0}, | |
999 {"executive", 522.0, 756.0}, | |
1000 {"folio", 595.0, 935.0}, | |
1001 {"ledger", 1224.0, 792.0}, /* Yes, it is wider than taller! */ | |
1002 {"legal", 612.0, 1008.0}, | |
1003 {"quarto", 610.0, 780.0}, | |
1004 {"statement", 396.0, 612.0}, | |
1005 {"tabloid", 792.0, 1224.0} | |
1006 }; | |
1007 | |
1008 /* PS font names, must be in Roman, Bold, Italic, Bold-Italic order */ | |
1009 struct prt_ps_font_S | |
1010 { | |
1011 int wx; | |
1012 int uline_offset; | |
1013 int uline_width; | |
1014 int bbox_min_y; | |
1015 int bbox_max_y; | |
1016 char *(ps_fontname[4]); | |
1017 }; | |
1018 | |
1019 #define PRT_PS_FONT_ROMAN (0) | |
1020 #define PRT_PS_FONT_BOLD (1) | |
1021 #define PRT_PS_FONT_OBLIQUE (2) | |
1022 #define PRT_PS_FONT_BOLDOBLIQUE (3) | |
1023 | |
1024 /* Standard font metrics for Courier family */ | |
1025 static struct prt_ps_font_S prt_ps_courier_font = | |
1026 { | |
1027 600, | |
1028 -100, 50, | |
1029 -250, 805, | |
1030 {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"} | |
1031 }; | |
1032 | |
1033 /* Generic font metrics for multi-byte fonts */ | |
1034 static struct prt_ps_font_S prt_ps_mb_font = | |
1035 { | |
1036 1000, | |
1037 -100, 50, | |
1038 -250, 805, | |
1039 {NULL, NULL, NULL, NULL} | |
1040 }; | |
1041 | |
1042 /* Pointer to current font set being used */ | |
1043 static struct prt_ps_font_S* prt_ps_font; | |
1044 | |
1045 /* Structures to map user named encoding and mapping to PS equivalents for | |
1046 * building CID font name */ | |
1047 struct prt_ps_encoding_S | |
1048 { | |
1049 char *encoding; | |
1050 char *cmap_encoding; | |
1051 int needs_charset; | |
1052 }; | |
1053 | |
1054 struct prt_ps_charset_S | |
1055 { | |
1056 char *charset; | |
1057 char *cmap_charset; | |
1058 int has_charset; | |
1059 }; | |
1060 | |
1061 | |
1062 #define CS_JIS_C_1978 (0x01) | |
1063 #define CS_JIS_X_1983 (0x02) | |
1064 #define CS_JIS_X_1990 (0x04) | |
856 | 1065 #define CS_NEC (0x08) |
1066 #define CS_MSWINDOWS (0x10) | |
1067 #define CS_CP932 (0x20) | |
1068 #define CS_KANJITALK6 (0x40) | |
442 | 1069 #define CS_KANJITALK7 (0x80) |
1070 | |
1071 /* Japanese encodings and charsets */ | |
1072 static struct prt_ps_encoding_S j_encodings[] = | |
1073 { | |
1074 {"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990| | |
856 | 1075 CS_NEC)}, |
1076 {"euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990)}, | |
1077 {"sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS| | |
1078 CS_KANJITALK6|CS_KANJITALK7)}, | |
442 | 1079 {"cp932", "RKSJ", CS_JIS_X_1983}, |
1080 {"ucs-2", "UCS2", CS_JIS_X_1990}, | |
1081 {"utf-8", "UTF8" , CS_JIS_X_1990} | |
1082 }; | |
1083 static struct prt_ps_charset_S j_charsets[] = | |
1084 { | |
1085 {"JIS_C_1978", "78", CS_JIS_C_1978}, | |
1086 {"JIS_X_1983", NULL, CS_JIS_X_1983}, | |
1087 {"JIS_X_1990", "Hojo", CS_JIS_X_1990}, | |
856 | 1088 {"NEC", "Ext", CS_NEC}, |
442 | 1089 {"MSWINDOWS", "90ms", CS_MSWINDOWS}, |
1090 {"CP932", "90ms", CS_JIS_X_1983}, | |
1091 {"KANJITALK6", "83pv", CS_KANJITALK6}, | |
1092 {"KANJITALK7", "90pv", CS_KANJITALK7} | |
1093 }; | |
1094 | |
1095 #define CS_GB_2312_80 (0x01) | |
1096 #define CS_GBT_12345_90 (0x02) | |
856 | 1097 #define CS_GBK2K (0x04) |
1098 #define CS_SC_MAC (0x08) | |
1099 #define CS_GBT_90_MAC (0x10) | |
1100 #define CS_GBK (0x20) | |
442 | 1101 #define CS_SC_ISO10646 (0x40) |
1102 | |
1103 /* Simplified Chinese encodings and charsets */ | |
1104 static struct prt_ps_encoding_S sc_encodings[] = | |
1105 { | |
1106 {"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)}, | |
1107 {"gb18030", NULL, CS_GBK2K}, | |
1108 {"euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC| | |
856 | 1109 CS_GBT_90_MAC)}, |
1110 {"gbk", "EUC", CS_GBK}, | |
442 | 1111 {"ucs-2", "UCS2", CS_SC_ISO10646}, |
1112 {"utf-8", "UTF8", CS_SC_ISO10646} | |
1113 }; | |
1114 static struct prt_ps_charset_S sc_charsets[] = | |
1115 { | |
1116 {"GB_2312-80", "GB", CS_GB_2312_80}, | |
1117 {"GBT_12345-90","GBT", CS_GBT_12345_90}, | |
856 | 1118 {"MAC", "GBpc", CS_SC_MAC}, |
1119 {"GBT-90_MAC", "GBTpc", CS_GBT_90_MAC}, | |
1120 {"GBK", "GBK", CS_GBK}, | |
442 | 1121 {"GB18030", "GBK2K", CS_GBK2K}, |
1122 {"ISO10646", "UniGB", CS_SC_ISO10646} | |
1123 }; | |
1124 | |
1125 #define CS_CNS_PLANE_1 (0x01) | |
1126 #define CS_CNS_PLANE_2 (0x02) | |
1127 #define CS_CNS_PLANE_1_2 (0x04) | |
856 | 1128 #define CS_B5 (0x08) |
1129 #define CS_ETEN (0x10) | |
1130 #define CS_HK_GCCS (0x20) | |
1131 #define CS_HK_SCS (0x40) | |
1132 #define CS_HK_SCS_ETEN (0x80) | |
1133 #define CS_MTHKL (0x100) | |
1134 #define CS_MTHKS (0x200) | |
1135 #define CS_DLHKL (0x400) | |
1136 #define CS_DLHKS (0x800) | |
1137 #define CS_TC_ISO10646 (0x1000) | |
442 | 1138 |
1139 /* Traditional Chinese encodings and charsets */ | |
1140 static struct prt_ps_encoding_S tc_encodings[] = | |
1141 { | |
1142 {"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)}, | |
1143 {"euc-tw", "EUC", CS_CNS_PLANE_1_2}, | |
856 | 1144 {"big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS| |
1145 CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL| | |
1146 CS_DLHKS)}, | |
442 | 1147 {"cp950", "B5", CS_B5}, |
1148 {"ucs-2", "UCS2", CS_TC_ISO10646}, | |
1149 {"utf-8", "UTF8", CS_TC_ISO10646}, | |
1150 {"utf-16", "UTF16", CS_TC_ISO10646}, | |
1151 {"utf-32", "UTF32", CS_TC_ISO10646} | |
1152 }; | |
1153 static struct prt_ps_charset_S tc_charsets[] = | |
1154 { | |
1155 {"CNS_1992_1", "CNS1", CS_CNS_PLANE_1}, | |
1156 {"CNS_1992_2", "CNS2", CS_CNS_PLANE_2}, | |
1157 {"CNS_1993", "CNS", CS_CNS_PLANE_1_2}, | |
856 | 1158 {"BIG5", NULL, CS_B5}, |
1159 {"CP950", NULL, CS_B5}, | |
1160 {"ETEN", "ETen", CS_ETEN}, | |
1161 {"HK_GCCS", "HKgccs", CS_HK_GCCS}, | |
1162 {"SCS", "HKscs", CS_HK_SCS}, | |
442 | 1163 {"SCS_ETEN", "ETHK", CS_HK_SCS_ETEN}, |
1164 {"MTHKL", "HKm471", CS_MTHKL}, | |
1165 {"MTHKS", "HKm314", CS_MTHKS}, | |
1166 {"DLHKL", "HKdla", CS_DLHKL}, | |
1167 {"DLHKS", "HKdlb", CS_DLHKS}, | |
1168 {"ISO10646", "UniCNS", CS_TC_ISO10646} | |
1169 }; | |
1170 | |
856 | 1171 #define CS_KR_X_1992 (0x01) |
1172 #define CS_KR_MAC (0x02) | |
442 | 1173 #define CS_KR_X_1992_MS (0x04) |
1174 #define CS_KR_ISO10646 (0x08) | |
1175 | |
1176 /* Korean encodings and charsets */ | |
1177 static struct prt_ps_encoding_S k_encodings[] = | |
1178 { | |
1179 {"iso-2022-kr", NULL, CS_KR_X_1992}, | |
1180 {"euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC)}, | |
1181 {"johab", "Johab", CS_KR_X_1992}, | |
1182 {"cp1361", "Johab", CS_KR_X_1992}, | |
856 | 1183 {"uhc", "UHC", CS_KR_X_1992_MS}, |
442 | 1184 {"cp949", "UHC", CS_KR_X_1992_MS}, |
1185 {"ucs-2", "UCS2", CS_KR_ISO10646}, | |
1186 {"utf-8", "UTF8", CS_KR_ISO10646} | |
1187 }; | |
1188 static struct prt_ps_charset_S k_charsets[] = | |
1189 { | |
1190 {"KS_X_1992", "KSC", CS_KR_X_1992}, | |
1191 {"CP1361", "KSC", CS_KR_X_1992}, | |
856 | 1192 {"MAC", "KSCpc", CS_KR_MAC}, |
442 | 1193 {"MSWINDOWS", "KSCms", CS_KR_X_1992_MS}, |
1194 {"CP949", "KSCms", CS_KR_X_1992_MS}, | |
1195 {"WANSUNG", "KSCms", CS_KR_X_1992_MS}, | |
1196 {"ISO10646", "UniKS", CS_KR_ISO10646} | |
1197 }; | |
1198 | |
1199 /* Collections of encodings and charsets for multi-byte printing */ | |
1200 struct prt_ps_mbfont_S | |
1201 { | |
856 | 1202 int num_encodings; |
1203 struct prt_ps_encoding_S *encodings; | |
1204 int num_charsets; | |
1205 struct prt_ps_charset_S *charsets; | |
1206 char *ascii_enc; | |
1207 char *defcs; | |
442 | 1208 }; |
1209 | |
1210 static struct prt_ps_mbfont_S prt_ps_mbfonts[] = | |
1211 { | |
1212 { | |
856 | 1213 NUM_ELEMENTS(j_encodings), |
1214 j_encodings, | |
1215 NUM_ELEMENTS(j_charsets), | |
1216 j_charsets, | |
1217 "jis_roman", | |
1218 "JIS_X_1983" | |
442 | 1219 }, |
1220 { | |
856 | 1221 NUM_ELEMENTS(sc_encodings), |
1222 sc_encodings, | |
1223 NUM_ELEMENTS(sc_charsets), | |
1224 sc_charsets, | |
1225 "gb_roman", | |
1226 "GB_2312-80" | |
442 | 1227 }, |
1228 { | |
856 | 1229 NUM_ELEMENTS(tc_encodings), |
1230 tc_encodings, | |
1231 NUM_ELEMENTS(tc_charsets), | |
1232 tc_charsets, | |
1233 "cns_roman", | |
1234 "BIG5" | |
442 | 1235 }, |
1236 { | |
856 | 1237 NUM_ELEMENTS(k_encodings), |
1238 k_encodings, | |
1239 NUM_ELEMENTS(k_charsets), | |
1240 k_charsets, | |
1241 "ks_roman", | |
1242 "KS_X_1992" | |
442 | 1243 } |
1244 }; | |
1245 | |
1246 struct prt_ps_resource_S | |
1247 { | |
1248 char_u name[64]; | |
1249 char_u filename[MAXPATHL + 1]; | |
1250 int type; | |
1251 char_u title[256]; | |
1252 char_u version[256]; | |
1253 }; | |
1254 | |
1255 /* Types of PS resource file currently used */ | |
1256 #define PRT_RESOURCE_TYPE_PROCSET (0) | |
1257 #define PRT_RESOURCE_TYPE_ENCODING (1) | |
1258 #define PRT_RESOURCE_TYPE_CMAP (2) | |
1259 | |
1260 /* The PS prolog file version number has to match - if the prolog file is | |
1261 * updated, increment the number in the file and here. Version checking was | |
1262 * added as of VIM 6.2. | |
1263 * The CID prolog file version number behaves as per PS prolog. | |
1264 * Table of VIM and prolog versions: | |
1265 * | |
1266 * VIM Prolog CIDProlog | |
1267 * 6.2 1.3 | |
1268 * 7.0 1.4 1.0 | |
1269 */ | |
1270 #define PRT_PROLOG_VERSION ((char_u *)"1.4") | |
1271 #define PRT_CID_PROLOG_VERSION ((char_u *)"1.0") | |
1272 | |
1273 /* String versions of PS resource types - indexed by constants above so don't | |
1274 * re-order! | |
1275 */ | |
1276 static char *prt_resource_types[] = | |
1277 { | |
1278 "procset", | |
1279 "encoding", | |
1280 "cmap" | |
1281 }; | |
1282 | |
1283 /* Strings to look for in a PS resource file */ | |
1284 #define PRT_RESOURCE_HEADER "%!PS-Adobe-" | |
1285 #define PRT_RESOURCE_RESOURCE "Resource-" | |
1286 #define PRT_RESOURCE_PROCSET "ProcSet" | |
1287 #define PRT_RESOURCE_ENCODING "Encoding" | |
856 | 1288 #define PRT_RESOURCE_CMAP "CMap" |
442 | 1289 |
1290 | |
1291 /* Data for table based DSC comment recognition, easy to extend if VIM needs to | |
1292 * read more comments. */ | |
856 | 1293 #define PRT_DSC_MISC_TYPE (-1) |
1294 #define PRT_DSC_TITLE_TYPE (1) | |
1295 #define PRT_DSC_VERSION_TYPE (2) | |
442 | 1296 #define PRT_DSC_ENDCOMMENTS_TYPE (3) |
1297 | |
856 | 1298 #define PRT_DSC_TITLE "%%Title:" |
1299 #define PRT_DSC_VERSION "%%Version:" | |
1300 #define PRT_DSC_ENDCOMMENTS "%%EndComments:" | |
442 | 1301 |
1302 struct prt_dsc_comment_S | |
1303 { | |
1304 char *string; | |
1305 int len; | |
1306 int type; | |
1307 }; | |
1308 | |
1309 struct prt_dsc_line_S | |
1310 { | |
1311 int type; | |
1312 char_u *string; | |
1313 int len; | |
1314 }; | |
1315 | |
1316 | |
1317 #define SIZEOF_CSTR(s) (sizeof(s) - 1) | |
1318 static struct prt_dsc_comment_S prt_dsc_table[] = | |
1319 { | |
1320 {PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE}, | |
1321 {PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION), | |
1322 PRT_DSC_VERSION_TYPE}, | |
1323 {PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS), | |
1324 PRT_DSC_ENDCOMMENTS_TYPE} | |
1325 }; | |
1326 | |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
6759
diff
changeset
|
1327 static void prt_write_file_len(char_u *buffer, int bytes); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
6759
diff
changeset
|
1328 static int prt_next_dsc(struct prt_dsc_line_S *p_dsc_line); |
442 | 1329 |
1330 /* | |
1331 * Variables for the output PostScript file. | |
1332 */ | |
1333 static FILE *prt_ps_fd; | |
1334 static int prt_file_error; | |
1335 static char_u *prt_ps_file_name = NULL; | |
1336 | |
1337 /* | |
1338 * Various offsets and dimensions in default PostScript user space (points). | |
1339 * Used for text positioning calculations | |
1340 */ | |
1341 static float prt_page_width; | |
1342 static float prt_page_height; | |
1343 static float prt_left_margin; | |
1344 static float prt_right_margin; | |
1345 static float prt_top_margin; | |
1346 static float prt_bottom_margin; | |
1347 static float prt_line_height; | |
1348 static float prt_first_line_height; | |
1349 static float prt_char_width; | |
1350 static float prt_number_width; | |
1351 static float prt_bgcol_offset; | |
1352 static float prt_pos_x_moveto = 0.0; | |
1353 static float prt_pos_y_moveto = 0.0; | |
1354 | |
1355 /* | |
1356 * Various control variables used to decide when and how to change the | |
1357 * PostScript graphics state. | |
1358 */ | |
1359 static int prt_need_moveto; | |
1360 static int prt_do_moveto; | |
1361 static int prt_need_font; | |
1362 static int prt_font; | |
1363 static int prt_need_underline; | |
1364 static int prt_underline; | |
1365 static int prt_do_underline; | |
1366 static int prt_need_fgcol; | |
1367 static int prt_fgcol; | |
1368 static int prt_need_bgcol; | |
1369 static int prt_do_bgcol; | |
1370 static int prt_bgcol; | |
1371 static int prt_new_bgcol; | |
1372 static int prt_attribute_change; | |
1373 static float prt_text_run; | |
1374 static int prt_page_num; | |
1375 static int prt_bufsiz; | |
1376 | |
1377 /* | |
1378 * Variables controlling physical printing. | |
1379 */ | |
1380 static int prt_media; | |
1381 static int prt_portrait; | |
1382 static int prt_num_copies; | |
1383 static int prt_duplex; | |
1384 static int prt_tumble; | |
1385 static int prt_collate; | |
1386 | |
1387 /* | |
1388 * Buffers used when generating PostScript output | |
1389 */ | |
1390 static char_u prt_line_buffer[257]; | |
1391 static garray_T prt_ps_buffer; | |
1392 | |
1393 static int prt_do_conv; | |
1394 static vimconv_T prt_conv; | |
1395 | |
1396 static int prt_out_mbyte; | |
1397 static int prt_custom_cmap; | |
1398 static char prt_cmap[80]; | |
1399 static int prt_use_courier; | |
1400 static int prt_in_ascii; | |
1401 static int prt_half_width; | |
1402 static char *prt_ascii_encoding; | |
1403 static char_u prt_hexchar[] = "0123456789abcdef"; | |
1404 | |
1405 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1406 prt_write_file_raw_len(char_u *buffer, int bytes) |
442 | 1407 { |
1408 if (!prt_file_error | |
1409 && fwrite(buffer, sizeof(char_u), bytes, prt_ps_fd) | |
1410 != (size_t)bytes) | |
1411 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1412 emsg(_("E455: Error writing to PostScript output file")); |
442 | 1413 prt_file_error = TRUE; |
1414 } | |
1415 } | |
1416 | |
1417 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1418 prt_write_file(char_u *buffer) |
442 | 1419 { |
835 | 1420 prt_write_file_len(buffer, (int)STRLEN(buffer)); |
442 | 1421 } |
1422 | |
1423 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1424 prt_write_file_len(char_u *buffer, int bytes) |
442 | 1425 { |
1426 #ifdef EBCDIC | |
1427 ebcdic2ascii(buffer, bytes); | |
1428 #endif | |
1429 prt_write_file_raw_len(buffer, bytes); | |
1430 } | |
1431 | |
1432 /* | |
1433 * Write a string. | |
1434 */ | |
1435 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1436 prt_write_string(char *s) |
442 | 1437 { |
1438 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%s", s); | |
1439 prt_write_file(prt_line_buffer); | |
1440 } | |
1441 | |
1442 /* | |
1443 * Write an int and a space. | |
1444 */ | |
1445 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1446 prt_write_int(int i) |
442 | 1447 { |
1448 sprintf((char *)prt_line_buffer, "%d ", i); | |
1449 prt_write_file(prt_line_buffer); | |
1450 } | |
1451 | |
1452 /* | |
1453 * Write a boolean and a space. | |
1454 */ | |
1455 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1456 prt_write_boolean(int b) |
442 | 1457 { |
1458 sprintf((char *)prt_line_buffer, "%s ", (b ? "T" : "F")); | |
1459 prt_write_file(prt_line_buffer); | |
1460 } | |
1461 | |
1462 /* | |
1463 * Write PostScript to re-encode and define the font. | |
1464 */ | |
1465 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1466 prt_def_font( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1467 char *new_name, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1468 char *encoding, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1469 int height, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1470 char *font) |
442 | 1471 { |
1472 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1473 "/_%s /VIM-%s /%s ref\n", new_name, encoding, font); | |
1474 prt_write_file(prt_line_buffer); | |
1475 if (prt_out_mbyte) | |
856 | 1476 sprintf((char *)prt_line_buffer, "/%s %d %f /_%s sffs\n", |
442 | 1477 new_name, height, 500./prt_ps_courier_font.wx, new_name); |
1478 else | |
1479 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1480 "/%s %d /_%s ffs\n", new_name, height, new_name); | |
1481 prt_write_file(prt_line_buffer); | |
1482 } | |
1483 | |
1484 /* | |
1485 * Write a line to define the CID font. | |
1486 */ | |
1487 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1488 prt_def_cidfont(char *new_name, int height, char *cidfont) |
442 | 1489 { |
1490 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1491 "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont); | |
1492 prt_write_file(prt_line_buffer); | |
1493 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1494 "/%s %d /_%s ffs\n", new_name, height, new_name); | |
1495 prt_write_file(prt_line_buffer); | |
1496 } | |
1497 | |
1498 /* | |
1499 * Write a line to define a duplicate of a CID font | |
1500 */ | |
1501 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1502 prt_dup_cidfont(char *original_name, char *new_name) |
442 | 1503 { |
1504 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1505 "/%s %s d\n", new_name, original_name); | |
1506 prt_write_file(prt_line_buffer); | |
1507 } | |
1508 | |
1509 /* | |
1510 * Convert a real value into an integer and fractional part as integers, with | |
1511 * the fractional part being in the range [0,10^precision). The fractional part | |
1512 * is also rounded based on the precision + 1'th fractional digit. | |
1513 */ | |
1514 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1515 prt_real_bits( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1516 double real, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1517 int precision, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1518 int *pinteger, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1519 int *pfraction) |
442 | 1520 { |
1521 int i; | |
1522 int integer; | |
1523 float fraction; | |
1524 | |
1525 integer = (int)real; | |
1526 fraction = (float)(real - integer); | |
1527 if (real < (double)integer) | |
1528 fraction = -fraction; | |
1529 for (i = 0; i < precision; i++) | |
1530 fraction *= 10.0; | |
1531 | |
1532 *pinteger = integer; | |
1533 *pfraction = (int)(fraction + 0.5); | |
1534 } | |
1535 | |
1536 /* | |
1537 * Write a real and a space. Save bytes if real value has no fractional part! | |
1538 * We use prt_real_bits() as %f in sprintf uses the locale setting to decide | |
1539 * what decimal point character to use, but PS always requires a '.'. | |
1540 */ | |
1541 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1542 prt_write_real(double val, int prec) |
442 | 1543 { |
1544 int integer; | |
1545 int fraction; | |
1546 | |
1547 prt_real_bits(val, prec, &integer, &fraction); | |
1548 /* Emit integer part */ | |
1549 sprintf((char *)prt_line_buffer, "%d", integer); | |
1550 prt_write_file(prt_line_buffer); | |
1551 /* Only emit fraction if necessary */ | |
1552 if (fraction != 0) | |
1553 { | |
1554 /* Remove any trailing zeros */ | |
1555 while ((fraction % 10) == 0) | |
1556 { | |
1557 prec--; | |
1558 fraction /= 10; | |
1559 } | |
1560 /* Emit fraction left padded with zeros */ | |
1561 sprintf((char *)prt_line_buffer, ".%0*d", prec, fraction); | |
1562 prt_write_file(prt_line_buffer); | |
1563 } | |
1564 sprintf((char *)prt_line_buffer, " "); | |
1565 prt_write_file(prt_line_buffer); | |
1566 } | |
1567 | |
1568 /* | |
1569 * Write a line to define a numeric variable. | |
1570 */ | |
1571 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1572 prt_def_var(char *name, double value, int prec) |
442 | 1573 { |
1574 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1575 "/%s ", name); | |
1576 prt_write_file(prt_line_buffer); | |
1577 prt_write_real(value, prec); | |
1578 sprintf((char *)prt_line_buffer, "d\n"); | |
1579 prt_write_file(prt_line_buffer); | |
1580 } | |
1581 | |
1582 /* Convert size from font space to user space at current font scale */ | |
1583 #define PRT_PS_FONT_TO_USER(scale, size) ((size) * ((scale)/1000.0)) | |
1584 | |
1585 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1586 prt_flush_buffer(void) |
442 | 1587 { |
1588 if (prt_ps_buffer.ga_len > 0) | |
1589 { | |
1590 /* Any background color must be drawn first */ | |
1591 if (prt_do_bgcol && (prt_new_bgcol != PRCOLOR_WHITE)) | |
1592 { | |
1593 int r, g, b; | |
1594 | |
1595 if (prt_do_moveto) | |
1596 { | |
1597 prt_write_real(prt_pos_x_moveto, 2); | |
1598 prt_write_real(prt_pos_y_moveto, 2); | |
1599 prt_write_string("m\n"); | |
1600 prt_do_moveto = FALSE; | |
1601 } | |
1602 | |
1603 /* Size of rect of background color on which text is printed */ | |
1604 prt_write_real(prt_text_run, 2); | |
1605 prt_write_real(prt_line_height, 2); | |
1606 | |
1607 /* Lastly add the color of the background */ | |
1608 r = ((unsigned)prt_new_bgcol & 0xff0000) >> 16; | |
1609 g = ((unsigned)prt_new_bgcol & 0xff00) >> 8; | |
1610 b = prt_new_bgcol & 0xff; | |
1611 prt_write_real(r / 255.0, 3); | |
1612 prt_write_real(g / 255.0, 3); | |
1613 prt_write_real(b / 255.0, 3); | |
1614 prt_write_string("bg\n"); | |
1615 } | |
1616 /* Draw underlines before the text as it makes it slightly easier to | |
1617 * find the starting point. | |
1618 */ | |
1619 if (prt_do_underline) | |
1620 { | |
1621 if (prt_do_moveto) | |
1622 { | |
1623 prt_write_real(prt_pos_x_moveto, 2); | |
1624 prt_write_real(prt_pos_y_moveto, 2); | |
1625 prt_write_string("m\n"); | |
1626 prt_do_moveto = FALSE; | |
1627 } | |
1628 | |
856 | 1629 /* Underline length of text run */ |
442 | 1630 prt_write_real(prt_text_run, 2); |
1631 prt_write_string("ul\n"); | |
1632 } | |
1633 /* Draw the text | |
1634 * Note: we write text out raw - EBCDIC conversion is handled in the | |
1635 * PostScript world via the font encoding vector. */ | |
856 | 1636 if (prt_out_mbyte) |
1637 prt_write_string("<"); | |
1638 else | |
1639 prt_write_string("("); | |
442 | 1640 prt_write_file_raw_len(prt_ps_buffer.ga_data, prt_ps_buffer.ga_len); |
856 | 1641 if (prt_out_mbyte) |
1642 prt_write_string(">"); | |
1643 else | |
1644 prt_write_string(")"); | |
442 | 1645 /* Add a moveto if need be and use the appropriate show procedure */ |
1646 if (prt_do_moveto) | |
1647 { | |
1648 prt_write_real(prt_pos_x_moveto, 2); | |
1649 prt_write_real(prt_pos_y_moveto, 2); | |
1650 /* moveto and a show */ | |
1651 prt_write_string("ms\n"); | |
1652 prt_do_moveto = FALSE; | |
1653 } | |
1654 else /* Simple show */ | |
1655 prt_write_string("s\n"); | |
1656 | |
1657 ga_clear(&prt_ps_buffer); | |
1658 ga_init2(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz); | |
1659 } | |
1660 } | |
1661 | |
1662 | |
1663 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1664 prt_resource_name(char_u *filename, void *cookie) |
442 | 1665 { |
1666 char_u *resource_filename = cookie; | |
1667 | |
1668 if (STRLEN(filename) >= MAXPATHL) | |
1669 *resource_filename = NUL; | |
1670 else | |
1671 STRCPY(resource_filename, filename); | |
1672 } | |
1673 | |
1674 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1675 prt_find_resource(char *name, struct prt_ps_resource_S *resource) |
442 | 1676 { |
2770 | 1677 char_u *buffer; |
1678 int retval; | |
1679 | |
1680 buffer = alloc(MAXPATHL + 1); | |
1681 if (buffer == NULL) | |
1682 return FALSE; | |
442 | 1683 |
2768 | 1684 vim_strncpy(resource->name, (char_u *)name, 63); |
442 | 1685 /* Look for named resource file in runtimepath */ |
1686 STRCPY(buffer, "print"); | |
1687 add_pathsep(buffer); | |
2768 | 1688 vim_strcat(buffer, (char_u *)name, MAXPATHL); |
1689 vim_strcat(buffer, (char_u *)".ps", MAXPATHL); | |
442 | 1690 resource->filename[0] = NUL; |
8524
2f57bbe870ea
commit https://github.com/vim/vim/commit/7f8989dd8a627af2185df381195351a913f3777f
Christian Brabandt <cb@256bit.org>
parents:
7823
diff
changeset
|
1691 retval = (do_in_runtimepath(buffer, 0, prt_resource_name, |
442 | 1692 resource->filename) |
1693 && resource->filename[0] != NUL); | |
2770 | 1694 vim_free(buffer); |
1695 return retval; | |
442 | 1696 } |
1697 | |
1698 /* PS CR and LF characters have platform independent values */ | |
1699 #define PSLF (0x0a) | |
1700 #define PSCR (0x0d) | |
1701 | |
1702 /* Static buffer to read initial comments in a resource file, some can have a | |
1703 * couple of KB of comments! */ | |
1704 #define PRT_FILE_BUFFER_LEN (2048) | |
1705 struct prt_resfile_buffer_S | |
1706 { | |
1707 char_u buffer[PRT_FILE_BUFFER_LEN]; | |
1708 int len; | |
1709 int line_start; | |
1710 int line_end; | |
1711 }; | |
1712 | |
1713 static struct prt_resfile_buffer_S prt_resfile; | |
1714 | |
1715 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1716 prt_resfile_next_line(void) |
442 | 1717 { |
944 | 1718 int idx; |
442 | 1719 |
1720 /* Move to start of next line and then find end of line */ | |
944 | 1721 idx = prt_resfile.line_end + 1; |
1722 while (idx < prt_resfile.len) | |
442 | 1723 { |
944 | 1724 if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) |
856 | 1725 break; |
944 | 1726 idx++; |
442 | 1727 } |
944 | 1728 prt_resfile.line_start = idx; |
1729 | |
1730 while (idx < prt_resfile.len) | |
442 | 1731 { |
944 | 1732 if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR) |
856 | 1733 break; |
944 | 1734 idx++; |
442 | 1735 } |
944 | 1736 prt_resfile.line_end = idx; |
1737 | |
1738 return (idx < prt_resfile.len); | |
442 | 1739 } |
1740 | |
1741 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1742 prt_resfile_strncmp(int offset, char *string, int len) |
442 | 1743 { |
1744 /* Force not equal if string is longer than remainder of line */ | |
1745 if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset))) | |
856 | 1746 return 1; |
442 | 1747 |
1748 return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset], | |
856 | 1749 string, len); |
442 | 1750 } |
1751 | |
1752 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1753 prt_resfile_skip_nonws(int offset) |
442 | 1754 { |
944 | 1755 int idx; |
1756 | |
1757 idx = prt_resfile.line_start + offset; | |
1758 while (idx < prt_resfile.line_end) | |
442 | 1759 { |
944 | 1760 if (isspace(prt_resfile.buffer[idx])) |
1761 return idx - prt_resfile.line_start; | |
1762 idx++; | |
442 | 1763 } |
1764 return -1; | |
1765 } | |
1766 | |
1767 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1768 prt_resfile_skip_ws(int offset) |
442 | 1769 { |
944 | 1770 int idx; |
1771 | |
1772 idx = prt_resfile.line_start + offset; | |
1773 while (idx < prt_resfile.line_end) | |
442 | 1774 { |
944 | 1775 if (!isspace(prt_resfile.buffer[idx])) |
1776 return idx - prt_resfile.line_start; | |
1777 idx++; | |
442 | 1778 } |
1779 return -1; | |
1780 } | |
1781 | |
1782 /* prt_next_dsc() - returns detail on next DSC comment line found. Returns true | |
1783 * if a DSC comment is found, else false */ | |
1784 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1785 prt_next_dsc(struct prt_dsc_line_S *p_dsc_line) |
442 | 1786 { |
1787 int comment; | |
1788 int offset; | |
1789 | |
1790 /* Move to start of next line */ | |
1791 if (!prt_resfile_next_line()) | |
856 | 1792 return FALSE; |
442 | 1793 |
1794 /* DSC comments always start %% */ | |
1795 if (prt_resfile_strncmp(0, "%%", 2) != 0) | |
856 | 1796 return FALSE; |
442 | 1797 |
1798 /* Find type of DSC comment */ | |
1880 | 1799 for (comment = 0; comment < (int)NUM_ELEMENTS(prt_dsc_table); comment++) |
856 | 1800 if (prt_resfile_strncmp(0, prt_dsc_table[comment].string, |
1801 prt_dsc_table[comment].len) == 0) | |
1802 break; | |
442 | 1803 |
1804 if (comment != NUM_ELEMENTS(prt_dsc_table)) | |
1805 { | |
856 | 1806 /* Return type of comment */ |
1807 p_dsc_line->type = prt_dsc_table[comment].type; | |
1808 offset = prt_dsc_table[comment].len; | |
442 | 1809 } |
1810 else | |
1811 { | |
856 | 1812 /* Unrecognised DSC comment, skip to ws after comment leader */ |
1813 p_dsc_line->type = PRT_DSC_MISC_TYPE; | |
1814 offset = prt_resfile_skip_nonws(0); | |
1815 if (offset == -1) | |
1816 return FALSE; | |
442 | 1817 } |
1818 | |
1819 /* Skip ws to comment value */ | |
1820 offset = prt_resfile_skip_ws(offset); | |
1821 if (offset == -1) | |
856 | 1822 return FALSE; |
442 | 1823 |
1824 p_dsc_line->string = &prt_resfile.buffer[prt_resfile.line_start + offset]; | |
1825 p_dsc_line->len = prt_resfile.line_end - (prt_resfile.line_start + offset); | |
1826 | |
1827 return TRUE; | |
1828 } | |
1829 | |
1830 /* Improved hand crafted parser to get the type, title, and version number of a | |
1831 * PS resource file so the file details can be added to the DSC header comments. | |
1832 */ | |
1833 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1834 prt_open_resource(struct prt_ps_resource_S *resource) |
442 | 1835 { |
856 | 1836 int offset; |
1837 int seen_all; | |
1838 int seen_title; | |
1839 int seen_version; | |
442 | 1840 FILE *fd_resource; |
1841 struct prt_dsc_line_S dsc_line; | |
1842 | |
1843 fd_resource = mch_fopen((char *)resource->filename, READBIN); | |
1844 if (fd_resource == NULL) | |
1845 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1846 semsg(_("E624: Can't open file \"%s\""), resource->filename); |
442 | 1847 return FALSE; |
1848 } | |
1849 vim_memset(prt_resfile.buffer, NUL, PRT_FILE_BUFFER_LEN); | |
1850 | |
1851 /* Parse first line to ensure valid resource file */ | |
835 | 1852 prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u), |
856 | 1853 PRT_FILE_BUFFER_LEN, fd_resource); |
442 | 1854 if (ferror(fd_resource)) |
1855 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1856 semsg(_("E457: Can't read PostScript resource file \"%s\""), |
442 | 1857 resource->filename); |
1858 fclose(fd_resource); | |
1859 return FALSE; | |
1860 } | |
2445
04dae202d316
Fixes for coverity warnings.
Bram Moolenaar <bram@vim.org>
parents:
2250
diff
changeset
|
1861 fclose(fd_resource); |
442 | 1862 |
1863 prt_resfile.line_end = -1; | |
1864 prt_resfile.line_start = 0; | |
1865 if (!prt_resfile_next_line()) | |
856 | 1866 return FALSE; |
442 | 1867 |
1868 offset = 0; | |
1869 | |
1870 if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER, | |
835 | 1871 (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) |
442 | 1872 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1873 semsg(_("E618: file \"%s\" is not a PostScript resource file"), |
442 | 1874 resource->filename); |
1875 return FALSE; | |
1876 } | |
1877 | |
1878 /* Skip over any version numbers and following ws */ | |
835 | 1879 offset += (int)STRLEN(PRT_RESOURCE_HEADER); |
442 | 1880 offset = prt_resfile_skip_nonws(offset); |
1881 if (offset == -1) | |
856 | 1882 return FALSE; |
442 | 1883 offset = prt_resfile_skip_ws(offset); |
1884 if (offset == -1) | |
856 | 1885 return FALSE; |
442 | 1886 |
1887 if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE, | |
835 | 1888 (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) |
442 | 1889 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1890 semsg(_("E619: file \"%s\" is not a supported PostScript resource file"), |
442 | 1891 resource->filename); |
1892 return FALSE; | |
1893 } | |
835 | 1894 offset += (int)STRLEN(PRT_RESOURCE_RESOURCE); |
442 | 1895 |
1896 /* Decide type of resource in the file */ | |
1897 if (prt_resfile_strncmp(offset, PRT_RESOURCE_PROCSET, | |
835 | 1898 (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0) |
442 | 1899 resource->type = PRT_RESOURCE_TYPE_PROCSET; |
1900 else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING, | |
835 | 1901 (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0) |
442 | 1902 resource->type = PRT_RESOURCE_TYPE_ENCODING; |
1903 else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP, | |
835 | 1904 (int)STRLEN(PRT_RESOURCE_CMAP)) == 0) |
442 | 1905 resource->type = PRT_RESOURCE_TYPE_CMAP; |
1906 else | |
1907 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1908 semsg(_("E619: file \"%s\" is not a supported PostScript resource file"), |
442 | 1909 resource->filename); |
1910 return FALSE; | |
1911 } | |
1912 | |
1913 /* Look for title and version of resource */ | |
1914 resource->title[0] = '\0'; | |
1915 resource->version[0] = '\0'; | |
1916 seen_title = FALSE; | |
1917 seen_version = FALSE; | |
1918 seen_all = FALSE; | |
1919 while (!seen_all && prt_next_dsc(&dsc_line)) | |
1920 { | |
856 | 1921 switch (dsc_line.type) |
1922 { | |
1923 case PRT_DSC_TITLE_TYPE: | |
1924 vim_strncpy(resource->title, dsc_line.string, dsc_line.len); | |
1925 seen_title = TRUE; | |
1926 if (seen_version) | |
1927 seen_all = TRUE; | |
1928 break; | |
1929 | |
1930 case PRT_DSC_VERSION_TYPE: | |
1931 vim_strncpy(resource->version, dsc_line.string, dsc_line.len); | |
1932 seen_version = TRUE; | |
1933 if (seen_title) | |
1934 seen_all = TRUE; | |
1935 break; | |
1936 | |
1937 case PRT_DSC_ENDCOMMENTS_TYPE: | |
1938 /* Wont find title or resource after this comment, stop searching */ | |
1939 seen_all = TRUE; | |
1940 break; | |
1941 | |
1942 case PRT_DSC_MISC_TYPE: | |
1943 /* Not interested in whatever comment this line had */ | |
1944 break; | |
1945 } | |
442 | 1946 } |
1947 | |
1948 if (!seen_title || !seen_version) | |
1949 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1950 semsg(_("E619: file \"%s\" is not a supported PostScript resource file"), |
442 | 1951 resource->filename); |
1952 return FALSE; | |
1953 } | |
1954 | |
1955 return TRUE; | |
1956 } | |
1957 | |
1958 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1959 prt_check_resource(struct prt_ps_resource_S *resource, char_u *version) |
442 | 1960 { |
1961 /* Version number m.n should match, the revision number does not matter */ | |
1962 if (STRNCMP(resource->version, version, STRLEN(version))) | |
1963 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
1964 semsg(_("E621: \"%s\" resource file has wrong version"), |
442 | 1965 resource->name); |
1966 return FALSE; | |
1967 } | |
1968 | |
1969 /* Other checks to be added as needed */ | |
1970 return TRUE; | |
1971 } | |
1972 | |
1973 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1974 prt_dsc_start(void) |
442 | 1975 { |
1976 prt_write_string("%!PS-Adobe-3.0\n"); | |
1977 } | |
1978 | |
1979 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1980 prt_dsc_noarg(char *comment) |
442 | 1981 { |
1982 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1983 "%%%%%s\n", comment); | |
1984 prt_write_file(prt_line_buffer); | |
1985 } | |
1986 | |
1987 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1988 prt_dsc_textline(char *comment, char *text) |
442 | 1989 { |
1990 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
1991 "%%%%%s: %s\n", comment, text); | |
1992 prt_write_file(prt_line_buffer); | |
1993 } | |
1994 | |
1995 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1996 prt_dsc_text(char *comment, char *text) |
442 | 1997 { |
1998 /* TODO - should scan 'text' for any chars needing escaping! */ | |
1999 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
2000 "%%%%%s: (%s)\n", comment, text); | |
2001 prt_write_file(prt_line_buffer); | |
2002 } | |
2003 | |
2004 #define prt_dsc_atend(c) prt_dsc_text((c), "atend") | |
2005 | |
2006 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2007 prt_dsc_ints(char *comment, int count, int *ints) |
442 | 2008 { |
2009 int i; | |
2010 | |
2011 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
2012 "%%%%%s:", comment); | |
2013 prt_write_file(prt_line_buffer); | |
2014 | |
2015 for (i = 0; i < count; i++) | |
2016 { | |
2017 sprintf((char *)prt_line_buffer, " %d", ints[i]); | |
2018 prt_write_file(prt_line_buffer); | |
2019 } | |
2020 | |
2021 prt_write_string("\n"); | |
2022 } | |
2023 | |
2024 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2025 prt_dsc_resources( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2026 char *comment, /* if NULL add to previous */ |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2027 char *type, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2028 char *string) |
442 | 2029 { |
2030 if (comment != NULL) | |
2031 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
2032 "%%%%%s: %s", comment, type); | |
2033 else | |
2034 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
2035 "%%%%+ %s", type); | |
2036 prt_write_file(prt_line_buffer); | |
2037 | |
2038 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
2039 " %s\n", string); | |
2040 prt_write_file(prt_line_buffer); | |
2041 } | |
2042 | |
2043 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2044 prt_dsc_font_resource(char *resource, struct prt_ps_font_S *ps_font) |
442 | 2045 { |
2046 int i; | |
2047 | |
2048 prt_dsc_resources(resource, "font", | |
856 | 2049 ps_font->ps_fontname[PRT_PS_FONT_ROMAN]); |
442 | 2050 for (i = PRT_PS_FONT_BOLD ; i <= PRT_PS_FONT_BOLDOBLIQUE ; i++) |
856 | 2051 if (ps_font->ps_fontname[i] != NULL) |
2052 prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]); | |
442 | 2053 } |
2054 | |
2055 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2056 prt_dsc_requirements( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2057 int duplex, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2058 int tumble, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2059 int collate, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2060 int color, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2061 int num_copies) |
442 | 2062 { |
2063 /* Only output the comment if we need to. | |
2064 * Note: tumble is ignored if we are not duplexing | |
2065 */ | |
2066 if (!(duplex || collate || color || (num_copies > 1))) | |
2067 return; | |
2068 | |
2069 sprintf((char *)prt_line_buffer, "%%%%Requirements:"); | |
2070 prt_write_file(prt_line_buffer); | |
2071 | |
2072 if (duplex) | |
2073 { | |
2074 prt_write_string(" duplex"); | |
2075 if (tumble) | |
2076 prt_write_string("(tumble)"); | |
2077 } | |
2078 if (collate) | |
2079 prt_write_string(" collate"); | |
2080 if (color) | |
2081 prt_write_string(" color"); | |
2082 if (num_copies > 1) | |
2083 { | |
2084 prt_write_string(" numcopies("); | |
4352 | 2085 /* Note: no space wanted so don't use prt_write_int() */ |
442 | 2086 sprintf((char *)prt_line_buffer, "%d", num_copies); |
2087 prt_write_file(prt_line_buffer); | |
2088 prt_write_string(")"); | |
2089 } | |
2090 prt_write_string("\n"); | |
2091 } | |
2092 | |
2093 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2094 prt_dsc_docmedia( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2095 char *paper_name, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2096 double width, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2097 double height, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2098 double weight, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2099 char *colour, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2100 char *type) |
442 | 2101 { |
2102 vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), | |
2103 "%%%%DocumentMedia: %s ", paper_name); | |
2104 prt_write_file(prt_line_buffer); | |
2105 prt_write_real(width, 2); | |
2106 prt_write_real(height, 2); | |
2107 prt_write_real(weight, 2); | |
2108 if (colour == NULL) | |
2109 prt_write_string("()"); | |
2110 else | |
2111 prt_write_string(colour); | |
2112 prt_write_string(" "); | |
2113 if (type == NULL) | |
2114 prt_write_string("()"); | |
2115 else | |
2116 prt_write_string(type); | |
2117 prt_write_string("\n"); | |
2118 } | |
2119 | |
2120 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2121 mch_print_cleanup(void) |
442 | 2122 { |
2123 if (prt_out_mbyte) | |
2124 { | |
856 | 2125 int i; |
2126 | |
2127 /* Free off all CID font names created, but first clear duplicate | |
2128 * pointers to the same string (when the same font is used for more than | |
2129 * one style). | |
2130 */ | |
2131 for (i = PRT_PS_FONT_ROMAN; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) | |
2132 { | |
2133 if (prt_ps_mb_font.ps_fontname[i] != NULL) | |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
2134 VIM_CLEAR(prt_ps_mb_font.ps_fontname[i]); |
856 | 2135 } |
442 | 2136 } |
2137 | |
2138 if (prt_do_conv) | |
2139 { | |
2140 convert_setup(&prt_conv, NULL, NULL); | |
2141 prt_do_conv = FALSE; | |
2142 } | |
2143 if (prt_ps_fd != NULL) | |
2144 { | |
2145 fclose(prt_ps_fd); | |
2146 prt_ps_fd = NULL; | |
2147 prt_file_error = FALSE; | |
2148 } | |
2149 if (prt_ps_file_name != NULL) | |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
2150 VIM_CLEAR(prt_ps_file_name); |
442 | 2151 } |
2152 | |
2153 static float | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2154 to_device_units(int idx, double physsize, int def_number) |
442 | 2155 { |
2156 float ret; | |
2157 int u; | |
2158 int nr; | |
2159 | |
2160 u = prt_get_unit(idx); | |
2161 if (u == PRT_UNIT_NONE) | |
2162 { | |
2163 u = PRT_UNIT_PERC; | |
2164 nr = def_number; | |
2165 } | |
2166 else | |
2167 nr = printer_opts[idx].number; | |
2168 | |
2169 switch (u) | |
2170 { | |
2171 case PRT_UNIT_INCH: | |
2172 ret = (float)(nr * PRT_PS_DEFAULT_DPI); | |
2173 break; | |
2174 case PRT_UNIT_MM: | |
2175 ret = (float)(nr * PRT_PS_DEFAULT_DPI) / (float)25.4; | |
2176 break; | |
2177 case PRT_UNIT_POINT: | |
2178 ret = (float)nr; | |
2179 break; | |
2180 case PRT_UNIT_PERC: | |
2181 default: | |
2182 ret = (float)(physsize * nr) / 100; | |
2183 break; | |
2184 } | |
2185 | |
2186 return ret; | |
2187 } | |
2188 | |
2189 /* | |
2190 * Calculate margins for given width and height from printoptions settings. | |
2191 */ | |
2192 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2193 prt_page_margins( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2194 double width, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2195 double height, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2196 double *left, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2197 double *right, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2198 double *top, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2199 double *bottom) |
442 | 2200 { |
2201 *left = to_device_units(OPT_PRINT_LEFT, width, 10); | |
2202 *right = width - to_device_units(OPT_PRINT_RIGHT, width, 5); | |
2203 *top = height - to_device_units(OPT_PRINT_TOP, height, 5); | |
2204 *bottom = to_device_units(OPT_PRINT_BOT, height, 5); | |
2205 } | |
2206 | |
2207 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2208 prt_font_metrics(int font_scale) |
442 | 2209 { |
2210 prt_line_height = (float)font_scale; | |
2211 prt_char_width = (float)PRT_PS_FONT_TO_USER(font_scale, prt_ps_font->wx); | |
2212 } | |
2213 | |
2214 | |
2215 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2216 prt_get_cpl(void) |
442 | 2217 { |
2218 if (prt_use_number()) | |
2219 { | |
2220 prt_number_width = PRINT_NUMBER_WIDTH * prt_char_width; | |
856 | 2221 /* If we are outputting multi-byte characters then line numbers will be |
2222 * printed with half width characters | |
2223 */ | |
2224 if (prt_out_mbyte) | |
2225 prt_number_width /= 2; | |
442 | 2226 prt_left_margin += prt_number_width; |
2227 } | |
2228 else | |
2229 prt_number_width = 0.0; | |
2230 | |
2231 return (int)((prt_right_margin - prt_left_margin) / prt_char_width); | |
2232 } | |
2233 | |
2234 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2235 prt_build_cid_fontname(int font, char_u *name, int name_len) |
442 | 2236 { |
2237 char *fontname; | |
2238 | |
2239 fontname = (char *)alloc(name_len + 1); | |
2240 if (fontname == NULL) | |
856 | 2241 return FALSE; |
442 | 2242 vim_strncpy((char_u *)fontname, name, name_len); |
2243 prt_ps_mb_font.ps_fontname[font] = fontname; | |
2244 | |
2245 return TRUE; | |
2246 } | |
2247 | |
2248 /* | |
2249 * Get number of lines of text that fit on a page (excluding the header). | |
2250 */ | |
2251 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2252 prt_get_lpp(void) |
442 | 2253 { |
2254 int lpp; | |
2255 | |
2256 /* | |
2257 * Calculate offset to lower left corner of background rect based on actual | |
2258 * font height (based on its bounding box) and the line height, handling the | |
2259 * case where the font height can exceed the line height. | |
2260 */ | |
2261 prt_bgcol_offset = (float)PRT_PS_FONT_TO_USER(prt_line_height, | |
2262 prt_ps_font->bbox_min_y); | |
2263 if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) | |
2264 { | |
2265 prt_bgcol_offset -= (float)PRT_PS_FONT_TO_USER(prt_line_height, | |
2266 (1000.0 - (prt_ps_font->bbox_max_y - | |
2267 prt_ps_font->bbox_min_y)) / 2); | |
2268 } | |
2269 | |
2270 /* Get height for topmost line based on background rect offset. */ | |
2271 prt_first_line_height = prt_line_height + prt_bgcol_offset; | |
2272 | |
2273 /* Calculate lpp */ | |
2274 lpp = (int)((prt_top_margin - prt_bottom_margin) / prt_line_height); | |
2275 | |
2276 /* Adjust top margin if there is a header */ | |
2277 prt_top_margin -= prt_line_height * prt_header_height(); | |
2278 | |
2279 return lpp - prt_header_height(); | |
2280 } | |
2281 | |
2282 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2283 prt_match_encoding( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2284 char *p_encoding, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2285 struct prt_ps_mbfont_S *p_cmap, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2286 struct prt_ps_encoding_S **pp_mbenc) |
442 | 2287 { |
2288 int mbenc; | |
2289 int enc_len; | |
2290 struct prt_ps_encoding_S *p_mbenc; | |
2291 | |
2292 *pp_mbenc = NULL; | |
2293 /* Look for recognised encoding */ | |
835 | 2294 enc_len = (int)STRLEN(p_encoding); |
442 | 2295 p_mbenc = p_cmap->encodings; |
2296 for (mbenc = 0; mbenc < p_cmap->num_encodings; mbenc++) | |
2297 { | |
856 | 2298 if (STRNICMP(p_mbenc->encoding, p_encoding, enc_len) == 0) |
2299 { | |
2300 *pp_mbenc = p_mbenc; | |
2301 return TRUE; | |
2302 } | |
2303 p_mbenc++; | |
442 | 2304 } |
2305 return FALSE; | |
2306 } | |
2307 | |
2308 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2309 prt_match_charset( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2310 char *p_charset, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2311 struct prt_ps_mbfont_S *p_cmap, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2312 struct prt_ps_charset_S **pp_mbchar) |
442 | 2313 { |
2314 int mbchar; | |
2315 int char_len; | |
2316 struct prt_ps_charset_S *p_mbchar; | |
2317 | |
2318 /* Look for recognised character set, using default if one is not given */ | |
2319 if (*p_charset == NUL) | |
856 | 2320 p_charset = p_cmap->defcs; |
835 | 2321 char_len = (int)STRLEN(p_charset); |
442 | 2322 p_mbchar = p_cmap->charsets; |
2323 for (mbchar = 0; mbchar < p_cmap->num_charsets; mbchar++) | |
2324 { | |
856 | 2325 if (STRNICMP(p_mbchar->charset, p_charset, char_len) == 0) |
2326 { | |
2327 *pp_mbchar = p_mbchar; | |
2328 return TRUE; | |
2329 } | |
2330 p_mbchar++; | |
442 | 2331 } |
2332 return FALSE; | |
2333 } | |
2334 | |
2335 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2336 mch_print_init( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2337 prt_settings_T *psettings, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2338 char_u *jobname, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2339 int forceit UNUSED) |
442 | 2340 { |
2341 int i; | |
2342 char *paper_name; | |
2343 int paper_strlen; | |
2344 int fontsize; | |
2345 char_u *p; | |
2346 double left; | |
2347 double right; | |
2348 double top; | |
2349 double bottom; | |
856 | 2350 int props; |
2351 int cmap = 0; | |
442 | 2352 char_u *p_encoding; |
2353 struct prt_ps_encoding_S *p_mbenc; | |
2354 struct prt_ps_encoding_S *p_mbenc_first; | |
944 | 2355 struct prt_ps_charset_S *p_mbchar = NULL; |
442 | 2356 |
2357 #if 0 | |
2358 /* | |
2359 * TODO: | |
2360 * If "forceit" is false: pop up a dialog to select: | |
2361 * - printer name | |
2362 * - copies | |
2363 * - collated/uncollated | |
2364 * - duplex off/long side/short side | |
2365 * - paper size | |
2366 * - portrait/landscape | |
2367 * - font size | |
2368 * | |
2369 * If "forceit" is true: use the default printer and settings | |
2370 */ | |
2371 if (forceit) | |
2372 s_pd.Flags |= PD_RETURNDEFAULT; | |
2373 #endif | |
2374 | |
2375 /* | |
2376 * Set up font and encoding. | |
2377 */ | |
2378 p_encoding = enc_skip(p_penc); | |
2379 if (*p_encoding == NUL) | |
856 | 2380 p_encoding = enc_skip(p_enc); |
442 | 2381 |
864 | 2382 /* Look for a multi-byte font that matches the encoding and character set. |
2383 * Only look if multi-byte character set is defined, or using multi-byte | |
2384 * encoding other than Unicode. This is because a Unicode encoding does not | |
2385 * uniquely identify a CJK character set to use. */ | |
442 | 2386 p_mbenc = NULL; |
819 | 2387 props = enc_canon_props(p_encoding); |
864 | 2388 if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) |
819 | 2389 { |
6759 | 2390 int cmap_first = 0; |
6745 | 2391 |
856 | 2392 p_mbenc_first = NULL; |
1880 | 2393 for (cmap = 0; cmap < (int)NUM_ELEMENTS(prt_ps_mbfonts); cmap++) |
856 | 2394 if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap], |
442 | 2395 &p_mbenc)) |
856 | 2396 { |
2397 if (p_mbenc_first == NULL) | |
6745 | 2398 { |
856 | 2399 p_mbenc_first = p_mbenc; |
6745 | 2400 cmap_first = cmap; |
2401 } | |
856 | 2402 if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap], |
442 | 2403 &p_mbchar)) |
856 | 2404 break; |
2405 } | |
2406 | |
2407 /* Use first encoding matched if no charset matched */ | |
2408 if (p_mbchar == NULL && p_mbenc_first != NULL) | |
6745 | 2409 { |
856 | 2410 p_mbenc = p_mbenc_first; |
6745 | 2411 cmap = cmap_first; |
2412 } | |
819 | 2413 } |
442 | 2414 |
2415 prt_out_mbyte = (p_mbenc != NULL); | |
2416 if (prt_out_mbyte) | |
2417 { | |
856 | 2418 /* Build CMap name - will be same for all multi-byte fonts used */ |
2419 prt_cmap[0] = NUL; | |
2420 | |
2421 prt_custom_cmap = (p_mbchar == NULL); | |
2422 if (!prt_custom_cmap) | |
2423 { | |
2424 /* Check encoding and character set are compatible */ | |
2425 if ((p_mbenc->needs_charset & p_mbchar->has_charset) == 0) | |
2426 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2427 emsg(_("E673: Incompatible multi-byte encoding and character set.")); |
856 | 2428 return FALSE; |
2429 } | |
2430 | |
2431 /* Add charset name if not empty */ | |
2432 if (p_mbchar->cmap_charset != NULL) | |
2433 { | |
2434 vim_strncpy((char_u *)prt_cmap, | |
442 | 2435 (char_u *)p_mbchar->cmap_charset, sizeof(prt_cmap) - 3); |
856 | 2436 STRCAT(prt_cmap, "-"); |
2437 } | |
2438 } | |
2439 else | |
2440 { | |
2441 /* Add custom CMap character set name */ | |
2442 if (*p_pmcs == NUL) | |
2443 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2444 emsg(_("E674: printmbcharset cannot be empty with multi-byte encoding.")); |
856 | 2445 return FALSE; |
2446 } | |
2447 vim_strncpy((char_u *)prt_cmap, p_pmcs, sizeof(prt_cmap) - 3); | |
2448 STRCAT(prt_cmap, "-"); | |
2449 } | |
2450 | |
2451 /* CMap name ends with (optional) encoding name and -H for horizontal */ | |
2452 if (p_mbenc->cmap_encoding != NULL && STRLEN(prt_cmap) | |
442 | 2453 + STRLEN(p_mbenc->cmap_encoding) + 3 < sizeof(prt_cmap)) |
856 | 2454 { |
2455 STRCAT(prt_cmap, p_mbenc->cmap_encoding); | |
2456 STRCAT(prt_cmap, "-"); | |
2457 } | |
2458 STRCAT(prt_cmap, "H"); | |
2459 | |
2460 if (!mbfont_opts[OPT_MBFONT_REGULAR].present) | |
2461 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2462 emsg(_("E675: No default font specified for multi-byte printing.")); |
856 | 2463 return FALSE; |
2464 } | |
2465 | |
2466 /* Derive CID font names with fallbacks if not defined */ | |
2467 if (!prt_build_cid_fontname(PRT_PS_FONT_ROMAN, | |
2468 mbfont_opts[OPT_MBFONT_REGULAR].string, | |
2469 mbfont_opts[OPT_MBFONT_REGULAR].strlen)) | |
2470 return FALSE; | |
2471 if (mbfont_opts[OPT_MBFONT_BOLD].present) | |
2472 if (!prt_build_cid_fontname(PRT_PS_FONT_BOLD, | |
2473 mbfont_opts[OPT_MBFONT_BOLD].string, | |
2474 mbfont_opts[OPT_MBFONT_BOLD].strlen)) | |
2475 return FALSE; | |
2476 if (mbfont_opts[OPT_MBFONT_OBLIQUE].present) | |
2477 if (!prt_build_cid_fontname(PRT_PS_FONT_OBLIQUE, | |
2478 mbfont_opts[OPT_MBFONT_OBLIQUE].string, | |
2479 mbfont_opts[OPT_MBFONT_OBLIQUE].strlen)) | |
2480 return FALSE; | |
2481 if (mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].present) | |
2482 if (!prt_build_cid_fontname(PRT_PS_FONT_BOLDOBLIQUE, | |
442 | 2483 mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].string, |
2484 mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].strlen)) | |
856 | 2485 return FALSE; |
2486 | |
2487 /* Check if need to use Courier for ASCII code range, and if so pick up | |
2488 * the encoding to use */ | |
2489 prt_use_courier = mbfont_opts[OPT_MBFONT_USECOURIER].present && | |
2490 (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0]) == 'y'); | |
2491 if (prt_use_courier) | |
2492 { | |
2493 /* Use national ASCII variant unless ASCII wanted */ | |
2494 if (mbfont_opts[OPT_MBFONT_ASCII].present && | |
2495 (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_ASCII].string[0]) == 'y')) | |
2496 prt_ascii_encoding = "ascii"; | |
2497 else | |
2498 prt_ascii_encoding = prt_ps_mbfonts[cmap].ascii_enc; | |
2499 } | |
2500 | |
2501 prt_ps_font = &prt_ps_mb_font; | |
442 | 2502 } |
2503 else | |
2504 { | |
856 | 2505 prt_use_courier = FALSE; |
2506 prt_ps_font = &prt_ps_courier_font; | |
442 | 2507 } |
2508 | |
2509 /* | |
2510 * Find the size of the paper and set the margins. | |
2511 */ | |
2512 prt_portrait = (!printer_opts[OPT_PRINT_PORTRAIT].present | |
2513 || TOLOWER_ASC(printer_opts[OPT_PRINT_PORTRAIT].string[0]) == 'y'); | |
2514 if (printer_opts[OPT_PRINT_PAPER].present) | |
2515 { | |
2516 paper_name = (char *)printer_opts[OPT_PRINT_PAPER].string; | |
2517 paper_strlen = printer_opts[OPT_PRINT_PAPER].strlen; | |
2518 } | |
2519 else | |
2520 { | |
2521 paper_name = "A4"; | |
2522 paper_strlen = 2; | |
2523 } | |
1880 | 2524 for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i) |
442 | 2525 if (STRLEN(prt_mediasize[i].name) == (unsigned)paper_strlen |
2526 && STRNICMP(prt_mediasize[i].name, paper_name, | |
2527 paper_strlen) == 0) | |
2528 break; | |
2529 if (i == PRT_MEDIASIZE_LEN) | |
2530 i = 0; | |
2531 prt_media = i; | |
2532 | |
2533 /* | |
2534 * Set PS pagesize based on media dimensions and print orientation. | |
2535 * Note: Media and page sizes have defined meanings in PostScript and should | |
2536 * be kept distinct. Media is the paper (or transparency, or ...) that is | |
2537 * printed on, whereas the page size is the area that the PostScript | |
2538 * interpreter renders into. | |
2539 */ | |
2540 if (prt_portrait) | |
2541 { | |
2542 prt_page_width = prt_mediasize[i].width; | |
2543 prt_page_height = prt_mediasize[i].height; | |
2544 } | |
2545 else | |
2546 { | |
2547 prt_page_width = prt_mediasize[i].height; | |
2548 prt_page_height = prt_mediasize[i].width; | |
2549 } | |
2550 | |
2551 /* | |
2552 * Set PS page margins based on the PS pagesize, not the mediasize - this | |
2553 * needs to be done before the cpl and lpp are calculated. | |
2554 */ | |
2555 prt_page_margins(prt_page_width, prt_page_height, &left, &right, &top, | |
2556 &bottom); | |
2557 prt_left_margin = (float)left; | |
2558 prt_right_margin = (float)right; | |
2559 prt_top_margin = (float)top; | |
2560 prt_bottom_margin = (float)bottom; | |
2561 | |
2562 /* | |
2563 * Set up the font size. | |
2564 */ | |
2565 fontsize = PRT_PS_DEFAULT_FONTSIZE; | |
2566 for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p) | |
2567 if (p[1] == 'h' && VIM_ISDIGIT(p[2])) | |
2568 fontsize = atoi((char *)p + 2); | |
2569 prt_font_metrics(fontsize); | |
2570 | |
2571 /* | |
2572 * Return the number of characters per line, and lines per page for the | |
2573 * generic print code. | |
2574 */ | |
2575 psettings->chars_per_line = prt_get_cpl(); | |
2576 psettings->lines_per_page = prt_get_lpp(); | |
2577 | |
2578 /* Catch margin settings that leave no space for output! */ | |
2579 if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0) | |
2580 return FAIL; | |
2581 | |
2582 /* | |
2583 * Sort out the number of copies to be printed. PS by default will do | |
2584 * uncollated copies for you, so once we know how many uncollated copies are | |
2585 * wanted cache it away and lie to the generic code that we only want one | |
2586 * uncollated copy. | |
2587 */ | |
2588 psettings->n_collated_copies = 1; | |
2589 psettings->n_uncollated_copies = 1; | |
2590 prt_num_copies = 1; | |
2591 prt_collate = (!printer_opts[OPT_PRINT_COLLATE].present | |
2592 || TOLOWER_ASC(printer_opts[OPT_PRINT_COLLATE].string[0]) == 'y'); | |
2593 if (prt_collate) | |
2594 { | |
2595 /* TODO: Get number of collated copies wanted. */ | |
2596 psettings->n_collated_copies = 1; | |
2597 } | |
2598 else | |
2599 { | |
2600 /* TODO: Get number of uncollated copies wanted and update the cached | |
2601 * count. | |
2602 */ | |
2603 prt_num_copies = 1; | |
2604 } | |
2605 | |
2606 psettings->jobname = jobname; | |
2607 | |
2608 /* | |
2609 * Set up printer duplex and tumble based on Duplex option setting - default | |
2610 * is long sided duplex printing (i.e. no tumble). | |
2611 */ | |
2612 prt_duplex = TRUE; | |
2613 prt_tumble = FALSE; | |
2614 psettings->duplex = 1; | |
2615 if (printer_opts[OPT_PRINT_DUPLEX].present) | |
2616 { | |
2617 if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "off", 3) == 0) | |
2618 { | |
2619 prt_duplex = FALSE; | |
2620 psettings->duplex = 0; | |
2621 } | |
2622 else if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "short", 5) | |
2623 == 0) | |
2624 prt_tumble = TRUE; | |
2625 } | |
2626 | |
2627 /* For now user abort not supported */ | |
2628 psettings->user_abort = 0; | |
2629 | |
2630 /* If the user didn't specify a file name, use a temp file. */ | |
2631 if (psettings->outfile == NULL) | |
2632 { | |
6721 | 2633 prt_ps_file_name = vim_tempname('p', TRUE); |
442 | 2634 if (prt_ps_file_name == NULL) |
2635 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2636 emsg(_(e_notmp)); |
442 | 2637 return FAIL; |
2638 } | |
2639 prt_ps_fd = mch_fopen((char *)prt_ps_file_name, WRITEBIN); | |
2640 } | |
2641 else | |
2642 { | |
2643 p = expand_env_save(psettings->outfile); | |
2644 if (p != NULL) | |
2645 { | |
2646 prt_ps_fd = mch_fopen((char *)p, WRITEBIN); | |
2647 vim_free(p); | |
2648 } | |
2649 } | |
2650 if (prt_ps_fd == NULL) | |
2651 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2652 emsg(_("E324: Can't open PostScript output file")); |
442 | 2653 mch_print_cleanup(); |
2654 return FAIL; | |
2655 } | |
2656 | |
2657 prt_bufsiz = psettings->chars_per_line; | |
2658 if (prt_out_mbyte) | |
856 | 2659 prt_bufsiz *= 2; |
442 | 2660 ga_init2(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz); |
2661 | |
2662 prt_page_num = 0; | |
2663 | |
2664 prt_attribute_change = FALSE; | |
2665 prt_need_moveto = FALSE; | |
2666 prt_need_font = FALSE; | |
2667 prt_need_fgcol = FALSE; | |
2668 prt_need_bgcol = FALSE; | |
2669 prt_need_underline = FALSE; | |
2670 | |
2671 prt_file_error = FALSE; | |
2672 | |
2673 return OK; | |
2674 } | |
2675 | |
2676 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2677 prt_add_resource(struct prt_ps_resource_S *resource) |
442 | 2678 { |
2679 FILE* fd_resource; | |
2680 char_u resource_buffer[512]; | |
2681 size_t bytes_read; | |
2682 | |
2683 fd_resource = mch_fopen((char *)resource->filename, READBIN); | |
2684 if (fd_resource == NULL) | |
2685 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2686 semsg(_("E456: Can't open file \"%s\""), resource->filename); |
442 | 2687 return FALSE; |
2688 } | |
2689 prt_dsc_resources("BeginResource", prt_resource_types[resource->type], | |
2690 (char *)resource->title); | |
2691 | |
2692 prt_dsc_textline("BeginDocument", (char *)resource->filename); | |
2693 | |
2694 for (;;) | |
2695 { | |
2696 bytes_read = fread((char *)resource_buffer, sizeof(char_u), | |
2697 sizeof(resource_buffer), fd_resource); | |
2698 if (ferror(fd_resource)) | |
2699 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2700 semsg(_("E457: Can't read PostScript resource file \"%s\""), |
442 | 2701 resource->filename); |
2702 fclose(fd_resource); | |
2703 return FALSE; | |
2704 } | |
2705 if (bytes_read == 0) | |
2706 break; | |
835 | 2707 prt_write_file_raw_len(resource_buffer, (int)bytes_read); |
442 | 2708 if (prt_file_error) |
2709 { | |
2710 fclose(fd_resource); | |
2711 return FALSE; | |
2712 } | |
2713 } | |
2714 fclose(fd_resource); | |
2715 | |
2716 prt_dsc_noarg("EndDocument"); | |
2717 | |
2718 prt_dsc_noarg("EndResource"); | |
2719 | |
2720 return TRUE; | |
2721 } | |
2722 | |
2723 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2724 mch_print_begin(prt_settings_T *psettings) |
442 | 2725 { |
2726 time_t now; | |
2727 int bbox[4]; | |
2728 char *p_time; | |
2729 double left; | |
2730 double right; | |
2731 double top; | |
2732 double bottom; | |
2770 | 2733 struct prt_ps_resource_S *res_prolog; |
2734 struct prt_ps_resource_S *res_encoding; | |
442 | 2735 char buffer[256]; |
2736 char_u *p_encoding; | |
840 | 2737 char_u *p; |
2770 | 2738 struct prt_ps_resource_S *res_cidfont; |
2739 struct prt_ps_resource_S *res_cmap; | |
2740 int retval = FALSE; | |
2741 | |
2742 res_prolog = (struct prt_ps_resource_S *) | |
2743 alloc(sizeof(struct prt_ps_resource_S)); | |
2744 res_encoding = (struct prt_ps_resource_S *) | |
2745 alloc(sizeof(struct prt_ps_resource_S)); | |
2746 res_cidfont = (struct prt_ps_resource_S *) | |
2747 alloc(sizeof(struct prt_ps_resource_S)); | |
2748 res_cmap = (struct prt_ps_resource_S *) | |
2749 alloc(sizeof(struct prt_ps_resource_S)); | |
2750 if (res_prolog == NULL || res_encoding == NULL | |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
2751 || res_cidfont == NULL || res_cmap == NULL) |
2770 | 2752 goto theend; |
442 | 2753 |
2754 /* | |
2755 * PS DSC Header comments - no PS code! | |
2756 */ | |
2757 prt_dsc_start(); | |
2758 prt_dsc_textline("Title", (char *)psettings->jobname); | |
2759 if (!get_user_name((char_u *)buffer, 256)) | |
856 | 2760 STRCPY(buffer, "Unknown"); |
442 | 2761 prt_dsc_textline("For", buffer); |
2762 prt_dsc_textline("Creator", VIM_VERSION_LONG); | |
2763 /* Note: to ensure Clean8bit I don't think we can use LC_TIME */ | |
2764 now = time(NULL); | |
2765 p_time = ctime(&now); | |
2766 /* Note: ctime() adds a \n so we have to remove it :-( */ | |
840 | 2767 p = vim_strchr((char_u *)p_time, '\n'); |
2768 if (p != NULL) | |
2769 *p = NUL; | |
442 | 2770 prt_dsc_textline("CreationDate", p_time); |
2771 prt_dsc_textline("DocumentData", "Clean8Bit"); | |
2772 prt_dsc_textline("Orientation", "Portrait"); | |
2773 prt_dsc_atend("Pages"); | |
2774 prt_dsc_textline("PageOrder", "Ascend"); | |
2775 /* The bbox does not change with orientation - it is always in the default | |
2776 * user coordinate system! We have to recalculate right and bottom | |
2777 * coordinates based on the font metrics for the bbox to be accurate. */ | |
2778 prt_page_margins(prt_mediasize[prt_media].width, | |
2779 prt_mediasize[prt_media].height, | |
2780 &left, &right, &top, &bottom); | |
2781 bbox[0] = (int)left; | |
2782 if (prt_portrait) | |
2783 { | |
2784 /* In portrait printing the fixed point is the top left corner so we | |
2785 * derive the bbox from that point. We have the expected cpl chars | |
2786 * across the media and lpp lines down the media. | |
2787 */ | |
2788 bbox[1] = (int)(top - (psettings->lines_per_page + prt_header_height()) | |
2789 * prt_line_height); | |
2790 bbox[2] = (int)(left + psettings->chars_per_line * prt_char_width | |
2791 + 0.5); | |
2792 bbox[3] = (int)(top + 0.5); | |
2793 } | |
2794 else | |
2795 { | |
2796 /* In landscape printing the fixed point is the bottom left corner so we | |
2797 * derive the bbox from that point. We have lpp chars across the media | |
2798 * and cpl lines up the media. | |
2799 */ | |
2800 bbox[1] = (int)bottom; | |
2801 bbox[2] = (int)(left + ((psettings->lines_per_page | |
2802 + prt_header_height()) * prt_line_height) + 0.5); | |
2803 bbox[3] = (int)(bottom + psettings->chars_per_line * prt_char_width | |
2804 + 0.5); | |
2805 } | |
2806 prt_dsc_ints("BoundingBox", 4, bbox); | |
2807 /* The media width and height does not change with landscape printing! */ | |
2808 prt_dsc_docmedia(prt_mediasize[prt_media].name, | |
2809 prt_mediasize[prt_media].width, | |
2810 prt_mediasize[prt_media].height, | |
2811 (double)0, NULL, NULL); | |
2812 /* Define fonts needed */ | |
2813 if (!prt_out_mbyte || prt_use_courier) | |
856 | 2814 prt_dsc_font_resource("DocumentNeededResources", &prt_ps_courier_font); |
442 | 2815 if (prt_out_mbyte) |
2816 { | |
856 | 2817 prt_dsc_font_resource((prt_use_courier ? NULL |
2818 : "DocumentNeededResources"), &prt_ps_mb_font); | |
2819 if (!prt_custom_cmap) | |
2820 prt_dsc_resources(NULL, "cmap", prt_cmap); | |
442 | 2821 } |
2822 | |
2823 /* Search for external resources VIM supplies */ | |
2770 | 2824 if (!prt_find_resource("prolog", res_prolog)) |
442 | 2825 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2826 emsg(_("E456: Can't find PostScript resource file \"prolog.ps\"")); |
6404 | 2827 goto theend; |
442 | 2828 } |
2770 | 2829 if (!prt_open_resource(res_prolog)) |
6404 | 2830 goto theend; |
2770 | 2831 if (!prt_check_resource(res_prolog, PRT_PROLOG_VERSION)) |
6404 | 2832 goto theend; |
442 | 2833 if (prt_out_mbyte) |
2834 { | |
856 | 2835 /* Look for required version of multi-byte printing procset */ |
2770 | 2836 if (!prt_find_resource("cidfont", res_cidfont)) |
856 | 2837 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2838 emsg(_("E456: Can't find PostScript resource file \"cidfont.ps\"")); |
6404 | 2839 goto theend; |
856 | 2840 } |
2770 | 2841 if (!prt_open_resource(res_cidfont)) |
6404 | 2842 goto theend; |
2770 | 2843 if (!prt_check_resource(res_cidfont, PRT_CID_PROLOG_VERSION)) |
6404 | 2844 goto theend; |
442 | 2845 } |
2846 | |
2847 /* Find an encoding to use for printing. | |
2848 * Check 'printencoding'. If not set or not found, then use 'encoding'. If | |
2849 * that cannot be found then default to "latin1". | |
2850 * Note: VIM specific encoding header is always skipped. | |
2851 */ | |
2852 if (!prt_out_mbyte) | |
2853 { | |
856 | 2854 p_encoding = enc_skip(p_penc); |
2855 if (*p_encoding == NUL | |
2770 | 2856 || !prt_find_resource((char *)p_encoding, res_encoding)) |
856 | 2857 { |
2858 /* 'printencoding' not set or not supported - find alternate */ | |
2859 int props; | |
2860 | |
2861 p_encoding = enc_skip(p_enc); | |
2862 props = enc_canon_props(p_encoding); | |
2863 if (!(props & ENC_8BIT) | |
2770 | 2864 || !prt_find_resource((char *)p_encoding, res_encoding)) |
856 | 2865 /* 8-bit 'encoding' is not supported */ |
2866 { | |
2867 /* Use latin1 as default printing encoding */ | |
2868 p_encoding = (char_u *)"latin1"; | |
2770 | 2869 if (!prt_find_resource((char *)p_encoding, res_encoding)) |
856 | 2870 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2871 semsg(_("E456: Can't find PostScript resource file \"%s.ps\""), |
856 | 2872 p_encoding); |
6404 | 2873 goto theend; |
856 | 2874 } |
2875 } | |
2876 } | |
2770 | 2877 if (!prt_open_resource(res_encoding)) |
6404 | 2878 goto theend; |
856 | 2879 /* For the moment there are no checks on encoding resource files to |
2880 * perform */ | |
442 | 2881 } |
2882 else | |
2883 { | |
856 | 2884 p_encoding = enc_skip(p_penc); |
2885 if (*p_encoding == NUL) | |
2886 p_encoding = enc_skip(p_enc); | |
2887 if (prt_use_courier) | |
2888 { | |
2889 /* Include ASCII range encoding vector */ | |
2770 | 2890 if (!prt_find_resource(prt_ascii_encoding, res_encoding)) |
856 | 2891 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2892 semsg(_("E456: Can't find PostScript resource file \"%s.ps\""), |
442 | 2893 prt_ascii_encoding); |
6404 | 2894 goto theend; |
856 | 2895 } |
2770 | 2896 if (!prt_open_resource(res_encoding)) |
6404 | 2897 goto theend; |
856 | 2898 /* For the moment there are no checks on encoding resource files to |
2899 * perform */ | |
2900 } | |
442 | 2901 } |
2902 | |
2903 prt_conv.vc_type = CONV_NONE; | |
2904 if (!(enc_canon_props(p_enc) & enc_canon_props(p_encoding) & ENC_8BIT)) { | |
856 | 2905 /* Set up encoding conversion if required */ |
442 | 2906 if (FAIL == convert_setup(&prt_conv, p_enc, p_encoding)) |
2907 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2908 semsg(_("E620: Unable to convert to print encoding \"%s\""), |
442 | 2909 p_encoding); |
6404 | 2910 goto theend; |
442 | 2911 } |
2912 prt_do_conv = TRUE; | |
2913 } | |
2914 prt_do_conv = prt_conv.vc_type != CONV_NONE; | |
2915 | |
2916 if (prt_out_mbyte && prt_custom_cmap) | |
2917 { | |
856 | 2918 /* Find user supplied CMap */ |
2770 | 2919 if (!prt_find_resource(prt_cmap, res_cmap)) |
856 | 2920 { |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
2921 semsg(_("E456: Can't find PostScript resource file \"%s.ps\""), |
442 | 2922 prt_cmap); |
6404 | 2923 goto theend; |
856 | 2924 } |
2770 | 2925 if (!prt_open_resource(res_cmap)) |
6404 | 2926 goto theend; |
442 | 2927 } |
2928 | |
2929 /* List resources supplied */ | |
2770 | 2930 STRCPY(buffer, res_prolog->title); |
442 | 2931 STRCAT(buffer, " "); |
2770 | 2932 STRCAT(buffer, res_prolog->version); |
442 | 2933 prt_dsc_resources("DocumentSuppliedResources", "procset", buffer); |
2934 if (prt_out_mbyte) | |
2935 { | |
2770 | 2936 STRCPY(buffer, res_cidfont->title); |
856 | 2937 STRCAT(buffer, " "); |
2770 | 2938 STRCAT(buffer, res_cidfont->version); |
856 | 2939 prt_dsc_resources(NULL, "procset", buffer); |
2940 | |
2941 if (prt_custom_cmap) | |
2942 { | |
2770 | 2943 STRCPY(buffer, res_cmap->title); |
856 | 2944 STRCAT(buffer, " "); |
2770 | 2945 STRCAT(buffer, res_cmap->version); |
856 | 2946 prt_dsc_resources(NULL, "cmap", buffer); |
2947 } | |
442 | 2948 } |
2949 if (!prt_out_mbyte || prt_use_courier) | |
2950 { | |
2770 | 2951 STRCPY(buffer, res_encoding->title); |
856 | 2952 STRCAT(buffer, " "); |
2770 | 2953 STRCAT(buffer, res_encoding->version); |
856 | 2954 prt_dsc_resources(NULL, "encoding", buffer); |
442 | 2955 } |
2956 prt_dsc_requirements(prt_duplex, prt_tumble, prt_collate, | |
2957 #ifdef FEAT_SYN_HL | |
2958 psettings->do_syntax | |
2959 #else | |
2960 0 | |
2961 #endif | |
2962 , prt_num_copies); | |
2963 prt_dsc_noarg("EndComments"); | |
2964 | |
2965 /* | |
2966 * PS Document page defaults | |
2967 */ | |
2968 prt_dsc_noarg("BeginDefaults"); | |
2969 | |
2970 /* List font resources most likely common to all pages */ | |
2971 if (!prt_out_mbyte || prt_use_courier) | |
856 | 2972 prt_dsc_font_resource("PageResources", &prt_ps_courier_font); |
442 | 2973 if (prt_out_mbyte) |
2974 { | |
856 | 2975 prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"), |
2976 &prt_ps_mb_font); | |
2977 if (!prt_custom_cmap) | |
2978 prt_dsc_resources(NULL, "cmap", prt_cmap); | |
442 | 2979 } |
2980 | |
2981 /* Paper will be used for all pages */ | |
2982 prt_dsc_textline("PageMedia", prt_mediasize[prt_media].name); | |
2983 | |
2984 prt_dsc_noarg("EndDefaults"); | |
2985 | |
2986 /* | |
2987 * PS Document prolog inclusion - all required procsets. | |
2988 */ | |
2989 prt_dsc_noarg("BeginProlog"); | |
2990 | |
2991 /* Add required procsets - NOTE: order is important! */ | |
2770 | 2992 if (!prt_add_resource(res_prolog)) |
6404 | 2993 goto theend; |
442 | 2994 if (prt_out_mbyte) |
2995 { | |
856 | 2996 /* Add CID font procset, and any user supplied CMap */ |
2770 | 2997 if (!prt_add_resource(res_cidfont)) |
6404 | 2998 goto theend; |
2770 | 2999 if (prt_custom_cmap && !prt_add_resource(res_cmap)) |
6404 | 3000 goto theend; |
442 | 3001 } |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
3002 |
442 | 3003 if (!prt_out_mbyte || prt_use_courier) |
856 | 3004 /* There will be only one Roman font encoding to be included in the PS |
3005 * file. */ | |
2770 | 3006 if (!prt_add_resource(res_encoding)) |
6404 | 3007 goto theend; |
442 | 3008 |
3009 prt_dsc_noarg("EndProlog"); | |
3010 | |
3011 /* | |
3012 * PS Document setup - must appear after the prolog | |
3013 */ | |
3014 prt_dsc_noarg("BeginSetup"); | |
3015 | |
3016 /* Device setup - page size and number of uncollated copies */ | |
3017 prt_write_int((int)prt_mediasize[prt_media].width); | |
3018 prt_write_int((int)prt_mediasize[prt_media].height); | |
3019 prt_write_int(0); | |
3020 prt_write_string("sps\n"); | |
3021 prt_write_int(prt_num_copies); | |
3022 prt_write_string("nc\n"); | |
3023 prt_write_boolean(prt_duplex); | |
3024 prt_write_boolean(prt_tumble); | |
3025 prt_write_string("dt\n"); | |
3026 prt_write_boolean(prt_collate); | |
3027 prt_write_string("c\n"); | |
3028 | |
3029 /* Font resource inclusion and definition */ | |
3030 if (!prt_out_mbyte || prt_use_courier) | |
3031 { | |
856 | 3032 /* When using Courier for ASCII range when printing multi-byte, need to |
3033 * pick up ASCII encoding to use with it. */ | |
3034 if (prt_use_courier) | |
3035 p_encoding = (char_u *)prt_ascii_encoding; | |
3036 prt_dsc_resources("IncludeResource", "font", | |
3037 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]); | |
3038 prt_def_font("F0", (char *)p_encoding, (int)prt_line_height, | |
3039 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]); | |
3040 prt_dsc_resources("IncludeResource", "font", | |
3041 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]); | |
3042 prt_def_font("F1", (char *)p_encoding, (int)prt_line_height, | |
3043 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]); | |
3044 prt_dsc_resources("IncludeResource", "font", | |
3045 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); | |
3046 prt_def_font("F2", (char *)p_encoding, (int)prt_line_height, | |
3047 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); | |
3048 prt_dsc_resources("IncludeResource", "font", | |
3049 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); | |
3050 prt_def_font("F3", (char *)p_encoding, (int)prt_line_height, | |
3051 prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); | |
442 | 3052 } |
3053 if (prt_out_mbyte) | |
3054 { | |
856 | 3055 /* Define the CID fonts to be used in the job. Typically CJKV fonts do |
3056 * not have an italic form being a western style, so where no font is | |
3057 * defined for these faces VIM falls back to an existing face. | |
3058 * Note: if using Courier for the ASCII range then the printout will | |
3059 * have bold/italic/bolditalic regardless of the setting of printmbfont. | |
3060 */ | |
3061 prt_dsc_resources("IncludeResource", "font", | |
3062 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]); | |
3063 if (!prt_custom_cmap) | |
3064 prt_dsc_resources("IncludeResource", "cmap", prt_cmap); | |
3065 prt_def_cidfont("CF0", (int)prt_line_height, | |
3066 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]); | |
3067 | |
3068 if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD] != NULL) | |
3069 { | |
3070 prt_dsc_resources("IncludeResource", "font", | |
3071 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); | |
3072 if (!prt_custom_cmap) | |
3073 prt_dsc_resources("IncludeResource", "cmap", prt_cmap); | |
3074 prt_def_cidfont("CF1", (int)prt_line_height, | |
3075 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); | |
3076 } | |
3077 else | |
3078 /* Use ROMAN for BOLD */ | |
3079 prt_dup_cidfont("CF0", "CF1"); | |
3080 | |
3081 if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) | |
3082 { | |
3083 prt_dsc_resources("IncludeResource", "font", | |
3084 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); | |
3085 if (!prt_custom_cmap) | |
3086 prt_dsc_resources("IncludeResource", "cmap", prt_cmap); | |
3087 prt_def_cidfont("CF2", (int)prt_line_height, | |
3088 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); | |
3089 } | |
3090 else | |
3091 /* Use ROMAN for OBLIQUE */ | |
3092 prt_dup_cidfont("CF0", "CF2"); | |
3093 | |
3094 if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) | |
3095 { | |
3096 prt_dsc_resources("IncludeResource", "font", | |
3097 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); | |
3098 if (!prt_custom_cmap) | |
3099 prt_dsc_resources("IncludeResource", "cmap", prt_cmap); | |
3100 prt_def_cidfont("CF3", (int)prt_line_height, | |
3101 prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); | |
3102 } | |
3103 else | |
3104 /* Use BOLD for BOLDOBLIQUE */ | |
3105 prt_dup_cidfont("CF1", "CF3"); | |
442 | 3106 } |
3107 | |
3108 /* Misc constant vars used for underlining and background rects */ | |
3109 prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height, | |
3110 prt_ps_font->uline_offset), 2); | |
3111 prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height, | |
3112 prt_ps_font->uline_width), 2); | |
3113 prt_def_var("BO", prt_bgcol_offset, 2); | |
3114 | |
3115 prt_dsc_noarg("EndSetup"); | |
3116 | |
3117 /* Fail if any problems writing out to the PS file */ | |
2770 | 3118 retval = !prt_file_error; |
3119 | |
3120 theend: | |
3121 vim_free(res_prolog); | |
3122 vim_free(res_encoding); | |
3123 vim_free(res_cidfont); | |
3124 vim_free(res_cmap); | |
3125 | |
3126 return retval; | |
442 | 3127 } |
3128 | |
3129 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3130 mch_print_end(prt_settings_T *psettings) |
442 | 3131 { |
3132 prt_dsc_noarg("Trailer"); | |
3133 | |
3134 /* | |
3135 * Output any info we don't know in toto until we finish | |
3136 */ | |
3137 prt_dsc_ints("Pages", 1, &prt_page_num); | |
3138 | |
3139 prt_dsc_noarg("EOF"); | |
3140 | |
3141 /* Write CTRL-D to close serial communication link if used. | |
3142 * NOTHING MUST BE WRITTEN AFTER THIS! */ | |
3143 prt_write_file((char_u *)IF_EB("\004", "\067")); | |
3144 | |
3145 if (!prt_file_error && psettings->outfile == NULL | |
3146 && !got_int && !psettings->user_abort) | |
3147 { | |
3148 /* Close the file first. */ | |
3149 if (prt_ps_fd != NULL) | |
3150 { | |
3151 fclose(prt_ps_fd); | |
3152 prt_ps_fd = NULL; | |
3153 } | |
3154 prt_message((char_u *)_("Sending to printer...")); | |
3155 | |
3156 /* Not printing to a file: use 'printexpr' to print the file. */ | |
3157 if (eval_printexpr(prt_ps_file_name, psettings->arguments) == FAIL) | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
3158 emsg(_("E365: Failed to print PostScript file")); |
442 | 3159 else |
3160 prt_message((char_u *)_("Print job sent.")); | |
3161 } | |
3162 | |
3163 mch_print_cleanup(); | |
3164 } | |
3165 | |
3166 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3167 mch_print_end_page(void) |
442 | 3168 { |
3169 prt_flush_buffer(); | |
3170 | |
3171 prt_write_string("re sp\n"); | |
3172 | |
3173 prt_dsc_noarg("PageTrailer"); | |
3174 | |
3175 return !prt_file_error; | |
3176 } | |
3177 | |
3178 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3179 mch_print_begin_page(char_u *str UNUSED) |
442 | 3180 { |
3181 int page_num[2]; | |
3182 | |
3183 prt_page_num++; | |
3184 | |
3185 page_num[0] = page_num[1] = prt_page_num; | |
3186 prt_dsc_ints("Page", 2, page_num); | |
3187 | |
3188 prt_dsc_noarg("BeginPageSetup"); | |
3189 | |
3190 prt_write_string("sv\n0 g\n"); | |
3191 prt_in_ascii = !prt_out_mbyte; | |
3192 if (prt_out_mbyte) | |
856 | 3193 prt_write_string("CF0 sf\n"); |
442 | 3194 else |
856 | 3195 prt_write_string("F0 sf\n"); |
442 | 3196 prt_fgcol = PRCOLOR_BLACK; |
3197 prt_bgcol = PRCOLOR_WHITE; | |
3198 prt_font = PRT_PS_FONT_ROMAN; | |
3199 | |
3200 /* Set up page transformation for landscape printing. */ | |
3201 if (!prt_portrait) | |
3202 { | |
3203 prt_write_int(-((int)prt_mediasize[prt_media].width)); | |
3204 prt_write_string("sl\n"); | |
3205 } | |
3206 | |
3207 prt_dsc_noarg("EndPageSetup"); | |
3208 | |
3209 /* We have reset the font attributes, force setting them again. */ | |
3210 curr_bg = (long_u)0xffffffff; | |
3211 curr_fg = (long_u)0xffffffff; | |
3212 curr_bold = MAYBE; | |
3213 | |
3214 return !prt_file_error; | |
3215 } | |
3216 | |
3217 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3218 mch_print_blank_page(void) |
442 | 3219 { |
3220 return (mch_print_begin_page(NULL) ? (mch_print_end_page()) : FALSE); | |
3221 } | |
3222 | |
3223 static float prt_pos_x = 0; | |
3224 static float prt_pos_y = 0; | |
3225 | |
3226 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3227 mch_print_start_line(int margin, int page_line) |
442 | 3228 { |
3229 prt_pos_x = prt_left_margin; | |
3230 if (margin) | |
3231 prt_pos_x -= prt_number_width; | |
3232 | |
3233 prt_pos_y = prt_top_margin - prt_first_line_height - | |
3234 page_line * prt_line_height; | |
3235 | |
3236 prt_attribute_change = TRUE; | |
3237 prt_need_moveto = TRUE; | |
3238 prt_half_width = FALSE; | |
3239 } | |
3240 | |
3241 int | |
14077
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3242 mch_print_text_out(char_u *textp, int len UNUSED) |
442 | 3243 { |
14077
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3244 char_u *p = textp; |
442 | 3245 int need_break; |
3246 char_u ch; | |
3247 char_u ch_buff[8]; | |
3248 float char_width; | |
3249 float next_pos; | |
856 | 3250 int in_ascii; |
3251 int half_width; | |
13258
6acb9148d83e
patch 8.0.1503: access memory beyond end of string
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
3252 char_u *tofree = NULL; |
442 | 3253 |
3254 char_width = prt_char_width; | |
3255 | |
3256 /* Ideally VIM would create a rearranged CID font to combine a Roman and | |
3257 * CJKV font to do what VIM is doing here - use a Roman font for characters | |
1218 | 3258 * in the ASCII range, and the original CID font for everything else. |
442 | 3259 * The problem is that GhostScript still (as of 8.13) does not support |
3260 * rearranged fonts even though they have been documented by Adobe for 7 | |
3261 * years! If they ever do, a lot of this code will disappear. | |
3262 */ | |
3263 if (prt_use_courier) | |
3264 { | |
856 | 3265 in_ascii = (len == 1 && *p < 0x80); |
3266 if (prt_in_ascii) | |
3267 { | |
3268 if (!in_ascii) | |
3269 { | |
3270 /* No longer in ASCII range - need to switch font */ | |
3271 prt_in_ascii = FALSE; | |
3272 prt_need_font = TRUE; | |
3273 prt_attribute_change = TRUE; | |
3274 } | |
3275 } | |
3276 else if (in_ascii) | |
3277 { | |
3278 /* Now in ASCII range - need to switch font */ | |
3279 prt_in_ascii = TRUE; | |
3280 prt_need_font = TRUE; | |
3281 prt_attribute_change = TRUE; | |
3282 } | |
442 | 3283 } |
3284 if (prt_out_mbyte) | |
3285 { | |
856 | 3286 half_width = ((*mb_ptr2cells)(p) == 1); |
3287 if (half_width) | |
3288 char_width /= 2; | |
3289 if (prt_half_width) | |
3290 { | |
3291 if (!half_width) | |
3292 { | |
3293 prt_half_width = FALSE; | |
3294 prt_pos_x += prt_char_width/4; | |
3295 prt_need_moveto = TRUE; | |
3296 prt_attribute_change = TRUE; | |
3297 } | |
3298 } | |
3299 else if (half_width) | |
3300 { | |
3301 prt_half_width = TRUE; | |
3302 prt_pos_x += prt_char_width/4; | |
3303 prt_need_moveto = TRUE; | |
3304 prt_attribute_change = TRUE; | |
3305 } | |
442 | 3306 } |
3307 | |
3308 /* Output any required changes to the graphics state, after flushing any | |
3309 * text buffered so far. | |
3310 */ | |
3311 if (prt_attribute_change) | |
3312 { | |
3313 prt_flush_buffer(); | |
3314 /* Reset count of number of chars that will be printed */ | |
3315 prt_text_run = 0; | |
3316 | |
3317 if (prt_need_moveto) | |
3318 { | |
3319 prt_pos_x_moveto = prt_pos_x; | |
3320 prt_pos_y_moveto = prt_pos_y; | |
3321 prt_do_moveto = TRUE; | |
3322 | |
3323 prt_need_moveto = FALSE; | |
3324 } | |
3325 if (prt_need_font) | |
3326 { | |
856 | 3327 if (!prt_in_ascii) |
3328 prt_write_string("CF"); | |
3329 else | |
3330 prt_write_string("F"); | |
3331 prt_write_int(prt_font); | |
3332 prt_write_string("sf\n"); | |
3333 prt_need_font = FALSE; | |
442 | 3334 } |
3335 if (prt_need_fgcol) | |
3336 { | |
3337 int r, g, b; | |
3338 r = ((unsigned)prt_fgcol & 0xff0000) >> 16; | |
3339 g = ((unsigned)prt_fgcol & 0xff00) >> 8; | |
3340 b = prt_fgcol & 0xff; | |
3341 | |
3342 prt_write_real(r / 255.0, 3); | |
3343 if (r == g && g == b) | |
3344 prt_write_string("g\n"); | |
3345 else | |
3346 { | |
3347 prt_write_real(g / 255.0, 3); | |
3348 prt_write_real(b / 255.0, 3); | |
3349 prt_write_string("r\n"); | |
3350 } | |
3351 prt_need_fgcol = FALSE; | |
3352 } | |
3353 | |
3354 if (prt_bgcol != PRCOLOR_WHITE) | |
3355 { | |
3356 prt_new_bgcol = prt_bgcol; | |
3357 if (prt_need_bgcol) | |
3358 prt_do_bgcol = TRUE; | |
3359 } | |
3360 else | |
3361 prt_do_bgcol = FALSE; | |
3362 prt_need_bgcol = FALSE; | |
3363 | |
3364 if (prt_need_underline) | |
3365 prt_do_underline = prt_underline; | |
3366 prt_need_underline = FALSE; | |
3367 | |
3368 prt_attribute_change = FALSE; | |
3369 } | |
3370 | |
3371 if (prt_do_conv) | |
14077
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3372 { |
442 | 3373 /* Convert from multi-byte to 8-bit encoding */ |
13258
6acb9148d83e
patch 8.0.1503: access memory beyond end of string
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
3374 tofree = p = string_convert(&prt_conv, p, &len); |
14077
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3375 if (p == NULL) |
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3376 { |
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3377 p = (char_u *)""; |
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3378 len = 0; |
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3379 } |
873542706b0b
patch 8.1.0056: crash when using :hardcopy with illegal byte
Christian Brabandt <cb@256bit.org>
parents:
13258
diff
changeset
|
3380 } |
442 | 3381 |
3382 if (prt_out_mbyte) | |
3383 { | |
856 | 3384 /* Multi-byte character strings are represented more efficiently as hex |
3385 * strings when outputting clean 8 bit PS. | |
3386 */ | |
13258
6acb9148d83e
patch 8.0.1503: access memory beyond end of string
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
3387 while (len-- > 0) |
856 | 3388 { |
3389 ch = prt_hexchar[(unsigned)(*p) >> 4]; | |
3390 ga_append(&prt_ps_buffer, ch); | |
3391 ch = prt_hexchar[(*p) & 0xf]; | |
3392 ga_append(&prt_ps_buffer, ch); | |
3393 p++; | |
3394 } | |
442 | 3395 } |
3396 else | |
3397 { | |
856 | 3398 /* Add next character to buffer of characters to output. |
3399 * Note: One printed character may require several PS characters to | |
3400 * represent it, but we only count them as one printed character. | |
3401 */ | |
3402 ch = *p; | |
3403 if (ch < 32 || ch == '(' || ch == ')' || ch == '\\') | |
3404 { | |
3405 /* Convert non-printing characters to either their escape or octal | |
3406 * sequence, ensures PS sent over a serial line does not interfere | |
3407 * with the comms protocol. Note: For EBCDIC we need to write out | |
3408 * the escape sequences as ASCII codes! | |
442 | 3409 * Note 2: Char codes < 32 are identical in EBCDIC and ASCII AFAIK! |
3410 */ | |
856 | 3411 ga_append(&prt_ps_buffer, IF_EB('\\', 0134)); |
3412 switch (ch) | |
3413 { | |
3414 case BS: ga_append(&prt_ps_buffer, IF_EB('b', 0142)); break; | |
3415 case TAB: ga_append(&prt_ps_buffer, IF_EB('t', 0164)); break; | |
3416 case NL: ga_append(&prt_ps_buffer, IF_EB('n', 0156)); break; | |
3417 case FF: ga_append(&prt_ps_buffer, IF_EB('f', 0146)); break; | |
3418 case CAR: ga_append(&prt_ps_buffer, IF_EB('r', 0162)); break; | |
3419 case '(': ga_append(&prt_ps_buffer, IF_EB('(', 0050)); break; | |
3420 case ')': ga_append(&prt_ps_buffer, IF_EB(')', 0051)); break; | |
3421 case '\\': ga_append(&prt_ps_buffer, IF_EB('\\', 0134)); break; | |
3422 | |
3423 default: | |
3424 sprintf((char *)ch_buff, "%03o", (unsigned int)ch); | |
442 | 3425 #ifdef EBCDIC |
856 | 3426 ebcdic2ascii(ch_buff, 3); |
442 | 3427 #endif |
856 | 3428 ga_append(&prt_ps_buffer, ch_buff[0]); |
3429 ga_append(&prt_ps_buffer, ch_buff[1]); | |
3430 ga_append(&prt_ps_buffer, ch_buff[2]); | |
3431 break; | |
3432 } | |
3433 } | |
3434 else | |
3435 ga_append(&prt_ps_buffer, ch); | |
442 | 3436 } |
3437 | |
3438 /* Need to free any translated characters */ | |
13258
6acb9148d83e
patch 8.0.1503: access memory beyond end of string
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
3439 vim_free(tofree); |
442 | 3440 |
3441 prt_text_run += char_width; | |
3442 prt_pos_x += char_width; | |
3443 | |
3444 /* The downside of fp - use relative error on right margin check */ | |
3445 next_pos = prt_pos_x + prt_char_width; | |
3446 need_break = (next_pos > prt_right_margin) && | |
856 | 3447 ((next_pos - prt_right_margin) > (prt_right_margin*1e-5)); |
442 | 3448 |
3449 if (need_break) | |
3450 prt_flush_buffer(); | |
3451 | |
3452 return need_break; | |
3453 } | |
3454 | |
3455 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3456 mch_print_set_font(int iBold, int iItalic, int iUnderline) |
442 | 3457 { |
3458 int font = 0; | |
3459 | |
3460 if (iBold) | |
3461 font |= 0x01; | |
3462 if (iItalic) | |
3463 font |= 0x02; | |
3464 | |
3465 if (font != prt_font) | |
3466 { | |
3467 prt_font = font; | |
3468 prt_attribute_change = TRUE; | |
3469 prt_need_font = TRUE; | |
3470 } | |
3471 if (prt_underline != iUnderline) | |
3472 { | |
3473 prt_underline = iUnderline; | |
3474 prt_attribute_change = TRUE; | |
3475 prt_need_underline = TRUE; | |
3476 } | |
3477 } | |
3478 | |
3479 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3480 mch_print_set_bg(long_u bgcol) |
442 | 3481 { |
835 | 3482 prt_bgcol = (int)bgcol; |
442 | 3483 prt_attribute_change = TRUE; |
3484 prt_need_bgcol = TRUE; | |
3485 } | |
3486 | |
3487 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3488 mch_print_set_fg(long_u fgcol) |
442 | 3489 { |
3490 if (fgcol != (long_u)prt_fgcol) | |
3491 { | |
835 | 3492 prt_fgcol = (int)fgcol; |
442 | 3493 prt_attribute_change = TRUE; |
3494 prt_need_fgcol = TRUE; | |
3495 } | |
3496 } | |
3497 | |
3498 # endif /*FEAT_POSTSCRIPT*/ | |
3499 #endif /*FEAT_PRINTER*/ |