OSDN Git Service

test on linux.
[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 #define EXTERN extern
19
20 #include "texd.h"
21
22 bool pdf_doing_string;
23 bool pdf_doing_text;
24 static integer ten_pow[10] =
25 {
26   1,
27   10,
28   100,
29   1000,
30   10000,
31   100000,
32   1000000,
33   10000000,
34   100000000,
35   1000000000
36 };
37 integer scaled_out;
38 HPDF_Doc  yandy_pdf;
39 HPDF_Page yandy_page;
40 HPDF_Font yandy_font[1024];
41 tree *avl_tree = NULL;
42
43 struct tfm_map
44 {
45   char * tfm_name;
46   unsigned int key;
47 };
48
49 int tfm_cmp(void * a, void * b)
50 {
51   char * aa = ((struct tfm_map *) (a))->tfm_name;
52   char * bb = ((struct tfm_map *) (b))->tfm_name;
53
54   return (strcmp(aa, bb)) ;
55 }
56
57 void tfm_print(void *d)
58 {
59   struct tfm_map * dd = (struct tfm_map *) d;
60
61   if (dd)
62     printf("{ %s => %d }\n", dd->tfm_name, dd->key);
63 }
64
65 void tfm_delete(void *d)
66 {
67   struct tfm_map *dd = (struct tfm_map *) d;
68
69   if (dd)
70   {
71     free(dd);
72   }
73 }
74
75 void tfm_copy(void *src, void *dst)
76 {
77   struct tfm_map *s = (struct tfm_map *) src;
78   struct tfm_map *d = (struct tfm_map *) dst;
79   d->tfm_name = s->tfm_name;
80   d->key = s->key;
81 }
82
83 void init_tfm_map(void)
84 {
85   avl_tree = init_dictionnary(tfm_cmp, tfm_print, tfm_delete, tfm_copy);
86 }
87
88 void free_tfm_map(void)
89 {
90   delete_tree(avl_tree);
91 }
92
93 int insert_font_index(char * name)
94 {
95   struct tfm_map nn;
96   nn.tfm_name = name;
97   nn.key = avl_tree->count + 1;
98
99   return insert_elmt(avl_tree, &nn, sizeof(struct tfm_map));
100 }
101
102 int get_font_index(char * name)
103 {
104   struct tfm_map nn;
105
106   nn.tfm_name = name;
107   nn.key = -1;
108
109   if (is_present(avl_tree, &nn))
110   {
111     if (get_data(avl_tree, &nn, sizeof(struct tfm_map)))
112       return nn.key;
113     else
114       return 0;
115   }
116
117   return 0;
118 }
119 // report error.
120 void pdf_error(const char * t, const char * p)
121 {
122   normalize_selector();
123   print_err("Y&Y TeX error");
124
125   if (t != NULL)
126   {
127     print('(');
128     print_string(t);
129     print(')');
130   }
131
132   print_string(": ");
133   print_string(p);
134   succumb();
135 }
136 // char to string.
137 char * pdf_char_to_string(unsigned char i)
138 {
139   char * str = (char *) malloc(2);
140   str[0] = i;
141   str[1] = 0;
142   return str;
143 }
144 // output one char: normal.
145 void pdf_out(unsigned char i)
146 {
147   HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
148   HPDF_Stream_WriteChar(attr->stream, i);
149 }
150 // octal number: 032, 009 etc.
151 void pdf_print_octal(integer s)
152 {
153   char buf[HPDF_INT_LEN + 1];
154   HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
155   sprintf(buf, "%03o", s);
156   HPDF_Stream_Write(attr->stream, (HPDF_BYTE *)buf, strlen(buf));
157 }
158 // output one char: normal or octal.
159 void pdf_print_char(unsigned char s)
160 {
161   // 32 = '', 92 = '\', 40 = '(', 41 = ')'
162   if ((s <= 32) || (s == 92) || (s == 40) || (s == 41) || (s > 127))
163   {
164     pdf_out(92);
165     pdf_print_octal(s);
166   }
167   else
168   {
169     pdf_out(s);
170   }
171 }
172 // equivlent: pdf_print in pdfTeX.
173 void pdf_print_string(char * s)
174 {
175   HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
176   HPDF_Stream_WriteStr(attr->stream, s);
177 }
178 // print one integer value: signed or unsigned.
179 void pdf_print_int(int s)
180 {
181   char buf[HPDF_INT_LEN + 1];
182   HPDF_PageAttr attr = (HPDF_PageAttr) yandy_page->attr;
183   char* p = HPDF_IToA(buf, s, buf + HPDF_INT_LEN);
184   HPDF_Stream_Write(attr->stream, (HPDF_BYTE *)buf, (HPDF_UINT)(p - buf));
185 }
186 // translate sp to bp.
187 HPDF_REAL pdf_sp_to_bp(scaled s)
188 {
189   // 1 bp = 65781.76 sp
190   return (HPDF_REAL) s / 65781.76;
191 }
192 // divides scaled s by scaled m.
193 scaled divide_scaled(scaled s, scaled m, integer dd)
194 {
195   scaled q, r;
196   integer sign, i;
197
198   sign = 1;
199
200   if (s < 0)
201   {
202     sign = -sign;
203     s = -s;
204   }
205
206   if (m < 0)
207   {
208     sign = -sign;
209     m = -m;
210   }
211
212   if (m == 0)
213     pdf_error("arithmetic", "divided by zero");
214   else if (m >= 0x7FFFFFFF / 10)
215     pdf_error("arithmetic", "number too big");
216
217   q = s / m;
218   r = s % m;
219
220   for (i = 1; i <= dd; i++)
221   {
222     q = 10 * q + (10 * r) / m;
223     r = (10 * r) % m;
224   }
225
226   if (2 * r >= m)
227   {
228     incr(q);
229     r = r - m;
230   }
231
232   scaled_out = sign * (s - (r / ten_pow[dd]));
233   return sign * q;
234 }
235 scaled round_xn_over_d(scaled x, integer n, integer d)
236 {
237   bool positive;
238   nonnegative_integer t, u, v;
239
240   if (x >= 0)
241     positive = true; 
242   else
243   {
244     x = - (integer) x;
245     positive = false;
246   }
247
248   t = (x % 32767L) * n;
249   u = (x / 32768L) * n + (t / 32768L);
250   v = (u % d) * 32768L + (t % 32768L); 
251
252   if (u / d >= 32768L)
253     arith_error = true; 
254   else
255     u = 32768L * (u / d) + (v / d);
256
257   v = v % d;
258
259   if (2 * v >= d)
260     incr(u);
261
262   if (positive)
263     return u;
264   else
265     return -u;
266 }
267 // advance char width
268 void adv_char_width(internal_font_number f, eight_bits c)
269 {
270   scaled w, s_out;
271   integer s;
272
273   w = char_width(f, char_info(f, c));
274   divide_scaled(w, font_size[f], 4);
275   pdf_delta_h = pdf_delta_h + scaled_out;
276 }
277 // print real value
278 void pdf_print(integer m, integer d)
279 {
280   if (m < 0)
281   {
282     pdf_out('-');
283     m = -m;
284   }
285
286   pdf_print_int(m / ten_pow[d]);
287   m = m % ten_pow[d];
288
289   if (m > 0)
290   {
291     pdf_out('.');
292     decr(d);
293
294     while (m < ten_pow[d])
295     {
296       pdf_out('0');
297       decr(d);
298     }
299
300     while (m % 10 == 0)
301       m = m / 10;
302
303     pdf_print_int(m);
304   }
305 }
306 // end the current string
307 void pdf_end_string(void)
308 {
309   if (pdf_doing_string)
310   {
311     pdf_print_string(")] TJ\012");
312     pdf_doing_string = false;
313   }
314 }
315 // begin to draw a string
316 void pdf_begin_string(internal_font_number f)
317 {
318   scaled s_out, v, v_out;
319   integer s;
320
321   if (!pdf_doing_text)
322 //    pdf_begin_text();
323
324   if (f != dvi_f)
325   {
326     pdf_end_string();
327     pdf_font_def(f);
328   }
329
330   s = divide_scaled(cur_h - pdf_delta_h, font_size[f], 3);
331   s_out = scaled_out;
332
333   if (abs(s) < 0100000)
334   {
335     s_out = divide_scaled(round_xn_over_d(cur_h - pdf_delta_h, 1000, 1000),
336       font_size[f], 3);
337
338     if (s < 0)
339       s_out = -s_out;
340   }
341
342 //  if (cur_v - pdf_v >= )
343 }
344 // end a text section.
345 void pdf_end_text()
346 {
347   if (pdf_doing_text)
348   {
349     pdf_end_string();
350     HPDF_Page_EndText(yandy_page);
351     pdf_doing_text = false;
352   }
353 }
354 // draw a rule.
355 void pdf_set_rule(scaled x, scaled y, scaled w, scaled h)
356 {
357 }
358 void pdf_error_handler (HPDF_STATUS error_no, HPDF_STATUS detail_no, void * user_data)
359 {
360   printf ("Y&Y TeX error: error_no=%04X, detail_no=%u\n",
361     (HPDF_UINT)error_no,
362     (HPDF_UINT)detail_no);
363   longjmp(jumpbuffer, 1);
364 }
365
366 void pdf_font_def(internal_font_number f)
367 {
368   int k;
369   const char * fnt_name;
370   char * afm_name;
371   char * pfb_name;
372   char buffer[256];
373   
374   memcpy(buffer, (const char *) str_pool + str_start[font_name[f]], length(font_name[f]));
375   buffer[length(font_name[f])] = '\0';
376
377   k = get_font_index(buffer);
378   printf("DEF: %s--%d.\n", buffer, k);
379
380   if (k == 0)
381   {
382     afm_name = kpse_find_file(strcat(strdup(buffer), ".afm"), kpse_afm_format, 1);
383     printf("path: %s.\n", afm_name);
384     pfb_name = kpse_find_file(strcat(strdup(buffer), ".pfb"), kpse_type1_format, 1);
385
386     if (afm_name != NULL && pfb_name != NULL)
387     {
388       k = insert_font_index(buffer);
389       fnt_name = HPDF_LoadType1FontFromFile (yandy_pdf, afm_name, pfb_name);
390       yandy_font[k] = HPDF_GetFont(yandy_pdf, fnt_name, NULL);
391     }
392   }
393
394   HPDF_Page_SetFontAndSize(yandy_page, yandy_font[k], (font_size[f] / 65535));
395 }
396
397 void pdf_ship_out(halfword p)
398 {
399   char j, k;
400
401   if (tracing_output > 0)
402   {
403     print_nl("");
404     print_ln();
405     print_string("Completed box being shipped out");
406   }
407
408   if (term_offset > max_print_line - 9)
409     print_ln();
410   else if ((term_offset > 0) || (file_offset > 0))
411     print_char(' ');
412
413   print_char('[');
414   j = 9;
415
416   while((count(j) == 0) && (j > 0))
417     decr(j);
418
419   for (k = 0; k <= j; k++)
420   {
421     print_int(count(k));
422
423     if (k < j)
424       print_char('.');
425   }
426
427 #ifndef _WINDOWS
428   fflush(stdout);
429 #endif
430
431   if (tracing_output > 0)
432   {
433     print_char(']');
434     begin_diagnostic();
435     show_box(p);
436     end_diagnostic(true);
437   }
438
439   if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
440       (height(p) + depth(p) + v_offset > max_dimen) ||
441       (width(p) + h_offset > max_dimen))
442   {
443     print_err("Huge page cannot be shipped out");
444     help2("The page just created is more than 18 feet tall or",
445         "more than 18 feet wide, so I suspect something went wrong.");
446     error();
447
448     if (tracing_output <= 0)
449     {
450       begin_diagnostic();
451       print_nl("The following box has been deleted:");
452       show_box(p);
453       end_diagnostic(true);
454     }
455
456     goto lab30;
457   }
458
459   if (height(p) + depth(p) + v_offset > max_v)
460     max_v = height(p) + depth(p) + v_offset;
461
462   if (width(p) + h_offset > max_h)
463     max_h = width(p) + h_offset;
464
465   dvi_h = 0;
466   dvi_v = 0;
467   cur_h = h_offset;
468   dvi_f = null_font;
469
470   if (output_file_name == 0)
471   {
472     if (job_name == 0)
473       open_log_file();
474
475     pack_job_name(".pdf");
476
477     while(!b_open_out(pdf_file))
478     {
479       prompt_file_name("file name for output", ".pdf");
480     }
481
482     output_file_name = b_make_name_string(pdf_file);
483   }
484
485   if (total_pages == 0)
486   {
487     init_tfm_map();
488     yandy_pdf = HPDF_New (pdf_error_handler, NULL);
489     HPDF_SetCompressionMode (yandy_pdf, HPDF_COMP_ALL);
490     yandy_pdf -> pdf_version = HPDF_VER_17;
491     HPDF_SetInfoAttr(yandy_pdf, HPDF_INFO_PRODUCER, "Y&Y TeX");
492     yandy_font[0] = HPDF_GetFont (yandy_pdf, "Times-Roman", NULL);
493   }
494
495   yandy_page = HPDF_AddPage (yandy_pdf);
496   HPDF_Page_SetSize (yandy_page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
497
498   cur_v = height(p) + v_offset;
499   temp_ptr = p;
500
501   if (type(p) == vlist_node)
502     pdf_vlist_out();
503   else
504     pdf_hlist_out();
505
506   incr(total_pages);
507   cur_s = -1;
508 lab30:;
509   if (tracing_output <= 0)
510     print_char(']');
511
512   dead_cycles = 0;
513
514 #ifndef _WINDOWS
515   fflush(stdout);
516 #endif
517
518   flush_node_list(p);
519 }
520
521
522 void pdf_hlist_out (void)
523 {
524   scaled base_line;
525   scaled left_edge;
526   scaled save_h, save_v;
527   halfword this_box;
528 /*  glue_ord g_order;  */
529   int g_order;           /* 95/Jan/7 */
530 /*  char g_sign;  */
531   int g_sign;            /* 95/Jan/7 */
532   halfword p;
533   //integer save_loc;
534   halfword leader_box;
535   scaled leader_wd;
536   scaled lx;
537   bool outer_doing_leaders;
538   scaled edge;
539   real glue_temp;
540   real cur_glue;
541   scaled cur_g;
542
543   cur_g = 0;
544   cur_glue = 0.0;
545   this_box = temp_ptr;
546   g_order = glue_order(this_box);
547   g_sign = glue_sign(this_box);
548   p = list_ptr(this_box);
549   incr(cur_s);
550
551   base_line = cur_v;
552   left_edge = cur_h;
553
554   while (p != 0)
555 lab21:
556     if (is_char_node(p))
557     {
558       do
559         {
560           f = font(p);
561           c = character(p);
562
563           if (f != dvi_f)
564           {
565             pdf_font_def(f);
566
567             if (!font_used[f])
568             {
569               font_used[f] = true;
570             }
571
572             dvi_f = f;
573           }
574           
575           HPDF_Page_SetFontAndSize (yandy_page, yandy_font[dvi_f], 10);
576           HPDF_Page_BeginText(yandy_page);
577           HPDF_Page_MoveTextPos(yandy_page, pdf_sp_to_bp(cur_h) + 72, (841.89 - (pdf_sp_to_bp(cur_v) + 72)));
578           HPDF_Page_ShowText(yandy_page, pdf_char_to_string(c));
579           HPDF_Page_EndText(yandy_page);
580           cur_h = cur_h + char_width(f, char_info(f, c));
581           p = link(p);
582         }
583       while(((p >= hi_mem_min)));
584
585       dvi_h = cur_h;
586   }
587   else
588   {
589     switch (type(p))
590     {
591       case hlist_node:
592       case vlist_node:
593         if (list_ptr(p) == 0)
594           cur_h = cur_h + width(p);
595         else
596         {
597           save_h = dvi_h;
598           save_v = dvi_v;
599           cur_v = base_line + shift_amount(p);
600           temp_ptr = p;
601           edge = cur_h;
602
603           if (type(p) == vlist_node)
604             pdf_vlist_out();
605           else
606             pdf_hlist_out();
607
608           dvi_h = save_h;
609           dvi_v = save_v;
610           cur_h = edge + width(p);
611           cur_v = base_line;
612         }
613         break;
614
615       case rule_node:
616         {
617           rule_ht = height(p);
618           rule_dp = depth(p);
619           rule_wd = width(p);
620           goto lab14;
621         }
622         break;
623
624       case whatsit_node:
625         //out_what(p);
626         break;
627
628       case glue_node:
629         {
630           g = glue_ptr(p);
631           rule_wd = width(g) - cur_g;
632
633           if (g_sign != normal)
634           {
635             if (g_sign == stretching)
636             {
637               if (stretch_order(g) == g_order)
638               {
639                 cur_glue = cur_glue + stretch(g);
640                 glue_temp = glue_set(this_box) * cur_glue;
641
642                 if (glue_temp > 1000000000.0)
643                   glue_temp = 1000000000.0;
644                 else if (glue_temp < -1000000000.0)
645                   glue_temp = -1000000000.0;
646
647                 cur_g = round(glue_temp);
648               }
649             }
650             else if (shrink_order(g) == g_order)
651             {
652               cur_glue = cur_glue - shrink(g);
653               glue_temp = glue_set(this_box) * cur_glue;
654
655               if (glue_temp > 1000000000.0)
656                 glue_temp = 1000000000.0;
657               else if (glue_temp < -1000000000.0)
658                 glue_temp = -1000000000.0;
659
660               cur_g = round(glue_temp);
661             }
662           }
663
664           rule_wd = rule_wd + cur_g;
665
666           if (subtype(p) >= a_leaders)
667           {
668             leader_box = leader_ptr(p);
669
670             if (type(leader_box) == rule_node)
671             {
672               rule_ht = height(leader_box);
673               rule_dp = depth(leader_box);
674               goto lab14;
675             }
676
677             leader_wd = width(leader_box);
678
679             if ((leader_wd > 0) && (rule_wd > 0))
680             {
681               rule_wd = rule_wd + 10;
682               edge = cur_h + rule_wd;
683               lx = 0;
684
685               if (subtype(p) == a_leaders)
686               {
687                 save_h = cur_h;
688                 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
689
690                 if (cur_h < save_h)
691                   cur_h = cur_h + leader_wd;
692               }
693               else
694               {
695                 lq = rule_wd / leader_wd;
696                 lr = rule_wd % leader_wd;
697
698                 if (subtype(p) == c_leaders)
699                   cur_h = cur_h + (lr / 2);
700                 else
701                 {
702                   lx =(2 * lr + lq + 1) / (2 * lq + 2);
703                   cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
704                 }
705               }
706
707               while (cur_h + leader_wd <= edge)
708               {
709                 cur_v = base_line + shift_amount(leader_box);
710                 //synch_v();
711                 dvi_v = cur_v;
712                 save_v = dvi_v;
713                 //synch_h();
714                 dvi_h = cur_h;
715                 save_h = dvi_h;
716                 temp_ptr = leader_box;
717                 outer_doing_leaders = doing_leaders;
718                 doing_leaders = true;
719
720                 if (type(leader_box) == vlist_node)
721                   pdf_vlist_out();
722                 else
723                   pdf_hlist_out();
724
725                 doing_leaders = outer_doing_leaders;
726                 dvi_v = save_v;
727                 dvi_h = save_h;
728                 cur_v = base_line;
729                 cur_h = save_h + leader_wd + lx;
730               }
731
732               cur_h = edge - 10;
733               goto lab15;
734             }
735           }
736
737           goto lab13;
738         }
739         break;
740
741       case kern_node:
742       case math_node:
743         cur_h = cur_h + width(p);
744         break;
745
746       case ligature_node:
747         {
748           mem[lig_trick] = mem[lig_char(p)];
749           link(lig_trick) = link(p);
750           p = lig_trick;
751           goto lab21;
752         }
753         break;
754
755       default:
756         break;
757     }
758
759     goto lab15;
760 lab14:
761     if ((rule_ht == -1073741824L))  /* - 2^30 */
762       rule_ht = height(this_box);
763
764     if ((rule_dp == -1073741824L))     /* - 2^30 */
765       rule_dp = depth(this_box);
766
767     rule_ht = rule_ht + rule_dp;
768
769     if ((rule_ht > 0) && (rule_wd > 0))
770     {
771       cur_v = base_line + rule_dp;
772       HPDF_Page_SetLineWidth(yandy_page, rule_ht / 65535);
773       HPDF_Page_MoveTo (yandy_page, (cur_h / 65535 + 72), (841.89 - cur_v / 65535 - 72));
774       HPDF_Page_LineTo (yandy_page, (cur_h / 65535 + 72 + rule_wd / 65535), (841.89 - cur_v / 65535 - 72));
775       HPDF_Page_Stroke (yandy_page);
776       cur_v = base_line;
777       dvi_h = dvi_h + rule_wd;
778     }
779 lab13:
780     cur_h = cur_h + rule_wd;
781 lab15:
782     p = link(p);
783   }
784
785   decr(cur_s);
786 }
787 /* following needs access to dvi_buf=zdvibuf see coerce.h */
788 /* sec 0629 */
789 void pdf_vlist_out (void)
790 {
791   scaled left_edge;
792   scaled top_edge;
793   scaled save_h, save_v;
794   halfword this_box;
795 /*  glue_ord g_order;  */
796   int g_order;         /* 95/Jan/7 */
797 /*  char g_sign;  */
798   int g_sign;          /* 95/Jan/7 */
799   halfword p;
800   //integer save_loc;
801   halfword leader_box;
802   scaled leader_ht;
803   scaled lx;
804   bool outer_doing_leaders;
805   scaled edge;
806   real glue_temp;
807   real cur_glue;
808   scaled cur_g;
809
810   cur_g = 0;
811   cur_glue = 0.0;
812   this_box = temp_ptr;
813   g_order = glue_order(this_box);
814   g_sign = glue_sign(this_box);
815   p = list_ptr(this_box);
816   incr(cur_s);
817
818   left_edge = cur_h;
819   cur_v = cur_v - height(this_box);
820   top_edge = cur_v;
821
822   while (p != 0)
823   {
824     if ((p >= hi_mem_min))
825     {
826       confusion("vlistout");
827       return;       // abort_flag set
828     }
829     else
830     {
831       switch (type(p))
832       {
833         case hlist_node:
834         case vlist_node:
835           if (list_ptr(p) == 0)
836             cur_v = cur_v + height(p) + depth(p);
837           else
838           {
839             cur_v = cur_v + height(p);
840             //synch_v();
841             dvi_v = cur_v;
842             save_h = dvi_h;
843             save_v = dvi_v;
844             cur_h = left_edge + shift_amount(p);
845             temp_ptr = p;
846
847             if (type(p) == vlist_node)
848               pdf_vlist_out();
849             else
850               pdf_hlist_out();
851
852             dvi_h = save_h;
853             dvi_v = save_v;
854             cur_v = save_v + depth(p);
855             cur_h = left_edge;
856           }
857           break;
858
859         case rule_node:
860           {
861             rule_ht = height(p);
862             rule_dp = depth(p);
863             rule_wd = width(p);
864             goto lab14;
865           }
866           break;
867
868         case whatsit_node:
869           //out_what(p);
870           break;
871
872         case glue_node:
873           {
874             g = glue_ptr(p);
875             rule_ht = width(g) - cur_g;
876
877             if (g_sign != normal)
878             {
879               if (g_sign == stretching)
880               {
881                 if (stretch_order(g) == g_order)
882                 {
883                   cur_glue = cur_glue + stretch(g);
884                   glue_temp = glue_set(this_box) * cur_glue;
885
886                   if (glue_temp > 1000000000.0)
887                     glue_temp = 1000000000.0;
888                   else if (glue_temp < -1000000000.0)
889                     glue_temp = -1000000000.0;
890
891                   cur_g = round(glue_temp);
892                 }
893               }
894               else if (shrink_order(g) == g_order)   /* BUG FIX !!! */
895               {
896                 cur_glue = cur_glue - shrink(g);
897                 glue_temp = glue_set(this_box) * cur_glue;
898
899                 if (glue_temp > 1000000000.0)
900                   glue_temp = 1000000000.0;
901                 else if (glue_temp < -1000000000.0)
902                   glue_temp = -1000000000.0;
903
904                 cur_g = round(glue_temp);
905               }
906             }
907
908             rule_ht = rule_ht + cur_g;
909
910             if (subtype(p) >= a_leaders)
911             {
912               leader_box = leader_ptr(p);
913
914               if (type(leader_box) == rule_node)
915               {
916                 rule_wd = width(leader_box);
917                 rule_dp = 0;
918                 goto lab14;
919               }
920
921               leader_ht = height(leader_box) + depth(leader_box);
922
923               if ((leader_ht > 0) && (rule_ht > 0))
924               {
925                 rule_ht = rule_ht + 10;
926                 edge = cur_v + rule_ht;
927                 lx = 0;
928
929                 if (subtype(p) == a_leaders)
930                 {
931                   save_v = cur_v;
932                   cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
933
934                   if (cur_v < save_v)
935                     cur_v = cur_v + leader_ht;
936                 }
937                 else
938                 {
939                   lq = rule_ht / leader_ht;
940                   lr = rule_ht % leader_ht;
941
942                   if (subtype(p) == c_leaders)
943                     cur_v = cur_v + (lr / 2);
944                   else
945                   {
946                     lx = (2 * lr + lq + 1) / (2 * lq + 2);
947                     cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
948                   }
949                 }
950
951                 while (cur_v + leader_ht <= edge)
952                 {
953                   cur_h = left_edge + shift_amount(leader_box);
954                   //synch_h();
955                   dvi_h = cur_h;
956                   save_h = dvi_h;
957                   cur_v = cur_v + height(leader_box);
958                   //synch_v();
959                   dvi_v = cur_v;
960                   save_v = dvi_v;
961                   temp_ptr = leader_box;
962                   outer_doing_leaders = doing_leaders;
963                   doing_leaders = true;
964
965                   if (type(leader_box) == vlist_node)
966                     pdf_vlist_out();
967                   else
968                     pdf_hlist_out();
969
970                   doing_leaders = outer_doing_leaders;
971                   dvi_v = save_v;
972                   dvi_h = save_h;
973                   cur_h = left_edge;
974                   cur_v = save_v - height(leader_box) + leader_ht + lx;
975                 }
976
977                 cur_v = edge - 10;
978                 goto lab15;
979               }
980             }
981
982             goto lab13;
983           }
984           break;
985
986         case kern_node:
987           cur_v = cur_v + width(p);
988           break;
989
990         default:
991           break;
992       }
993       goto lab15;
994 lab14:
995       if ((rule_wd == -1073741824L))    /* -2^30 */
996         rule_wd = width(this_box);
997
998       rule_ht = rule_ht + rule_dp;
999       cur_v = cur_v + rule_ht;
1000
1001       if ((rule_ht > 0) && (rule_wd > 0))
1002       {
1003         HPDF_Page_SetLineWidth(yandy_page, rule_ht / 65535);
1004         HPDF_Page_MoveTo(yandy_page, (cur_h / 65535 + 72), (841.89 - cur_v / 65535 - 72));
1005         HPDF_Page_LineTo(yandy_page, (cur_h / 65535 + 72 + rule_wd / 65535), (841.89 - cur_v / 65535 - 72));
1006         HPDF_Page_Stroke(yandy_page);
1007       }
1008
1009       goto lab15;
1010 lab13:
1011       cur_v = cur_v + rule_ht;
1012     }
1013 lab15:
1014     p = link(p);
1015   }
1016
1017   decr(cur_s);
1018 }