OSDN Git Service

redesigning header.
[putex/putex.git] / src / texsourc / yandy_pdf_backend.c
1 /* Copyright 2014 Clerk Ma
2
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.
7
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.
12
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
16    02110-1301 USA.  */
17
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
22
23 #define EXTERN extern
24
25 #include "texd.h"
26
27 bool pdf_doing_string;
28 bool pdf_doing_text;
29 HPDF_Doc  yandy_pdf;
30 HPDF_Page yandy_page;
31 HPDF_Font yandy_font[1024];
32 tree *avl_tree = NULL;
33
34 struct tfm_map
35 {
36   char * tfm_name;
37   unsigned int key;
38 };
39
40 int tfm_cmp(void * a, void * b)
41 {
42   struct tfm_map * aa = (struct tfm_map *) a;
43   struct tfm_map * bb = (struct tfm_map *) b;
44
45   if (!aa || !bb)
46     return 0;
47
48   return strcmp(aa->tfm_name, bb->tfm_name);
49 }
50
51 void tfm_print(void *d)
52 {
53   struct tfm_map * dd = (struct tfm_map *) d;
54
55   if (dd)
56     printf("{ %s => %d }\n", dd->tfm_name, dd->key);
57 }
58
59 void tfm_delete(void *d)
60 {
61   struct tfm_map *dd = (struct tfm_map *) d;
62
63   if (dd)
64   {
65     free(dd);
66   }
67 }
68
69 void tfm_copy(void *src, void *dst)
70 {
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;
74   d->key = s->key;
75 }
76
77 void init_tfm_map(void)
78 {
79   avl_tree = init_dictionnary(tfm_cmp, tfm_print, tfm_delete, tfm_copy);
80 }
81
82 void free_tfm_map(void)
83 {
84   delete_tree(avl_tree);
85 }
86
87 int insert_font_index(char * name)
88 {
89   struct tfm_map nn;
90   nn.tfm_name = name;
91   nn.key = avl_tree->count + 1;
92   return insert_elmt(avl_tree, &nn, sizeof(struct tfm_map));
93 }
94
95 int get_font_index(char * name)
96 {
97   struct tfm_map nn;
98   nn.tfm_name = name;
99   nn.key      = 0;
100   if (is_present(avl_tree, &nn))
101   {
102     if (get_data(avl_tree, &nn, sizeof(struct tfm_map)))
103       return nn.key;
104     else
105       return 0;
106   }
107   else
108   {
109     return nn.key;
110   }
111 }
112
113 char * pdf_char_to_string(unsigned char i)
114 {
115   char * str = (char *) malloc(2);
116   str[0] = i;
117   str[1] = 0;
118   return str;
119 }
120
121 void pdf_out(unsigned char i)
122 {
123   char temp[2] = {i, '\0'};
124   HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
125   HPDF_Stream_WriteStr(attr->stream, temp);
126 }
127
128 void pdf_print_octal(integer n)
129 {
130   unsigned int k = 0;
131
132   do
133     {
134       dig[k] = n % 8;
135       n = n / 8;
136       incr(k);
137     }
138   while (n != 0);
139
140   if (k == 1)
141   {
142     pdf_out('0');
143     pdf_out('0');
144   }
145
146   if (k == 2)
147   {
148     pdf_out('0');
149   }
150
151   while (k > 0)
152   {
153     decr(k);
154     pdf_out('0' + dig[k]);
155   }
156 }
157
158 void pdf_print_char(unsigned char c)
159 {
160   if ((c < 32) || (c == 92) || (c == 40) || (c == 41) || (c > 127))
161   {
162     pdf_out(92);
163     pdf_print_octal(c);
164   }
165   else
166   {
167     pdf_out(c);
168   }
169 }
170
171 void pdf_print_string(char * s)
172 {
173   HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
174   HPDF_Stream_WriteStr(attr->stream, s);
175 }
176
177 void hpdf_print_char(unsigned char c)
178 {
179   if ((c < 32) || (c == 92) || (c == 40) || (c == 41) || (c > 127))
180   {
181     pdf_print_string(" [(!\\051)] TJ\012");
182   }
183   else
184   {
185     HPDF_Page_ShowText(yandy_page, pdf_char_to_string(c));
186   }
187 }
188
189 void pdf_end_string(void)
190 {
191   if (pdf_doing_string)
192   {
193     pdf_print_string(")] TJ\012");
194     pdf_doing_string = false;
195   }
196 }
197
198 void pdf_begin_string(internal_font_number f)
199 {
200   scaled s, v;
201
202   if (!pdf_doing_text)
203     pdf_begin_text();
204
205   if (f != dvi_f)
206   {
207     pdf_end_string();
208     pdf_font_def(f);
209   }
210
211   {
212     s = cur_h - pdf_delta_h;
213     v = pdf_v - cur_v;
214   }
215
216   if ((f != pdf_f) || (v != 0) || (s >= 0100000))
217   {
218     pdf_end_string();
219     //pdf_set_textmatrix();
220     pdf_f = f;
221     s = 0;
222   }
223
224   if (!pdf_doing_string)
225   {
226     pdf_print_string(" [");
227     if (s == 0)
228       pdf_out('(');
229   }
230
231   if (s != 0)
232   {
233     if (pdf_doing_string)
234       pdf_out(')');
235     //pdf_print_int(-s);
236     pdf_out('(');
237     pdf_delta_h = cur_h;
238   }
239
240   pdf_doing_string = true;
241 }
242 void pdf_begin_text(void)
243 {
244   HPDF_Page_BeginText(yandy_page);
245   pdf_doing_text = true;
246   pdf_f = null_font;
247   pdf_doing_string = false;
248 }
249
250 void pdf_end_text(void)
251 {
252   if (pdf_doing_text)
253   {
254     HPDF_Page_EndText(yandy_page);
255     pdf_doing_text = false;
256   }
257 }
258
259 void pdf_error_handler (HPDF_STATUS error_no, HPDF_STATUS detail_no, void * user_data)
260 {
261   printf ("YANDYTEX ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
262   longjmp(jumpbuffer, 1);
263 }
264
265 void pdf_font_def(internal_font_number f)
266 {
267   int k;
268   const char * fnt_name;
269   char * afm_name;
270   char * pfb_name;
271   char buffer[256], cuffer[256], duffer[256];
272   
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]));
279
280   //if ((k = get_font_index(buffer)) != 0)
281   //{
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));
284   //}
285   //else
286   k = get_font_index(buffer);
287
288   if (k == 0)
289   {
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);
295
296     if (afm_name != NULL && pfb_name != NULL)
297     {
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);
303     }
304     else
305     {
306       k = 0; //get_font_index(buffer);
307     }
308   }
309   HPDF_Page_SetFontAndSize(yandy_page, yandy_font[k], (font_size[f] / 65535));
310 }
311
312 void pdf_ship_out(halfword p)
313 {
314   integer page_loc;
315   char j, k;
316   pool_pointer s;
317   char old_setting;
318
319   if (tracing_output > 0)
320   {
321     print_nl("");
322     print_ln();
323     print_string("Completed box being shipped out");
324   }
325
326   if (term_offset > max_print_line - 9)
327     print_ln();
328   else if ((term_offset > 0) || (file_offset > 0))
329     print_char(' ');
330
331   print_char('[');
332   j = 9;
333
334   while((count(j) == 0) && (j > 0))
335     decr(j);
336
337   for (k = 0; k <= j; k++)
338   {
339     print_int(count(k));
340
341     if (k < j)
342       print_char('.');
343   }
344
345 #ifndef _WINDOWS
346   fflush(stdout);
347 #endif
348
349   if (tracing_output > 0)
350   {
351     print_char(']');
352     begin_diagnostic();
353     show_box(p);
354     end_diagnostic(true);
355   }
356
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))
360   {
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.");
364     error();
365
366     if (tracing_output <= 0)
367     {
368       begin_diagnostic();
369       print_nl("The following box has been deleted:");
370       show_box(p);
371       end_diagnostic(true);
372     }
373
374     goto lab30;
375   }
376
377   if (height(p) + depth(p) + v_offset > max_v)
378     max_v = height(p) + depth(p) + v_offset;
379
380   if (width(p) + h_offset > max_h)
381     max_h = width(p) + h_offset;
382
383   dvi_h = 0;
384   pdf_delta_h = 0;
385   dvi_v = 0;
386   pdf_delta_v = 0;
387   cur_h = h_offset;
388   dvi_f = null_font;
389
390   if (output_file_name == 0)
391   {
392     if (job_name == 0)
393       open_log_file();
394
395     pack_job_name(".pdf");
396
397     while(!b_open_out(pdf_file))
398     {
399       prompt_file_name("file name for output", ".pdf");
400     }
401
402     output_file_name = b_make_name_string(pdf_file);
403   }
404
405   if (total_pages == 0)
406   {
407     init_tfm_map();
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);
413   }
414
415   //page_loc = dvi_offset + dvi_ptr;
416   //dvi_out(bop);
417   yandy_page = HPDF_AddPage (yandy_pdf);
418   HPDF_Page_SetSize(yandy_page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
419
420   //for (k = 0; k <= 9; k++)
421   //  dvi_four(count(k));
422   //
423   //dvi_four(last_bop);
424   //last_bop = page_loc;
425   cur_v = height(p) + v_offset;
426   temp_ptr = p;
427
428   if (type(p) == vlist_node)
429     pdf_vlist_out();
430   else
431     pdf_hlist_out();
432
433   //dvi_out(eop);
434   incr(total_pages);
435   cur_s = -1;
436 lab30:;
437   if (tracing_output <= 0)
438     print_char(']');
439
440   dead_cycles = 0;
441
442 #ifndef _WINDOWS
443   fflush(stdout);
444 #endif
445
446   flush_node_list(p);
447 }
448 /*
449 void pdf_ship_out(pointer p)
450 {
451   integer i, j, k;
452
453   if (tracing_output > 0)
454   {
455     print_nl("");
456     print_ln();
457     print_string("Completed box being shipped out");
458   }
459
460   if (term_offset > max_print_line - 9)
461     print_ln();
462   else if ((term_offset > 0) || (file_offset > 0))
463     print_char(' ');
464
465   print_char('[');
466   j = 9;
467
468   while((count(j) == 0) && (j > 0))
469     decr(j);
470
471   for (k = 0; k <= j; k++)
472   {
473     print_int(count(k));
474
475     if (k < j)
476       print_char('.');
477   }
478
479 #ifndef _WINDOWS
480   fflush(stdout);
481 #endif
482
483   if (tracing_output > 0)
484   {
485     print_char(']');
486     begin_diagnostic();
487     show_box(p);
488     end_diagnostic(true);
489   }
490
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))
494   {
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.");
498     error();
499
500     if (tracing_output <= 0)
501     {
502       begin_diagnostic();
503       print_nl("The following box has been deleted:");
504       show_box(p);
505       end_diagnostic(true);
506     }
507
508     goto lab30;
509   }
510
511   if (height(p) + depth(p) + v_offset > max_v)
512     max_v = height(p) + depth(p) + v_offset;
513
514   if (width(p) + h_offset > max_h)
515     max_h = width(p) + h_offset;
516
517   pdf_h = 0;
518   pdf_v = 0;
519   cur_h = h_offset;
520   pdf_f = null_font;
521
522  if (output_file_name == 0)
523   {
524     if (job_name == 0)
525       open_log_file();
526
527     pack_job_name(".pdf");
528
529     while(!b_open_out(dvi_file))
530     {
531       prompt_file_name("file name for output", ".pdf");
532     }
533
534     output_file_name = b_make_name_string(dvi_file);
535   }
536
537   if (total_pages == 0)
538   {
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);
542   }
543
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);
547
548   cur_v = height(p) + v_offset;
549   temp_ptr = p;
550
551   incr(total_pages);
552   cur_s = -1;
553 lab30:;
554   if (tracing_output <= 0)
555     print_char(']');
556
557   dead_cycles = 0;
558
559 #ifndef _WINDOWS
560   fflush(stdout);
561 #endif
562
563   flush_node_list(p);
564 }
565 */
566 void pdf_hlist_out (void)
567 {
568   scaled base_line;
569   scaled left_edge;
570   scaled save_h, save_v;
571   halfword this_box;
572 /*  glue_ord g_order;  */
573   int g_order;           /* 95/Jan/7 */
574 /*  char g_sign;  */
575   int g_sign;            /* 95/Jan/7 */
576   halfword p;
577   integer save_loc;
578   halfword leader_box;
579   scaled leader_wd;
580   scaled lx;
581   bool outer_doing_leaders;
582   scaled edge;
583   real glue_temp;
584   real cur_glue;
585   scaled cur_g;
586
587   cur_g = 0;
588   cur_glue = 0.0;
589   this_box = temp_ptr;
590   g_order = glue_order(this_box);
591   g_sign = glue_sign(this_box);
592   p = list_ptr(this_box);
593   incr(cur_s);
594
595   //if (cur_s > 0)
596   //  dvi_out(141);
597
598   //if (cur_s > max_push)
599   //  max_push = cur_s;
600
601   //save_loc = dvi_offset + dvi_ptr;
602   base_line = cur_v;
603   left_edge = cur_h;
604
605   while (p != 0)
606 lab21:
607     if (is_char_node(p))
608     {
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(" [(");
613       do
614         {
615           f = font(p);
616           c = character(p);
617
618           if (f != dvi_f)
619           {
620             if (!font_used[f])
621             {
622               //dvi_font_def(f);
623               pdf_font_def(f);
624               //if (dvi_f != null_font)
625               //  pdf_print_string(")] TJ\012");
626               //pdf_print_string(" [(");
627               font_used[f] = true;
628             }
629
630             dvi_f = f;
631           }
632
633           //pdf_print_char(c);
634           if (!pdf_doing_text)
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));
638           hpdf_print_char(c);
639           HPDF_Page_EndText(yandy_page);
640           //pdf_begin_string(f);
641           //pdf_print_char(c);
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));
645           p = link(p);
646         }
647       while(((p >= hi_mem_min)));
648       //pdf_print_string(")] TJ\012");
649       //HPDF_Page_EndText(yandy_page);
650       dvi_h = cur_h;
651   }
652   else
653   {
654     switch (type(p))
655     {
656       case hlist_node:
657       case vlist_node:
658         if (list_ptr(p) == 0)
659           cur_h = cur_h + width(p);
660         else
661         {
662           save_h = dvi_h;
663           save_v = dvi_v;
664           cur_v = base_line + shift_amount(p);
665           temp_ptr = p;
666           edge = cur_h;
667
668           if (type(p) == vlist_node)
669             pdf_vlist_out();
670           else
671             pdf_hlist_out();
672
673           dvi_h = save_h;
674           dvi_v = save_v;
675           cur_h = edge + width(p);
676           cur_v = base_line;
677         }
678         break;
679
680       case rule_node:
681         {
682           rule_ht = height(p);
683           rule_dp = depth(p);
684           rule_wd = width(p);
685           goto lab14;
686         }
687         break;
688
689       case whatsit_node:
690         //out_what(p);
691         break;
692
693       case glue_node:
694         {
695           g = glue_ptr(p);
696           rule_wd = width(g) - cur_g;
697
698           if (g_sign != normal)
699           {
700             if (g_sign == stretching)
701             {
702               if (stretch_order(g) == g_order)
703               {
704                 cur_glue = cur_glue + stretch(g);
705                 glue_temp = glue_set(this_box) * cur_glue;
706
707                 if (glue_temp > 1000000000.0)
708                   glue_temp = 1000000000.0;
709                 else if (glue_temp < -1000000000.0)
710                   glue_temp = -1000000000.0;
711
712                 cur_g = round(glue_temp);
713               }
714             }
715             else if (shrink_order(g) == g_order)
716             {
717               cur_glue = cur_glue - shrink(g);
718               glue_temp = glue_set(this_box) * cur_glue;
719
720               if (glue_temp > 1000000000.0)
721                 glue_temp = 1000000000.0;
722               else if (glue_temp < -1000000000.0)
723                 glue_temp = -1000000000.0;
724
725               cur_g = round(glue_temp);
726             }
727           }
728
729           rule_wd = rule_wd + cur_g;
730
731           if (subtype(p) >= a_leaders)
732           {
733             leader_box = leader_ptr(p);
734
735             if (type(leader_box) == rule_node)
736             {
737               rule_ht = height(leader_box);
738               rule_dp = depth(leader_box);
739               goto lab14;
740             }
741
742             leader_wd = width(leader_box);
743
744             if ((leader_wd > 0) && (rule_wd > 0))
745             {
746               rule_wd = rule_wd + 10;
747               edge = cur_h + rule_wd;
748               lx = 0;
749
750               if (subtype(p) == a_leaders)
751               {
752                 save_h = cur_h;
753                 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
754
755                 if (cur_h < save_h)
756                   cur_h = cur_h + leader_wd;
757               }
758               else
759               {
760                 lq = rule_wd / leader_wd;
761                 lr = rule_wd % leader_wd;
762
763                 if (subtype(p) == c_leaders)
764                   cur_h = cur_h + (lr / 2);
765                 else
766                 {
767                   lx =(2 * lr + lq + 1) / (2 * lq + 2);
768                   cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
769                 }
770               }
771
772               while (cur_h + leader_wd <= edge)
773               {
774                 cur_v = base_line + shift_amount(leader_box);
775                 synch_v();
776                 save_v = dvi_v;
777                 synch_h();
778                 save_h = dvi_h;
779                 temp_ptr = leader_box;
780                 outer_doing_leaders = doing_leaders;
781                 doing_leaders = true;
782
783                 if (type(leader_box) == vlist_node)
784                   pdf_vlist_out();
785                 else
786                   pdf_hlist_out();
787
788                 doing_leaders = outer_doing_leaders;
789                 dvi_v = save_v;
790                 dvi_h = save_h;
791                 cur_v = base_line;
792                 cur_h = save_h + leader_wd + lx;
793               }
794
795               cur_h = edge - 10;
796               goto lab15;
797             }
798           }
799
800           goto lab13;
801         }
802         break;
803
804       case kern_node:
805       case math_node:
806         cur_h = cur_h + width(p);
807         break;
808
809       case ligature_node:
810         {
811           mem[lig_trick] = mem[lig_char(p)];
812           link(lig_trick) = link(p);
813           p = lig_trick;
814           goto lab21;
815         }
816         break;
817
818       default:
819         break;
820     }
821
822     goto lab15;
823 lab14:
824     if ((rule_ht == -1073741824L))  /* - 2^30 */
825       rule_ht = height(this_box);
826
827     if ((rule_dp == -1073741824L))     /* - 2^30 */
828       rule_dp = depth(this_box);
829
830     rule_ht = rule_ht + rule_dp;
831
832     if ((rule_ht > 0) && (rule_wd > 0))
833     {
834       //synch_h();
835       cur_v = base_line + rule_dp;
836       //synch_v();
837       //dvi_out(set_rule);
838       //dvi_four(rule_ht);
839       //dvi_four(rule_wd);
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);
844       cur_v = base_line;
845       dvi_h = dvi_h + rule_wd;
846     }
847 lab13:
848     cur_h = cur_h + rule_wd;
849 lab15:
850     p = link(p);
851   }
852
853   //prune_movements(save_loc);
854
855   //if (cur_s > 0)
856   //  dvi_pop(save_loc);
857
858   decr(cur_s);
859 }
860 /* following needs access to dvi_buf=zdvibuf see coerce.h */
861 /* sec 0629 */
862 void pdf_vlist_out (void)
863 {
864   scaled left_edge;
865   scaled top_edge;
866   scaled save_h, save_v;
867   halfword this_box;
868 /*  glue_ord g_order;  */
869   int g_order;         /* 95/Jan/7 */
870 /*  char g_sign;  */
871   int g_sign;          /* 95/Jan/7 */
872   halfword p;
873   integer save_loc;
874   halfword leader_box;
875   scaled leader_ht;
876   scaled lx;
877   bool outer_doing_leaders;
878   scaled edge;
879   real glue_temp;
880   real cur_glue;
881   scaled cur_g;
882
883   cur_g = 0;
884   cur_glue = 0.0;
885   this_box = temp_ptr;
886   g_order = glue_order(this_box);
887   g_sign = glue_sign(this_box);
888   p = list_ptr(this_box);
889   incr(cur_s);
890
891   //if (cur_s > 0)
892   //  dvi_out(141);
893
894   //if (cur_s > max_push)
895   //  max_push = cur_s;
896
897   //save_loc = dvi_offset + dvi_ptr;
898   left_edge = cur_h;
899   cur_v = cur_v - height(this_box);
900   top_edge = cur_v;
901
902   while (p != 0)
903   {
904     if ((p >= hi_mem_min))
905     {
906       confusion("vlistout");
907       return;       // abort_flag set
908     }
909     else
910     {
911       switch (type(p))
912       {
913         case hlist_node:
914         case vlist_node:
915           if (list_ptr(p) == 0)
916             cur_v = cur_v + height(p) + depth(p);
917           else
918           {
919             cur_v = cur_v + height(p);
920             synch_v();
921             save_h = dvi_h;
922             save_v = dvi_v;
923             cur_h = left_edge + shift_amount(p);
924             temp_ptr = p;
925
926             if (type(p) == vlist_node)
927               pdf_vlist_out();
928             else
929               pdf_hlist_out();
930
931             dvi_h = save_h;
932             dvi_v = save_v;
933             cur_v = save_v + depth(p);
934             cur_h = left_edge;
935           }
936           break;
937
938         case rule_node:
939           {
940             rule_ht = height(p);
941             rule_dp = depth(p);
942             rule_wd = width(p);
943             goto lab14;
944           }
945           break;
946
947         case whatsit_node:
948           //out_what(p);
949           break;
950
951         case glue_node:
952           {
953             g = glue_ptr(p);
954             rule_ht = width(g) - cur_g;
955
956             if (g_sign != normal)
957             {
958               if (g_sign == stretching)
959               {
960                 if (stretch_order(g) == g_order)
961                 {
962                   cur_glue = cur_glue + stretch(g);
963                   glue_temp = glue_set(this_box) * cur_glue;
964
965                   if (glue_temp > 1000000000.0)
966                     glue_temp = 1000000000.0;
967                   else if (glue_temp < -1000000000.0)
968                     glue_temp = -1000000000.0;
969
970                   cur_g = round(glue_temp);
971                 }
972               }
973               else if (shrink_order(g) == g_order)   /* BUG FIX !!! */
974               {
975                 cur_glue = cur_glue - shrink(g);
976                 glue_temp = glue_set(this_box) * cur_glue;
977
978                 if (glue_temp > 1000000000.0)
979                   glue_temp = 1000000000.0;
980                 else if (glue_temp < -1000000000.0)
981                   glue_temp = -1000000000.0;
982
983                 cur_g = round(glue_temp);
984               }
985             }
986
987             rule_ht = rule_ht + cur_g;
988
989             if (subtype(p) >= a_leaders)
990             {
991               leader_box = leader_ptr(p);
992
993               if (type(leader_box) == rule_node)
994               {
995                 rule_wd = width(leader_box);
996                 rule_dp = 0;
997                 goto lab14;
998               }
999
1000               leader_ht = height(leader_box) + depth(leader_box);
1001
1002               if ((leader_ht > 0) && (rule_ht > 0))
1003               {
1004                 rule_ht = rule_ht + 10;
1005                 edge = cur_v + rule_ht;
1006                 lx = 0;
1007
1008                 if (subtype(p) == a_leaders)
1009                 {
1010                   save_v = cur_v;
1011                   cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
1012
1013                   if (cur_v < save_v)
1014                     cur_v = cur_v + leader_ht;
1015                 }
1016                 else
1017                 {
1018                   lq = rule_ht / leader_ht;
1019                   lr = rule_ht % leader_ht;
1020
1021                   if (subtype(p) == c_leaders)
1022                     cur_v = cur_v + (lr / 2);
1023                   else
1024                   {
1025                     lx = (2 * lr + lq + 1) / (2 * lq + 2);
1026                     cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
1027                   }
1028                 }
1029
1030                 while (cur_v + leader_ht <= edge)
1031                 {
1032                   cur_h = left_edge + shift_amount(leader_box);
1033                   synch_h();
1034                   save_h = dvi_h;
1035                   cur_v = cur_v + height(leader_box);
1036                   synch_v();
1037                   save_v = dvi_v;
1038                   temp_ptr = leader_box;
1039                   outer_doing_leaders = doing_leaders;
1040                   doing_leaders = true;
1041
1042                   if (type(leader_box) == vlist_node)
1043                     pdf_vlist_out();
1044                   else
1045                     pdf_hlist_out();
1046
1047                   doing_leaders = outer_doing_leaders;
1048                   dvi_v = save_v;
1049                   dvi_h = save_h;
1050                   cur_h = left_edge;
1051                   cur_v = save_v - height(leader_box) + leader_ht + lx;
1052                 }
1053
1054                 cur_v = edge - 10;
1055                 goto lab15;
1056               }
1057             }
1058
1059             goto lab13;
1060           }
1061           break;
1062
1063         case kern_node:
1064           cur_v = cur_v + width(p);
1065           break;
1066
1067         default:
1068           break;
1069       }
1070       goto lab15;
1071 lab14:
1072       if ((rule_wd == -1073741824L))    /* -2^30 */
1073         rule_wd = width(this_box);
1074
1075       rule_ht = rule_ht + rule_dp;
1076       cur_v = cur_v + rule_ht;
1077
1078       if ((rule_ht > 0) && (rule_wd > 0))
1079       {
1080         //synch_h();
1081         //synch_v();
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);
1089       }
1090
1091       goto lab15;
1092 lab13:
1093       cur_v = cur_v + rule_ht;
1094     }
1095 lab15:
1096     p = link(p);
1097   }
1098
1099   //prune_movements(save_loc);
1100
1101   //if (cur_s > 0)
1102   //  dvi_pop(save_loc);
1103
1104   decr(cur_s);
1105 }