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 #define EXTERN extern
\r
21 #include "yandytex.h"
\r
23 void ensure_pdf_open(void)
\r
25 if (output_file_name == 0)
\r
30 pack_job_name(".pdf");
\r
32 while (!b_open_out(pdf_file))
\r
33 prompt_file_name("file name for output", ".pdf");
\r
35 output_file_name = b_make_name_string(pdf_file);
\r
39 void pdf_ship_out (pointer p)
\r
44 if (tracing_output > 0)
\r
48 prints("Completed box being shipped out");
\r
51 if (term_offset > max_print_line - 9)
\r
53 else if ((term_offset > 0) || (file_offset > 0))
\r
59 while ((count(j) == 0) && (j > 0))
\r
62 for (k = 0; k <= j; k++)
\r
64 print_int(count(k));
\r
72 if (tracing_output > 0)
\r
77 end_diagnostic(true);
\r
80 if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
\r
81 (height(p) + depth(p) + v_offset > max_dimen) ||
\r
82 (width(p) + h_offset > max_dimen))
\r
84 print_err("Huge page cannot be shipped out");
\r
85 help2("The page just created is more than 18 feet tall or",
\r
86 "more than 18 feet wide, so I suspect something went wrong.");
\r
89 if (tracing_output <= 0)
\r
92 print_nl("The following box has been deleted:");
\r
94 end_diagnostic(true);
\r
100 if (height(p) + depth(p) + v_offset > max_v)
\r
101 max_v = height(p) + depth(p) + v_offset;
\r
103 if (width(p) + h_offset > max_h)
\r
104 max_h = width(p) + h_offset;
\r
112 if (total_pages == 0)
\r
114 pdf_set_version(5);
\r
115 pdf_set_compression(9);
\r
116 pdf_init_fontmaps();
\r
117 read_config_file("dvipdfmx.cfg");
\r
118 pdf_doc_set_producer("Y&YTeX 2.3.0");
\r
119 pdf_doc_set_creator("TeX");
\r
121 pdf_init_device(0.000015202, 2, 0);
\r
122 // TODO: pdfTeX's page width and height.
\r
123 // page_width = pdf_page_width != 0 ? <- : width(p) + 2 * (pdf_h_origin + h_offset);
\r
124 // page_height = pdf_page_height != 0 ? <- : height(p) + depth(p) + 2 * (pdf_v_origin + v_offset);
\r
125 pdf_open_document(pdf_file_name, 0, 595.0, 842.0, 0, 0, (1 << 4));
\r
126 spc_exec_at_begin_document();
\r
129 page_loc = dvi_offset + dvi_ptr;
\r
130 pdf_doc_begin_page(1.0, 72.0, 770.0);
\r
131 spc_exec_at_begin_page();
\r
133 last_bop = page_loc;
\r
134 cur_v = height(p) + v_offset;
\r
137 if (type(p) == vlist_node)
\r
142 spc_exec_at_end_page();
\r
143 pdf_doc_end_page();
\r
148 if (tracing_output <= 0)
\r
155 if (tracing_stats > 1)
\r
157 print_nl("Memory usage before: ");
\r
158 print_int(var_used);
\r
160 print_int(dyn_used);
\r
165 flush_node_list(p);
\r
168 if (tracing_stats > 1)
\r
170 prints(" after: ");
\r
171 print_int(var_used);
\r
173 print_int(dyn_used);
\r
174 prints("; still utouched: ");
\r
175 print_int(hi_mem_min - lo_mem_max - 1);
\r
181 void pdf_synch_h (void)
\r
183 if (cur_h != dvi_h)
\r
187 void pdf_synch_v (void)
\r
189 if (cur_v != dvi_v)
\r
193 int pdf_get_font_id (internal_font_number f)
\r
195 char * sbuf = malloc(length(font_name[f]) + 1);
\r
197 memset(sbuf, 0, length(font_name[f]) + 1);
\r
198 memcpy(sbuf, str_pool + str_start[font_name[f]], length(font_name[f]));
\r
199 id = dvi_locate_font(sbuf, font_size[f]);
\r
205 void pdf_out_char (internal_font_number f, ASCII_code c)
\r
211 pdf_dev_set_string(cur_h, -cur_v, cbuf, 1, char_width(f, char_info(f, c)), font_id[f], 1);
\r
212 pdf_dev_set_rect(&rect, cur_h, -cur_v, char_width(f, char_info(f, c)),
\r
213 char_height(f, height_depth(char_info(f, c))),
\r
214 char_depth(f, height_depth(char_info(f, c))));
\r
215 pdf_doc_expand_box(&rect);
\r
218 void pdf_hlist_out (void)
\r
222 scaled save_h, save_v;
\r
224 // glue_ord g_order;
\r
230 pointer leader_box;
\r
233 boolean outer_doing_leaders;
\r
241 this_box = temp_ptr;
\r
242 g_order = glue_order(this_box);
\r
243 g_sign = glue_sign(this_box);
\r
244 p = list_ptr(this_box);
\r
247 if (cur_s > max_push)
\r
250 save_loc = dvi_offset + dvi_ptr;
\r
256 if (is_char_node(p))
\r
270 font_used[f] = true;
\r
271 font_id[f] = pdf_get_font_id(f);
\r
277 pdf_out_char(dvi_f, c);
\r
278 cur_h = cur_h + char_width(f, char_info(f, c));
\r
280 } while (!(!is_char_node(p)));
\r
290 if (list_ptr(p) == 0)
\r
291 cur_h = cur_h + width(p);
\r
296 cur_v = base_line + shift_amount(p);
\r
300 if (type(p) == vlist_node)
\r
307 cur_h = edge + width(p);
\r
314 rule_ht = height(p);
\r
315 rule_dp = depth(p);
\r
316 rule_wd = width(p);
\r
328 rule_wd = width(g) - cur_g;
\r
330 if (g_sign != normal)
\r
332 if (g_sign == stretching)
\r
334 if (stretch_order(g) == g_order)
\r
336 cur_glue = cur_glue + stretch(g);
\r
337 vet_glue(glue_set(this_box) * cur_glue);
\r
338 cur_g = round(glue_temp);
\r
341 else if (shrink_order(g) == g_order)
\r
343 cur_glue = cur_glue - shrink(g);
\r
344 vet_glue(glue_set(this_box) * cur_glue);
\r
345 cur_g = round(glue_temp);
\r
349 rule_wd = rule_wd + cur_g;
\r
351 if (subtype(p) >= a_leaders)
\r
353 leader_box = leader_ptr(p);
\r
355 if (type(leader_box) == rule_node)
\r
357 rule_ht = height(leader_box);
\r
358 rule_dp = depth(leader_box);
\r
362 leader_wd = width(leader_box);
\r
364 if ((leader_wd > 0) && (rule_wd > 0))
\r
366 rule_wd = rule_wd + 10;
\r
367 edge = cur_h + rule_wd;
\r
370 if (subtype(p) == a_leaders)
\r
373 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
\r
375 if (cur_h < save_h)
\r
376 cur_h = cur_h + leader_wd;
\r
380 lq = rule_wd / leader_wd;
\r
381 lr = rule_wd % leader_wd;
\r
383 if (subtype(p) == c_leaders)
\r
384 cur_h = cur_h + (lr / 2);
\r
387 lx = (2 * lr + lq + 1) / (2 * lq + 2);
\r
388 cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
\r
392 while (cur_h + leader_wd <= edge)
\r
394 cur_v = base_line + shift_amount(leader_box);
\r
399 temp_ptr = leader_box;
\r
400 outer_doing_leaders = doing_leaders;
\r
401 doing_leaders = true;
\r
403 if (type(leader_box) == vlist_node)
\r
408 doing_leaders = outer_doing_leaders;
\r
412 cur_h = save_h + leader_wd + lx;
\r
426 cur_h = cur_h + width(p);
\r
429 case ligature_node:
\r
431 mem[lig_trick] = mem[lig_char(p)];
\r
432 link(lig_trick) = link(p);
\r
445 if (is_running(rule_ht))
\r
446 rule_ht = height(this_box);
\r
448 if (is_running(rule_dp))
\r
449 rule_dp = depth(this_box);
\r
451 rule_ht = rule_ht + rule_dp;
\r
453 if ((rule_ht > 0) && (rule_wd > 0))
\r
456 cur_v = base_line + rule_dp;
\r
458 pdf_dev_set_rule(dvi_h, -dvi_v, rule_wd, rule_ht);
\r
460 dvi_h = dvi_h + rule_wd;
\r
464 cur_h = cur_h + rule_wd;
\r
470 prune_movements(save_loc);
\r
474 void pdf_vlist_out (void)
\r
478 scaled save_h, save_v;
\r
480 // glue_ord g_order;
\r
486 pointer leader_box;
\r
489 boolean outer_doing_leaders;
\r
497 this_box = temp_ptr;
\r
498 g_order = glue_order(this_box);
\r
499 g_sign = glue_sign(this_box);
\r
500 p = list_ptr(this_box);
\r
503 if (cur_s > max_push)
\r
506 save_loc = dvi_offset + dvi_ptr;
\r
508 cur_v = cur_v - height(this_box);
\r
513 if (is_char_node(p))
\r
515 confusion("vlistout");
\r
524 if (list_ptr(p) == 0)
\r
525 cur_v = cur_v + height(p) + depth(p);
\r
528 cur_v = cur_v + height(p);
\r
532 cur_h = left_edge + shift_amount(p);
\r
535 if (type(p) == vlist_node)
\r
542 cur_v = save_v + depth(p);
\r
549 rule_ht = height(p);
\r
550 rule_dp = depth(p);
\r
551 rule_wd = width(p);
\r
563 rule_ht = width(g) - cur_g;
\r
565 if (g_sign != normal)
\r
567 if (g_sign == stretching)
\r
569 if (stretch_order(g) == g_order)
\r
571 cur_glue = cur_glue + stretch(g);
\r
572 vet_glue(glue_set(this_box) * cur_glue);
\r
573 cur_g = round(glue_temp);
\r
576 else if (shrink_order(g) == g_order) /* BUG FIX !!! */
\r
578 cur_glue = cur_glue - shrink(g);
\r
579 vet_glue(glue_set(this_box) * cur_glue);
\r
580 cur_g = round(glue_temp);
\r
584 rule_ht = rule_ht + cur_g;
\r
586 if (subtype(p) >= a_leaders)
\r
588 leader_box = leader_ptr(p);
\r
590 if (type(leader_box) == rule_node)
\r
592 rule_wd = width(leader_box);
\r
597 leader_ht = height(leader_box) + depth(leader_box);
\r
599 if ((leader_ht > 0) && (rule_ht > 0))
\r
601 rule_ht = rule_ht + 10;
\r
602 edge = cur_v + rule_ht;
\r
605 if (subtype(p) == a_leaders)
\r
608 cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
\r
610 if (cur_v < save_v)
\r
611 cur_v = cur_v + leader_ht;
\r
615 lq = rule_ht / leader_ht;
\r
616 lr = rule_ht % leader_ht;
\r
618 if (subtype(p) == c_leaders)
\r
619 cur_v = cur_v + (lr / 2);
\r
622 lx = (2 * lr + lq + 1) / (2 * lq + 2);
\r
623 cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
\r
627 while (cur_v + leader_ht <= edge)
\r
629 cur_h = left_edge + shift_amount(leader_box);
\r
632 cur_v = cur_v + height(leader_box);
\r
635 temp_ptr = leader_box;
\r
636 outer_doing_leaders = doing_leaders;
\r
637 doing_leaders = true;
\r
639 if (type(leader_box) == vlist_node)
\r
644 doing_leaders = outer_doing_leaders;
\r
648 cur_v = save_v - height(leader_box) + leader_ht + lx;
\r
661 cur_v = cur_v + width(p);
\r
671 if (is_running(rule_wd))
\r
672 rule_wd = width(this_box);
\r
674 rule_ht = rule_ht + rule_dp;
\r
675 cur_v = cur_v + rule_ht;
\r
677 if ((rule_ht > 0) && (rule_wd > 0))
\r
681 pdf_dev_set_rule(dvi_h, -dvi_v, rule_wd, rule_ht);
\r
687 cur_v = cur_v + rule_ht;
\r
694 prune_movements(save_loc);
\r