1 /* Copyright 2014 Clerk Ma
\r
3 This program is free software; you can redistribute it and/or modify
\r
4 it under the terms of the GNU General Public License as published by
\r
5 the Free Software Foundation; either version 2 of the License, or
\r
6 (at your option) any later version.
\r
8 This program is distributed in the hope that it will be useful, but
\r
9 WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
11 General Public License for more details.
\r
13 You should have received a copy of the GNU General Public License
\r
14 along with this program; if not, write to the Free Software
\r
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
\r
18 /* Y&Y TeX's DVIPDFMX backend. */
\r
20 #define EXTERN extern
\r
22 #include "yandytex.h"
\r
24 void ensure_pdf_open(void)
\r
26 if (output_file_name == 0)
\r
31 pack_job_name(".pdf");
\r
33 while (!b_open_out(pdf_file))
\r
34 prompt_file_name("file name for output", ".pdf");
\r
36 output_file_name = b_make_name_string(pdf_file);
\r
40 extern void pdf_set_version(unsigned version);
\r
41 extern void pdf_set_compression(int level);
\r
42 extern void pdf_doc_set_creator(const char * creator);
\r
43 extern void pdf_files_init(void);
\r
44 extern void pdf_init_device(double dvi2pts, int precision, int black_and_white);
\r
45 extern void pdf_open_document(const char *filename,
\r
47 double media_width, double media_height,
\r
48 double annot_grow_amount, int bookmark_open_depth,
\r
50 extern void pdf_doc_begin_page(double scale, double x_origin, double y_origin);
\r
51 extern void pdf_doc_end_page(void);
\r
52 extern int spc_exec_at_begin_document(void);
\r
53 extern int spc_exec_at_end_document(void);
\r
54 extern int spc_exec_at_begin_page(void);
\r
55 extern int spc_exec_at_end_page(void);
\r
56 extern void read_config_file (const char *config);
\r
57 extern void pdf_hlist_out (void);
\r
58 extern void pdf_vlist_out (void);
\r
60 void pdf_ship_out (pointer p)
\r
67 if (tracing_output > 0)
\r
71 prints("Completed box being shipped out");
\r
74 if (term_offset > max_print_line - 9)
\r
76 else if ((term_offset > 0) || (file_offset > 0))
\r
82 while ((count(j) == 0) && (j > 0))
\r
85 for (k = 0; k <= j; k++)
\r
87 print_int(count(k));
\r
95 if (tracing_output > 0)
\r
100 end_diagnostic(true);
\r
103 if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
\r
104 (height(p) + depth(p) + v_offset > max_dimen) ||
\r
105 (width(p) + h_offset > max_dimen))
\r
107 print_err("Huge page cannot be shipped out");
\r
108 help2("The page just created is more than 18 feet tall or",
\r
109 "more than 18 feet wide, so I suspect something went wrong.");
\r
112 if (tracing_output <= 0)
\r
114 begin_diagnostic();
\r
115 print_nl("The following box has been deleted:");
\r
117 end_diagnostic(true);
\r
123 if (height(p) + depth(p) + v_offset > max_v)
\r
124 max_v = height(p) + depth(p) + v_offset;
\r
126 if (width(p) + h_offset > max_h)
\r
127 max_h = width(p) + h_offset;
\r
135 if (total_pages == 0)
\r
137 //kpse_init_prog("", 600, NULL, NULL);
\r
138 //kpse_set_program_enabled(kpse_pk_format, true, kpse_src_texmf_cnf);
\r
139 //pdf_font_set_dpi(600);
\r
140 //dpx_delete_old_cache(image_cache_life);
\r
141 pdf_set_version(5);
\r
142 pdf_set_compression(9);
\r
143 pdf_init_fontmaps();
\r
144 read_config_file("dvipdfmx.cfg");
\r
145 pdf_doc_set_producer("Y&YTeX 2.3.0");
\r
146 pdf_doc_set_creator("TeX");
\r
148 pdf_init_device(0.000015202, 2, 0);
\r
149 pdf_open_document(pdf_file_name, 0, 595.0, 842.0, 0, 0, (1 << 4));
\r
150 spc_exec_at_begin_document();
\r
153 page_loc = dvi_offset + dvi_ptr;
\r
154 pdf_doc_begin_page(1.0, 72.0, 770.0);
\r
155 spc_exec_at_begin_page();
\r
157 last_bop = page_loc;
\r
158 cur_v = height(p) + v_offset;
\r
161 if (type(p) == vlist_node)
\r
166 spc_exec_at_end_page();
\r
167 pdf_doc_end_page();
\r
172 if (tracing_output <= 0)
\r
179 if (tracing_stats > 1)
\r
181 print_nl("Memory usage before: ");
\r
182 print_int(var_used);
\r
184 print_int(dyn_used);
\r
189 flush_node_list(p);
\r
192 if (tracing_stats > 1)
\r
194 prints(" after: ");
\r
195 print_int(var_used);
\r
197 print_int(dyn_used);
\r
198 prints("; still utouched: ");
\r
199 print_int(hi_mem_min - lo_mem_max - 1);
\r
205 void pdf_synch_h (void)
\r
207 if (cur_h != dvi_h)
\r
211 void pdf_synch_v (void)
\r
213 if (cur_v != dvi_v)
\r
217 int pdf_get_font_id (internal_font_number f)
\r
219 char * sbuf = malloc(length(font_name[f]) + 1);
\r
221 memset(sbuf, 0, length(font_name[f]) + 1);
\r
222 memcpy(sbuf, str_pool + str_start[font_name[f]], length(font_name[f]));
\r
223 id = dvi_locate_font(sbuf, font_size[f]);
\r
229 void pdf_hlist_out (void)
\r
233 scaled save_h, save_v;
\r
235 // glue_ord g_order;
\r
241 pointer leader_box;
\r
244 boolean outer_doing_leaders;
\r
252 this_box = temp_ptr;
\r
253 g_order = glue_order(this_box);
\r
254 g_sign = glue_sign(this_box);
\r
255 p = list_ptr(this_box);
\r
258 if (cur_s > max_push)
\r
261 save_loc = dvi_offset + dvi_ptr;
\r
267 if (is_char_node(p))
\r
281 font_used[f] = true;
\r
282 font_id[f] = pdf_get_font_id(f);
\r
288 char cbuf[2] = {c, 0};
\r
289 pdf_dev_set_string(cur_h, -cur_v, cbuf, 1, char_width(f, char_info(f, c)), font_id[dvi_f], 1);
\r
290 cur_h = cur_h + char_width(f, char_info(f, c));
\r
292 } while (!(!is_char_node(p)));
\r
302 if (list_ptr(p) == 0)
\r
303 cur_h = cur_h + width(p);
\r
308 cur_v = base_line + shift_amount(p);
\r
312 if (type(p) == vlist_node)
\r
319 cur_h = edge + width(p);
\r
326 rule_ht = height(p);
\r
327 rule_dp = depth(p);
\r
328 rule_wd = width(p);
\r
340 rule_wd = width(g) - cur_g;
\r
342 if (g_sign != normal)
\r
344 if (g_sign == stretching)
\r
346 if (stretch_order(g) == g_order)
\r
348 cur_glue = cur_glue + stretch(g);
\r
349 vet_glue(glue_set(this_box) * cur_glue);
\r
350 cur_g = round(glue_temp);
\r
353 else if (shrink_order(g) == g_order)
\r
355 cur_glue = cur_glue - shrink(g);
\r
356 vet_glue(glue_set(this_box) * cur_glue);
\r
357 cur_g = round(glue_temp);
\r
361 rule_wd = rule_wd + cur_g;
\r
363 if (subtype(p) >= a_leaders)
\r
365 leader_box = leader_ptr(p);
\r
367 if (type(leader_box) == rule_node)
\r
369 rule_ht = height(leader_box);
\r
370 rule_dp = depth(leader_box);
\r
374 leader_wd = width(leader_box);
\r
376 if ((leader_wd > 0) && (rule_wd > 0))
\r
378 rule_wd = rule_wd + 10;
\r
379 edge = cur_h + rule_wd;
\r
382 if (subtype(p) == a_leaders)
\r
385 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
\r
387 if (cur_h < save_h)
\r
388 cur_h = cur_h + leader_wd;
\r
392 lq = rule_wd / leader_wd;
\r
393 lr = rule_wd % leader_wd;
\r
395 if (subtype(p) == c_leaders)
\r
396 cur_h = cur_h + (lr / 2);
\r
399 lx = (2 * lr + lq + 1) / (2 * lq + 2);
\r
400 cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
\r
404 while (cur_h + leader_wd <= edge)
\r
406 cur_v = base_line + shift_amount(leader_box);
\r
411 temp_ptr = leader_box;
\r
412 outer_doing_leaders = doing_leaders;
\r
413 doing_leaders = true;
\r
415 if (type(leader_box) == vlist_node)
\r
420 doing_leaders = outer_doing_leaders;
\r
424 cur_h = save_h + leader_wd + lx;
\r
438 cur_h = cur_h + width(p);
\r
441 case ligature_node:
\r
443 mem[lig_trick] = mem[lig_char(p)];
\r
444 link(lig_trick) = link(p);
\r
457 if (is_running(rule_ht))
\r
458 rule_ht = height(this_box);
\r
460 if (is_running(rule_dp))
\r
461 rule_dp = depth(this_box);
\r
463 rule_ht = rule_ht + rule_dp;
\r
465 if ((rule_ht > 0) && (rule_wd > 0))
\r
468 cur_v = base_line + rule_dp;
\r
470 pdf_dev_set_rule(dvi_h, dvi_v, rule_wd, rule_ht);
\r
472 dvi_h = dvi_h + rule_wd;
\r
476 cur_h = cur_h + rule_wd;
\r
482 prune_movements(save_loc);
\r
486 void pdf_vlist_out (void)
\r
490 scaled save_h, save_v;
\r
492 // glue_ord g_order;
\r
498 pointer leader_box;
\r
501 boolean outer_doing_leaders;
\r
509 this_box = temp_ptr;
\r
510 g_order = glue_order(this_box);
\r
511 g_sign = glue_sign(this_box);
\r
512 p = list_ptr(this_box);
\r
515 if (cur_s > max_push)
\r
518 save_loc = dvi_offset + dvi_ptr;
\r
520 cur_v = cur_v - height(this_box);
\r
525 if (is_char_node(p))
\r
527 confusion("vlistout");
\r
536 if (list_ptr(p) == 0)
\r
537 cur_v = cur_v + height(p) + depth(p);
\r
540 cur_v = cur_v + height(p);
\r
544 cur_h = left_edge + shift_amount(p);
\r
547 if (type(p) == vlist_node)
\r
554 cur_v = save_v + depth(p);
\r
561 rule_ht = height(p);
\r
562 rule_dp = depth(p);
\r
563 rule_wd = width(p);
\r
575 rule_ht = width(g) - cur_g;
\r
577 if (g_sign != normal)
\r
579 if (g_sign == stretching)
\r
581 if (stretch_order(g) == g_order)
\r
583 cur_glue = cur_glue + stretch(g);
\r
584 vet_glue(glue_set(this_box) * cur_glue);
\r
585 cur_g = round(glue_temp);
\r
588 else if (shrink_order(g) == g_order) /* BUG FIX !!! */
\r
590 cur_glue = cur_glue - shrink(g);
\r
591 vet_glue(glue_set(this_box) * cur_glue);
\r
592 cur_g = round(glue_temp);
\r
596 rule_ht = rule_ht + cur_g;
\r
598 if (subtype(p) >= a_leaders)
\r
600 leader_box = leader_ptr(p);
\r
602 if (type(leader_box) == rule_node)
\r
604 rule_wd = width(leader_box);
\r
609 leader_ht = height(leader_box) + depth(leader_box);
\r
611 if ((leader_ht > 0) && (rule_ht > 0))
\r
613 rule_ht = rule_ht + 10;
\r
614 edge = cur_v + rule_ht;
\r
617 if (subtype(p) == a_leaders)
\r
620 cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
\r
622 if (cur_v < save_v)
\r
623 cur_v = cur_v + leader_ht;
\r
627 lq = rule_ht / leader_ht;
\r
628 lr = rule_ht % leader_ht;
\r
630 if (subtype(p) == c_leaders)
\r
631 cur_v = cur_v + (lr / 2);
\r
634 lx = (2 * lr + lq + 1) / (2 * lq + 2);
\r
635 cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
\r
639 while (cur_v + leader_ht <= edge)
\r
641 cur_h = left_edge + shift_amount(leader_box);
\r
644 cur_v = cur_v + height(leader_box);
\r
647 temp_ptr = leader_box;
\r
648 outer_doing_leaders = doing_leaders;
\r
649 doing_leaders = true;
\r
651 if (type(leader_box) == vlist_node)
\r
656 doing_leaders = outer_doing_leaders;
\r
660 cur_v = save_v - height(leader_box) + leader_ht + lx;
\r
673 cur_v = cur_v + width(p);
\r
683 if (is_running(rule_wd))
\r
684 rule_wd = width(this_box);
\r
686 rule_ht = rule_ht + rule_dp;
\r
687 cur_v = cur_v + rule_ht;
\r
689 if ((rule_ht > 0) && (rule_wd > 0))
\r
693 pdf_dev_set_rule(cur_h, -cur_v, rule_wd, rule_ht);
\r
699 cur_v = cur_v + rule_ht;
\r
706 prune_movements(save_loc);
\r