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
23 #include "yandytex.h"
\r
25 void ensure_pdf_open(void)
\r
27 if (output_file_name == 0)
\r
32 pack_job_name(".pdf");
\r
34 while (!b_open_out(pdf_file))
\r
35 prompt_file_name("file name for output", ".pdf");
\r
37 output_file_name = b_make_name_string(pdf_file);
\r
41 void pdf_ship_out (pointer p)
\r
48 if (tracing_output > 0)
\r
52 prints("Completed box being shipped out");
\r
55 if (term_offset > max_print_line - 9)
\r
57 else if ((term_offset > 0) || (file_offset > 0))
\r
63 while ((count(j) == 0) && (j > 0))
\r
66 for (k = 0; k <= j; k++)
\r
68 print_int(count(k));
\r
76 if (tracing_output > 0)
\r
81 end_diagnostic(true);
\r
84 if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
\r
85 (height(p) + depth(p) + v_offset > max_dimen) ||
\r
86 (width(p) + h_offset > max_dimen))
\r
88 print_err("Huge page cannot be shipped out");
\r
89 help2("The page just created is more than 18 feet tall or",
\r
90 "more than 18 feet wide, so I suspect something went wrong.");
\r
93 if (tracing_output <= 0)
\r
96 print_nl("The following box has been deleted:");
\r
98 end_diagnostic(true);
\r
104 if (height(p) + depth(p) + v_offset > max_v)
\r
105 max_v = height(p) + depth(p) + v_offset;
\r
107 if (width(p) + h_offset > max_h)
\r
108 max_h = width(p) + h_offset;
\r
116 if (total_pages == 0)
\r
118 pdf_set_version(5);
\r
119 pdf_set_compression(9);
\r
120 pdf_init_fontmaps();
\r
121 read_config_file("dvipdfmx.cfg");
\r
122 pdf_doc_set_producer("Y&YTeX 2.3.0");
\r
123 pdf_doc_set_creator("TeX");
\r
125 pdf_init_device(0.000015202, 2, 0);
\r
126 pdf_open_document(pdf_file_name, 0, 595.0, 842.0, 0, 0, (1 << 4));
\r
127 spc_exec_at_begin_document();
\r
130 page_loc = dvi_offset + dvi_ptr;
\r
131 pdf_doc_begin_page(1.0, 72.0, 770.0);
\r
132 spc_exec_at_begin_page();
\r
134 last_bop = page_loc;
\r
135 cur_v = height(p) + v_offset;
\r
138 if (type(p) == vlist_node)
\r
143 spc_exec_at_end_page();
\r
144 pdf_doc_end_page();
\r
149 if (tracing_output <= 0)
\r
156 if (tracing_stats > 1)
\r
158 print_nl("Memory usage before: ");
\r
159 print_int(var_used);
\r
161 print_int(dyn_used);
\r
166 flush_node_list(p);
\r
169 if (tracing_stats > 1)
\r
171 prints(" after: ");
\r
172 print_int(var_used);
\r
174 print_int(dyn_used);
\r
175 prints("; still utouched: ");
\r
176 print_int(hi_mem_min - lo_mem_max - 1);
\r
182 void pdf_synch_h (void)
\r
184 if (cur_h != dvi_h)
\r
188 void pdf_synch_v (void)
\r
190 if (cur_v != dvi_v)
\r
194 int pdf_get_font_id (internal_font_number f)
\r
196 char * sbuf = malloc(length(font_name[f]) + 1);
\r
198 memset(sbuf, 0, length(font_name[f]) + 1);
\r
199 memcpy(sbuf, str_pool + str_start[font_name[f]], length(font_name[f]));
\r
200 id = dvi_locate_font(sbuf, font_size[f]);
\r
206 void pdf_hlist_out (void)
\r
210 scaled save_h, save_v;
\r
212 // glue_ord g_order;
\r
218 pointer leader_box;
\r
221 boolean outer_doing_leaders;
\r
229 this_box = temp_ptr;
\r
230 g_order = glue_order(this_box);
\r
231 g_sign = glue_sign(this_box);
\r
232 p = list_ptr(this_box);
\r
235 if (cur_s > max_push)
\r
238 save_loc = dvi_offset + dvi_ptr;
\r
244 if (is_char_node(p))
\r
258 font_used[f] = true;
\r
259 font_id[f] = pdf_get_font_id(f);
\r
265 char cbuf[2] = {c, 0};
\r
266 pdf_dev_set_string(cur_h, -cur_v, cbuf, 1, char_width(f, char_info(f, c)), font_id[dvi_f], 1);
\r
269 pdf_dev_set_rect(&rect, cur_h, -dvi_v,
\r
270 char_width (f, char_info(f, c)),
\r
271 char_height(f, height_depth(char_info(f, c))),
\r
272 char_depth (f, height_depth(char_info(f, c))));
\r
273 pdf_doc_expand_box(&rect);
\r
275 cur_h = cur_h + char_width(f, char_info(f, c));
\r
277 } while (!(!is_char_node(p)));
\r
287 if (list_ptr(p) == 0)
\r
288 cur_h = cur_h + width(p);
\r
293 cur_v = base_line + shift_amount(p);
\r
297 if (type(p) == vlist_node)
\r
304 cur_h = edge + width(p);
\r
311 rule_ht = height(p);
\r
312 rule_dp = depth(p);
\r
313 rule_wd = width(p);
\r
325 rule_wd = width(g) - cur_g;
\r
327 if (g_sign != normal)
\r
329 if (g_sign == stretching)
\r
331 if (stretch_order(g) == g_order)
\r
333 cur_glue = cur_glue + stretch(g);
\r
334 vet_glue(glue_set(this_box) * cur_glue);
\r
335 cur_g = round(glue_temp);
\r
338 else if (shrink_order(g) == g_order)
\r
340 cur_glue = cur_glue - shrink(g);
\r
341 vet_glue(glue_set(this_box) * cur_glue);
\r
342 cur_g = round(glue_temp);
\r
346 rule_wd = rule_wd + cur_g;
\r
348 if (subtype(p) >= a_leaders)
\r
350 leader_box = leader_ptr(p);
\r
352 if (type(leader_box) == rule_node)
\r
354 rule_ht = height(leader_box);
\r
355 rule_dp = depth(leader_box);
\r
359 leader_wd = width(leader_box);
\r
361 if ((leader_wd > 0) && (rule_wd > 0))
\r
363 rule_wd = rule_wd + 10;
\r
364 edge = cur_h + rule_wd;
\r
367 if (subtype(p) == a_leaders)
\r
370 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
\r
372 if (cur_h < save_h)
\r
373 cur_h = cur_h + leader_wd;
\r
377 lq = rule_wd / leader_wd;
\r
378 lr = rule_wd % leader_wd;
\r
380 if (subtype(p) == c_leaders)
\r
381 cur_h = cur_h + (lr / 2);
\r
384 lx = (2 * lr + lq + 1) / (2 * lq + 2);
\r
385 cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
\r
389 while (cur_h + leader_wd <= edge)
\r
391 cur_v = base_line + shift_amount(leader_box);
\r
396 temp_ptr = leader_box;
\r
397 outer_doing_leaders = doing_leaders;
\r
398 doing_leaders = true;
\r
400 if (type(leader_box) == vlist_node)
\r
405 doing_leaders = outer_doing_leaders;
\r
409 cur_h = save_h + leader_wd + lx;
\r
423 cur_h = cur_h + width(p);
\r
426 case ligature_node:
\r
428 mem[lig_trick] = mem[lig_char(p)];
\r
429 link(lig_trick) = link(p);
\r
442 if (is_running(rule_ht))
\r
443 rule_ht = height(this_box);
\r
445 if (is_running(rule_dp))
\r
446 rule_dp = depth(this_box);
\r
448 rule_ht = rule_ht + rule_dp;
\r
450 if ((rule_ht > 0) && (rule_wd > 0))
\r
453 cur_v = base_line + rule_dp;
\r
455 pdf_dev_set_rule(dvi_h, -dvi_v, rule_wd, rule_ht);
\r
457 dvi_h = dvi_h + rule_wd;
\r
461 cur_h = cur_h + rule_wd;
\r
467 prune_movements(save_loc);
\r
471 void pdf_vlist_out (void)
\r
475 scaled save_h, save_v;
\r
477 // glue_ord g_order;
\r
483 pointer leader_box;
\r
486 boolean outer_doing_leaders;
\r
494 this_box = temp_ptr;
\r
495 g_order = glue_order(this_box);
\r
496 g_sign = glue_sign(this_box);
\r
497 p = list_ptr(this_box);
\r
500 if (cur_s > max_push)
\r
503 save_loc = dvi_offset + dvi_ptr;
\r
505 cur_v = cur_v - height(this_box);
\r
510 if (is_char_node(p))
\r
512 confusion("vlistout");
\r
521 if (list_ptr(p) == 0)
\r
522 cur_v = cur_v + height(p) + depth(p);
\r
525 cur_v = cur_v + height(p);
\r
529 cur_h = left_edge + shift_amount(p);
\r
532 if (type(p) == vlist_node)
\r
539 cur_v = save_v + depth(p);
\r
546 rule_ht = height(p);
\r
547 rule_dp = depth(p);
\r
548 rule_wd = width(p);
\r
560 rule_ht = width(g) - cur_g;
\r
562 if (g_sign != normal)
\r
564 if (g_sign == stretching)
\r
566 if (stretch_order(g) == g_order)
\r
568 cur_glue = cur_glue + stretch(g);
\r
569 vet_glue(glue_set(this_box) * cur_glue);
\r
570 cur_g = round(glue_temp);
\r
573 else if (shrink_order(g) == g_order) /* BUG FIX !!! */
\r
575 cur_glue = cur_glue - shrink(g);
\r
576 vet_glue(glue_set(this_box) * cur_glue);
\r
577 cur_g = round(glue_temp);
\r
581 rule_ht = rule_ht + cur_g;
\r
583 if (subtype(p) >= a_leaders)
\r
585 leader_box = leader_ptr(p);
\r
587 if (type(leader_box) == rule_node)
\r
589 rule_wd = width(leader_box);
\r
594 leader_ht = height(leader_box) + depth(leader_box);
\r
596 if ((leader_ht > 0) && (rule_ht > 0))
\r
598 rule_ht = rule_ht + 10;
\r
599 edge = cur_v + rule_ht;
\r
602 if (subtype(p) == a_leaders)
\r
605 cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
\r
607 if (cur_v < save_v)
\r
608 cur_v = cur_v + leader_ht;
\r
612 lq = rule_ht / leader_ht;
\r
613 lr = rule_ht % leader_ht;
\r
615 if (subtype(p) == c_leaders)
\r
616 cur_v = cur_v + (lr / 2);
\r
619 lx = (2 * lr + lq + 1) / (2 * lq + 2);
\r
620 cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
\r
624 while (cur_v + leader_ht <= edge)
\r
626 cur_h = left_edge + shift_amount(leader_box);
\r
629 cur_v = cur_v + height(leader_box);
\r
632 temp_ptr = leader_box;
\r
633 outer_doing_leaders = doing_leaders;
\r
634 doing_leaders = true;
\r
636 if (type(leader_box) == vlist_node)
\r
641 doing_leaders = outer_doing_leaders;
\r
645 cur_v = save_v - height(leader_box) + leader_ht + lx;
\r
658 cur_v = cur_v + width(p);
\r
668 if (is_running(rule_wd))
\r
669 rule_wd = width(this_box);
\r
671 rule_ht = rule_ht + rule_dp;
\r
672 cur_v = cur_v + rule_ht;
\r
674 if ((rule_ht > 0) && (rule_wd > 0))
\r
678 pdf_dev_set_rule(dvi_h, -dvi_v, rule_wd, rule_ht);
\r
684 cur_v = cur_v + rule_ht;
\r
691 prune_movements(save_loc);
\r