1 /* Copyright 2014 Clerk Ma
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 #pragma warning(disable:4996)
19 #pragma warning(disable:4131) // old style declarator
20 #pragma warning(disable:4135) // conversion between different integral types
21 #pragma warning(disable:4127) // conditional expression is constant
27 bool pdf_doing_string;
31 HPDF_Font yandy_font[1024];
32 tree *avl_tree = NULL;
40 int tfm_cmp(void * a, void * b)
42 struct tfm_map * aa = (struct tfm_map *) a;
43 struct tfm_map * bb = (struct tfm_map *) b;
48 return strcmp(aa->tfm_name, bb->tfm_name);
51 void tfm_print(void *d)
53 struct tfm_map * dd = (struct tfm_map *) d;
56 printf("{ %s => %d }\n", dd->tfm_name, dd->key);
59 void tfm_delete(void *d)
61 struct tfm_map *dd = (struct tfm_map *) d;
69 void tfm_copy(void *src, void *dst)
71 struct tfm_map *s = (struct tfm_map *) src;
72 struct tfm_map *d = (struct tfm_map *) dst;
73 d->tfm_name = s->tfm_name;
77 void init_tfm_map(void)
79 avl_tree = init_dictionnary(tfm_cmp, tfm_print, tfm_delete, tfm_copy);
82 void free_tfm_map(void)
84 delete_tree(avl_tree);
87 int insert_font_index(char * name)
91 nn.key = avl_tree->count + 1;
92 return insert_elmt(avl_tree, &nn, sizeof(struct tfm_map));
95 int get_font_index(char * name)
100 if (is_present(avl_tree, &nn))
102 if (get_data(avl_tree, &nn, sizeof(struct tfm_map)))
113 char * pdf_char_to_string(unsigned char i)
115 char * str = (char *) malloc(2);
121 void pdf_out(unsigned char i)
123 char temp[2] = {i, '\0'};
124 HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
125 HPDF_Stream_WriteStr(attr->stream, temp);
128 void pdf_print_octal(integer n)
154 pdf_out('0' + dig[k]);
158 void pdf_print_char(unsigned char c)
160 if ((c < 32) || (c == 92) || (c == 40) || (c == 41) || (c > 127))
171 void pdf_print_string(char * s)
173 HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
174 HPDF_Stream_WriteStr(attr->stream, s);
177 void hpdf_print_char(unsigned char c)
179 if ((c < 32) || (c == 92) || (c == 40) || (c == 41) || (c > 127))
181 pdf_print_string(" [(!\\051)] TJ\012");
185 HPDF_Page_ShowText(yandy_page, pdf_char_to_string(c));
189 void pdf_end_string(void)
191 if (pdf_doing_string)
193 pdf_print_string(")] TJ\012");
194 pdf_doing_string = false;
198 void pdf_begin_string(internal_font_number f)
212 s = cur_h - pdf_delta_h;
216 if ((f != pdf_f) || (v != 0) || (s >= 0100000))
219 //pdf_set_textmatrix();
224 if (!pdf_doing_string)
226 pdf_print_string(" [");
233 if (pdf_doing_string)
240 pdf_doing_string = true;
242 void pdf_begin_text(void)
244 HPDF_Page_BeginText(yandy_page);
245 pdf_doing_text = true;
247 pdf_doing_string = false;
250 void pdf_end_text(void)
254 HPDF_Page_EndText(yandy_page);
255 pdf_doing_text = false;
259 void pdf_error_handler (HPDF_STATUS error_no, HPDF_STATUS detail_no, void * user_data)
261 printf ("YANDYTEX ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
262 longjmp(jumpbuffer, 1);
265 void pdf_font_def(internal_font_number f)
268 const char * fnt_name;
271 char buffer[256], cuffer[256], duffer[256];
273 memset(buffer, 0, sizeof(buffer));
274 memset(duffer, 0, sizeof(duffer));
275 memset(cuffer, 0, sizeof(cuffer));
276 memcpy(buffer, (const char *) str_pool + str_start[font_name[f]], length(font_name[f]));
277 memcpy(duffer, (const char *) str_pool + str_start[font_name[f]], length(font_name[f]));
278 memcpy(cuffer, (const char *) str_pool + str_start[font_name[f]], length(font_name[f]));
280 //if ((k = get_font_index(buffer)) != 0)
282 // printf("PDF_FONT_DEF2: %s-%d.\n", buffer,get_font_index(buffer));
283 // HPDF_Page_SetFontAndSize(yandy_page, yandy_font[get_font_index(buffer)], (font_size[f] / 65535));
286 k = get_font_index(buffer);
290 afm_name = kpse_find_file(strcat(buffer, ".afm"), kpse_afm_format, 0);
291 printf("PDF_FONT_DEF3: %s.\n", afm_name);
292 //printf("PDF_FONT_DEF3: %s.\n", pfb_name);
293 pfb_name = kpse_find_file(strcat(duffer, ".pfb"), kpse_type1_format, 0);
294 printf("PDF_FONT_DEF3: %s.\n", pfb_name);
296 if (afm_name != NULL && pfb_name != NULL)
298 printf("PDF_FONT_DEF4_NAME: %s.\n", cuffer);
299 k = insert_font_index(cuffer);
300 printf("PDF_FONT_DEF4: %d.\n", k);
301 fnt_name = HPDF_LoadType1FontFromFile (yandy_pdf, afm_name, pfb_name);
302 yandy_font[k] = HPDF_GetFont(yandy_pdf, fnt_name, NULL);
306 k = 0; //get_font_index(buffer);
309 HPDF_Page_SetFontAndSize(yandy_page, yandy_font[k], (font_size[f] / 65535));
312 void pdf_ship_out(halfword p)
319 if (tracing_output > 0)
323 print_string("Completed box being shipped out");
326 if (term_offset > max_print_line - 9)
328 else if ((term_offset > 0) || (file_offset > 0))
334 while((count(j) == 0) && (j > 0))
337 for (k = 0; k <= j; k++)
349 if (tracing_output > 0)
354 end_diagnostic(true);
357 if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
358 (height(p) + depth(p) + v_offset > max_dimen) ||
359 (width(p) + h_offset > max_dimen))
361 print_err("Huge page cannot be shipped out");
362 help2("The page just created is more than 18 feet tall or",
363 "more than 18 feet wide, so I suspect something went wrong.");
366 if (tracing_output <= 0)
369 print_nl("The following box has been deleted:");
371 end_diagnostic(true);
377 if (height(p) + depth(p) + v_offset > max_v)
378 max_v = height(p) + depth(p) + v_offset;
380 if (width(p) + h_offset > max_h)
381 max_h = width(p) + h_offset;
390 if (output_file_name == 0)
395 pack_job_name(".pdf");
397 while(!b_open_out(pdf_file))
399 prompt_file_name("file name for output", ".pdf");
402 output_file_name = b_make_name_string(pdf_file);
405 if (total_pages == 0)
408 yandy_pdf = HPDF_New(pdf_error_handler, NULL);
409 yandy_pdf->pdf_version = HPDF_VER_17;
410 //HPDF_SetCompressionMode(yandy_pdf, HPDF_COMP_ALL);
411 HPDF_SetInfoAttr(yandy_pdf, HPDF_INFO_PRODUCER, "Y&YTeX 2.2.3");
412 yandy_font[0] = HPDF_GetFont(yandy_pdf, "Times-Roman", NULL);
415 //page_loc = dvi_offset + dvi_ptr;
417 yandy_page = HPDF_AddPage (yandy_pdf);
418 HPDF_Page_SetSize(yandy_page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
420 //for (k = 0; k <= 9; k++)
421 // dvi_four(count(k));
423 //dvi_four(last_bop);
424 //last_bop = page_loc;
425 cur_v = height(p) + v_offset;
428 if (type(p) == vlist_node)
437 if (tracing_output <= 0)
449 void pdf_ship_out(pointer p)
453 if (tracing_output > 0)
457 print_string("Completed box being shipped out");
460 if (term_offset > max_print_line - 9)
462 else if ((term_offset > 0) || (file_offset > 0))
468 while((count(j) == 0) && (j > 0))
471 for (k = 0; k <= j; k++)
483 if (tracing_output > 0)
488 end_diagnostic(true);
491 if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
492 (height(p) + depth(p) + v_offset > max_dimen) ||
493 (width(p) + h_offset > max_dimen))
495 print_err("Huge page cannot be shipped out");
496 help2("The page just created is more than 18 feet tall or",
497 "more than 18 feet wide, so I suspect something went wrong.");
500 if (tracing_output <= 0)
503 print_nl("The following box has been deleted:");
505 end_diagnostic(true);
511 if (height(p) + depth(p) + v_offset > max_v)
512 max_v = height(p) + depth(p) + v_offset;
514 if (width(p) + h_offset > max_h)
515 max_h = width(p) + h_offset;
522 if (output_file_name == 0)
527 pack_job_name(".pdf");
529 while(!b_open_out(dvi_file))
531 prompt_file_name("file name for output", ".pdf");
534 output_file_name = b_make_name_string(dvi_file);
537 if (total_pages == 0)
539 yandy_pdf = HPDF_New(pdf_error_handler, NULL);
540 yandy_pdf->pdf_version = HPDF_VER_17;
541 HPDF_SetCompressionMode(yandy_pdf, HPDF_COMP_ALL);
544 yandy_page = HPDF_AddPage (yandy_pdf);
545 HPDF_Page_SetWidth (yandy_page, (HPDF_REAL)hsize / 65536);
546 HPDF_Page_SetHeight (yandy_page, (HPDF_REAL)vsize / 65536);
548 cur_v = height(p) + v_offset;
554 if (tracing_output <= 0)
566 void pdf_hlist_out (void)
570 scaled save_h, save_v;
572 /* glue_ord g_order; */
573 int g_order; /* 95/Jan/7 */
575 int g_sign; /* 95/Jan/7 */
581 bool outer_doing_leaders;
590 g_order = glue_order(this_box);
591 g_sign = glue_sign(this_box);
592 p = list_ptr(this_box);
598 //if (cur_s > max_push)
601 //save_loc = dvi_offset + dvi_ptr;
609 //HPDF_Page_BeginText(yandy_page);
610 //HPDF_Page_SetTextMatrix(yandy_page, 1, 0, 0, 1, (cur_h/65536 + 72), (841.89 - (cur_v/65536 + 72)));
611 //HPDF_Page_MoveTextPos(yandy_page, (cur_h/65536 + 72), (841.89 - (cur_v/65536 + 72)));
612 //pdf_print_string(" [(");
624 //if (dvi_f != null_font)
625 // pdf_print_string(")] TJ\012");
626 //pdf_print_string(" [(");
635 HPDF_Page_BeginText(yandy_page);
636 HPDF_Page_MoveTextPos(yandy_page, (cur_h/65536 + 72), (841.89 - (cur_v/65536 + 72)));
637 //HPDF_Page_ShowText(yandy_page, pdf_char_to_string(c));
639 HPDF_Page_EndText(yandy_page);
640 //pdf_begin_string(f);
642 //printf("HLISTOUT: %c.\n", c);
643 cur_h = cur_h + char_width(f, char_info(f, c));
644 pdf_delta_h = pdf_delta_h + char_width(f, char_info(f, c));
647 while(((p >= hi_mem_min)));
648 //pdf_print_string(")] TJ\012");
649 //HPDF_Page_EndText(yandy_page);
658 if (list_ptr(p) == 0)
659 cur_h = cur_h + width(p);
664 cur_v = base_line + shift_amount(p);
668 if (type(p) == vlist_node)
675 cur_h = edge + width(p);
696 rule_wd = width(g) - cur_g;
698 if (g_sign != normal)
700 if (g_sign == stretching)
702 if (stretch_order(g) == g_order)
704 cur_glue = cur_glue + stretch(g);
705 glue_temp = glue_set(this_box) * cur_glue;
707 if (glue_temp > 1000000000.0)
708 glue_temp = 1000000000.0;
709 else if (glue_temp < -1000000000.0)
710 glue_temp = -1000000000.0;
712 cur_g = round(glue_temp);
715 else if (shrink_order(g) == g_order)
717 cur_glue = cur_glue - shrink(g);
718 glue_temp = glue_set(this_box) * cur_glue;
720 if (glue_temp > 1000000000.0)
721 glue_temp = 1000000000.0;
722 else if (glue_temp < -1000000000.0)
723 glue_temp = -1000000000.0;
725 cur_g = round(glue_temp);
729 rule_wd = rule_wd + cur_g;
731 if (subtype(p) >= a_leaders)
733 leader_box = leader_ptr(p);
735 if (type(leader_box) == rule_node)
737 rule_ht = height(leader_box);
738 rule_dp = depth(leader_box);
742 leader_wd = width(leader_box);
744 if ((leader_wd > 0) && (rule_wd > 0))
746 rule_wd = rule_wd + 10;
747 edge = cur_h + rule_wd;
750 if (subtype(p) == a_leaders)
753 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
756 cur_h = cur_h + leader_wd;
760 lq = rule_wd / leader_wd;
761 lr = rule_wd % leader_wd;
763 if (subtype(p) == c_leaders)
764 cur_h = cur_h + (lr / 2);
767 lx =(2 * lr + lq + 1) / (2 * lq + 2);
768 cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
772 while (cur_h + leader_wd <= edge)
774 cur_v = base_line + shift_amount(leader_box);
779 temp_ptr = leader_box;
780 outer_doing_leaders = doing_leaders;
781 doing_leaders = true;
783 if (type(leader_box) == vlist_node)
788 doing_leaders = outer_doing_leaders;
792 cur_h = save_h + leader_wd + lx;
806 cur_h = cur_h + width(p);
811 mem[lig_trick] = mem[lig_char(p)];
812 link(lig_trick) = link(p);
824 if ((rule_ht == -1073741824L)) /* - 2^30 */
825 rule_ht = height(this_box);
827 if ((rule_dp == -1073741824L)) /* - 2^30 */
828 rule_dp = depth(this_box);
830 rule_ht = rule_ht + rule_dp;
832 if ((rule_ht > 0) && (rule_wd > 0))
835 cur_v = base_line + rule_dp;
840 HPDF_Page_SetLineWidth(yandy_page, rule_ht / 65535);
841 HPDF_Page_MoveTo (yandy_page, (cur_h / 65535 + 72), (841.89 - cur_v / 65535 - 72));
842 HPDF_Page_LineTo (yandy_page, (cur_h / 65535 + 72 + rule_wd / 65535), (841.89 - cur_v / 65535 - 72));
843 HPDF_Page_Stroke (yandy_page);
845 dvi_h = dvi_h + rule_wd;
848 cur_h = cur_h + rule_wd;
853 //prune_movements(save_loc);
856 // dvi_pop(save_loc);
860 /* following needs access to dvi_buf=zdvibuf see coerce.h */
862 void pdf_vlist_out (void)
866 scaled save_h, save_v;
868 /* glue_ord g_order; */
869 int g_order; /* 95/Jan/7 */
871 int g_sign; /* 95/Jan/7 */
877 bool outer_doing_leaders;
886 g_order = glue_order(this_box);
887 g_sign = glue_sign(this_box);
888 p = list_ptr(this_box);
894 //if (cur_s > max_push)
897 //save_loc = dvi_offset + dvi_ptr;
899 cur_v = cur_v - height(this_box);
904 if ((p >= hi_mem_min))
906 confusion("vlistout");
907 return; // abort_flag set
915 if (list_ptr(p) == 0)
916 cur_v = cur_v + height(p) + depth(p);
919 cur_v = cur_v + height(p);
923 cur_h = left_edge + shift_amount(p);
926 if (type(p) == vlist_node)
933 cur_v = save_v + depth(p);
954 rule_ht = width(g) - cur_g;
956 if (g_sign != normal)
958 if (g_sign == stretching)
960 if (stretch_order(g) == g_order)
962 cur_glue = cur_glue + stretch(g);
963 glue_temp = glue_set(this_box) * cur_glue;
965 if (glue_temp > 1000000000.0)
966 glue_temp = 1000000000.0;
967 else if (glue_temp < -1000000000.0)
968 glue_temp = -1000000000.0;
970 cur_g = round(glue_temp);
973 else if (shrink_order(g) == g_order) /* BUG FIX !!! */
975 cur_glue = cur_glue - shrink(g);
976 glue_temp = glue_set(this_box) * cur_glue;
978 if (glue_temp > 1000000000.0)
979 glue_temp = 1000000000.0;
980 else if (glue_temp < -1000000000.0)
981 glue_temp = -1000000000.0;
983 cur_g = round(glue_temp);
987 rule_ht = rule_ht + cur_g;
989 if (subtype(p) >= a_leaders)
991 leader_box = leader_ptr(p);
993 if (type(leader_box) == rule_node)
995 rule_wd = width(leader_box);
1000 leader_ht = height(leader_box) + depth(leader_box);
1002 if ((leader_ht > 0) && (rule_ht > 0))
1004 rule_ht = rule_ht + 10;
1005 edge = cur_v + rule_ht;
1008 if (subtype(p) == a_leaders)
1011 cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
1014 cur_v = cur_v + leader_ht;
1018 lq = rule_ht / leader_ht;
1019 lr = rule_ht % leader_ht;
1021 if (subtype(p) == c_leaders)
1022 cur_v = cur_v + (lr / 2);
1025 lx = (2 * lr + lq + 1) / (2 * lq + 2);
1026 cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
1030 while (cur_v + leader_ht <= edge)
1032 cur_h = left_edge + shift_amount(leader_box);
1035 cur_v = cur_v + height(leader_box);
1038 temp_ptr = leader_box;
1039 outer_doing_leaders = doing_leaders;
1040 doing_leaders = true;
1042 if (type(leader_box) == vlist_node)
1047 doing_leaders = outer_doing_leaders;
1051 cur_v = save_v - height(leader_box) + leader_ht + lx;
1064 cur_v = cur_v + width(p);
1072 if ((rule_wd == -1073741824L)) /* -2^30 */
1073 rule_wd = width(this_box);
1075 rule_ht = rule_ht + rule_dp;
1076 cur_v = cur_v + rule_ht;
1078 if ((rule_ht > 0) && (rule_wd > 0))
1082 //dvi_out(put_rule);
1083 //dvi_four(rule_ht);
1084 //dvi_four(rule_wd);
1085 HPDF_Page_SetLineWidth(yandy_page, rule_ht / 65535);
1086 HPDF_Page_MoveTo (yandy_page, (cur_h / 65535 + 72), (841.89 - cur_v / 65535 - 72));
1087 HPDF_Page_LineTo (yandy_page, (cur_h / 65535 + 72 + rule_wd / 65535), (841.89 - cur_v / 65535 - 72));
1088 HPDF_Page_Stroke (yandy_page);
1093 cur_v = cur_v + rule_ht;
1099 //prune_movements(save_loc);
1102 // dvi_pop(save_loc);