OSDN Git Service

0dedc8d86baa67bfaea26f109252a4bda5991212
[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   /*
369   int k;
370   const char * fnt_name;
371   char * afm_name;
372   char * pfb_name;
373   char buffer[256];
374   
375   memcpy(buffer, (const char *) str_pool + str_start[font_name[f]], length(font_name[f]));
376   buffer[length(font_name[f])] = '\0';
377
378   k = get_font_index(buffer);
379   printf("DEF: %s--%d.\n", buffer, k);
380
381   if (k == 0)
382   {
383     afm_name = kpse_find_file(strcat(strdup(buffer), ".afm"), kpse_afm_format, 1);
384     printf("path: %s.\n", afm_name);
385     pfb_name = kpse_find_file(strcat(strdup(buffer), ".pfb"), kpse_type1_format, 1);
386
387     if (afm_name != NULL && pfb_name != NULL)
388     {
389       k = insert_font_index(buffer);
390       fnt_name = HPDF_LoadType1FontFromFile (yandy_pdf, afm_name, pfb_name);
391       yandy_font[k] = HPDF_GetFont(yandy_pdf, fnt_name, NULL);
392     }
393   }
394   */
395   HPDF_Page_SetFontAndSize(yandy_page, yandy_font[0], (font_size[f] / 65535));
396 }
397
398 void pdf_ship_out(halfword p)
399 {
400   char j, k;
401
402   if (tracing_output > 0)
403   {
404     print_nl("");
405     print_ln();
406     print_string("Completed box being shipped out");
407   }
408
409   if (term_offset > max_print_line - 9)
410     print_ln();
411   else if ((term_offset > 0) || (file_offset > 0))
412     print_char(' ');
413
414   print_char('[');
415   j = 9;
416
417   while((count(j) == 0) && (j > 0))
418     decr(j);
419
420   for (k = 0; k <= j; k++)
421   {
422     print_int(count(k));
423
424     if (k < j)
425       print_char('.');
426   }
427
428 #ifndef _WINDOWS
429   fflush(stdout);
430 #endif
431
432   if (tracing_output > 0)
433   {
434     print_char(']');
435     begin_diagnostic();
436     show_box(p);
437     end_diagnostic(true);
438   }
439
440   if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
441       (height(p) + depth(p) + v_offset > max_dimen) ||
442       (width(p) + h_offset > max_dimen))
443   {
444     print_err("Huge page cannot be shipped out");
445     help2("The page just created is more than 18 feet tall or",
446         "more than 18 feet wide, so I suspect something went wrong.");
447     error();
448
449     if (tracing_output <= 0)
450     {
451       begin_diagnostic();
452       print_nl("The following box has been deleted:");
453       show_box(p);
454       end_diagnostic(true);
455     }
456
457     goto lab30;
458   }
459
460   if (height(p) + depth(p) + v_offset > max_v)
461     max_v = height(p) + depth(p) + v_offset;
462
463   if (width(p) + h_offset > max_h)
464     max_h = width(p) + h_offset;
465
466   dvi_h = 0;
467   dvi_v = 0;
468   cur_h = h_offset;
469   dvi_f = null_font;
470
471   if (output_file_name == 0)
472   {
473     if (job_name == 0)
474       open_log_file();
475
476     pack_job_name(".pdf");
477
478     while(!b_open_out(pdf_file))
479     {
480       prompt_file_name("file name for output", ".pdf");
481     }
482
483     output_file_name = b_make_name_string(pdf_file);
484   }
485
486   if (total_pages == 0)
487   {
488     init_tfm_map();
489     yandy_pdf = HPDF_New (pdf_error_handler, NULL);
490     HPDF_SetCompressionMode (yandy_pdf, HPDF_COMP_ALL);
491     yandy_pdf -> pdf_version = HPDF_VER_17;
492     HPDF_SetInfoAttr(yandy_pdf, HPDF_INFO_PRODUCER, "Y&Y TeX");
493     yandy_font[0] = HPDF_GetFont (yandy_pdf, "Times-Roman", NULL);
494   }
495
496   yandy_page = HPDF_AddPage (yandy_pdf);
497   HPDF_Page_SetFontAndSize(yandy_page, yandy_font[0], 10);
498   HPDF_Page_SetSize (yandy_page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
499
500   cur_v = height(p) + v_offset;
501   temp_ptr = p;
502
503   if (type(p) == vlist_node)
504     pdf_vlist_out();
505   else
506     pdf_hlist_out();
507
508   incr(total_pages);
509   cur_s = -1;
510 lab30:;
511   if (tracing_output <= 0)
512     print_char(']');
513
514   dead_cycles = 0;
515
516 #ifndef _WINDOWS
517   fflush(stdout);
518 #endif
519
520   flush_node_list(p);
521 }
522
523
524 void pdf_hlist_out (void)
525 {
526   scaled base_line;
527   scaled left_edge;
528   scaled save_h, save_v;
529   halfword this_box;
530 /*  glue_ord g_order;  */
531   int g_order;           /* 95/Jan/7 */
532 /*  char g_sign;  */
533   int g_sign;            /* 95/Jan/7 */
534   halfword p;
535   //integer save_loc;
536   halfword leader_box;
537   scaled leader_wd;
538   scaled lx;
539   bool outer_doing_leaders;
540   scaled edge;
541   real glue_temp;
542   real cur_glue;
543   scaled cur_g;
544
545   cur_g = 0;
546   cur_glue = 0.0;
547   this_box = temp_ptr;
548   g_order = glue_order(this_box);
549   g_sign = glue_sign(this_box);
550   p = list_ptr(this_box);
551   incr(cur_s);
552
553   base_line = cur_v;
554   left_edge = cur_h;
555
556   while (p != 0)
557 lab21:
558     if (is_char_node(p))
559     {
560       do
561         {
562           f = font(p);
563           c = character(p);
564
565           if (f != dvi_f)
566           {
567             if (!font_used[f])
568             {
569               font_used[f] = true;
570             }
571
572             dvi_f = f;
573           }
574           
575           HPDF_Page_BeginText(yandy_page);HPDF_Page_SetFontAndSize(yandy_page, yandy_font[0], 10);
576           HPDF_Page_MoveTextPos(yandy_page, pdf_sp_to_bp(cur_h) + 72, (841.89 - (pdf_sp_to_bp(cur_v) + 72)));
577           HPDF_Page_ShowText(yandy_page, pdf_char_to_string(c));
578           HPDF_Page_EndText(yandy_page);
579           cur_h = cur_h + char_width(f, char_info(f, c));
580           p = link(p);
581         }
582       while(((p >= hi_mem_min)));
583
584       dvi_h = cur_h;
585   }
586   else
587   {
588     switch (type(p))
589     {
590       case hlist_node:
591       case vlist_node:
592         if (list_ptr(p) == 0)
593           cur_h = cur_h + width(p);
594         else
595         {
596           save_h = dvi_h;
597           save_v = dvi_v;
598           cur_v = base_line + shift_amount(p);
599           temp_ptr = p;
600           edge = cur_h;
601
602           if (type(p) == vlist_node)
603             pdf_vlist_out();
604           else
605             pdf_hlist_out();
606
607           dvi_h = save_h;
608           dvi_v = save_v;
609           cur_h = edge + width(p);
610           cur_v = base_line;
611         }
612         break;
613
614       case rule_node:
615         {
616           rule_ht = height(p);
617           rule_dp = depth(p);
618           rule_wd = width(p);
619           goto lab14;
620         }
621         break;
622
623       case whatsit_node:
624         //out_what(p);
625         break;
626
627       case glue_node:
628         {
629           g = glue_ptr(p);
630           rule_wd = width(g) - cur_g;
631
632           if (g_sign != normal)
633           {
634             if (g_sign == stretching)
635             {
636               if (stretch_order(g) == g_order)
637               {
638                 cur_glue = cur_glue + stretch(g);
639                 glue_temp = glue_set(this_box) * cur_glue;
640
641                 if (glue_temp > 1000000000.0)
642                   glue_temp = 1000000000.0;
643                 else if (glue_temp < -1000000000.0)
644                   glue_temp = -1000000000.0;
645
646                 cur_g = round(glue_temp);
647               }
648             }
649             else if (shrink_order(g) == g_order)
650             {
651               cur_glue = cur_glue - shrink(g);
652               glue_temp = glue_set(this_box) * cur_glue;
653
654               if (glue_temp > 1000000000.0)
655                 glue_temp = 1000000000.0;
656               else if (glue_temp < -1000000000.0)
657                 glue_temp = -1000000000.0;
658
659               cur_g = round(glue_temp);
660             }
661           }
662
663           rule_wd = rule_wd + cur_g;
664
665           if (subtype(p) >= a_leaders)
666           {
667             leader_box = leader_ptr(p);
668
669             if (type(leader_box) == rule_node)
670             {
671               rule_ht = height(leader_box);
672               rule_dp = depth(leader_box);
673               goto lab14;
674             }
675
676             leader_wd = width(leader_box);
677
678             if ((leader_wd > 0) && (rule_wd > 0))
679             {
680               rule_wd = rule_wd + 10;
681               edge = cur_h + rule_wd;
682               lx = 0;
683
684               if (subtype(p) == a_leaders)
685               {
686                 save_h = cur_h;
687                 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
688
689                 if (cur_h < save_h)
690                   cur_h = cur_h + leader_wd;
691               }
692               else
693               {
694                 lq = rule_wd / leader_wd;
695                 lr = rule_wd % leader_wd;
696
697                 if (subtype(p) == c_leaders)
698                   cur_h = cur_h + (lr / 2);
699                 else
700                 {
701                   lx =(2 * lr + lq + 1) / (2 * lq + 2);
702                   cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
703                 }
704               }
705
706               while (cur_h + leader_wd <= edge)
707               {
708                 cur_v = base_line + shift_amount(leader_box);
709                 //synch_v();
710                 dvi_v = cur_v;
711                 save_v = dvi_v;
712                 //synch_h();
713                 dvi_h = cur_h;
714                 save_h = dvi_h;
715                 temp_ptr = leader_box;
716                 outer_doing_leaders = doing_leaders;
717                 doing_leaders = true;
718
719                 if (type(leader_box) == vlist_node)
720                   pdf_vlist_out();
721                 else
722                   pdf_hlist_out();
723
724                 doing_leaders = outer_doing_leaders;
725                 dvi_v = save_v;
726                 dvi_h = save_h;
727                 cur_v = base_line;
728                 cur_h = save_h + leader_wd + lx;
729               }
730
731               cur_h = edge - 10;
732               goto lab15;
733             }
734           }
735
736           goto lab13;
737         }
738         break;
739
740       case kern_node:
741       case math_node:
742         cur_h = cur_h + width(p);
743         break;
744
745       case ligature_node:
746         {
747           mem[lig_trick] = mem[lig_char(p)];
748           link(lig_trick) = link(p);
749           p = lig_trick;
750           goto lab21;
751         }
752         break;
753
754       default:
755         break;
756     }
757
758     goto lab15;
759 lab14:
760     if ((rule_ht == -1073741824L))  /* - 2^30 */
761       rule_ht = height(this_box);
762
763     if ((rule_dp == -1073741824L))     /* - 2^30 */
764       rule_dp = depth(this_box);
765
766     rule_ht = rule_ht + rule_dp;
767
768     if ((rule_ht > 0) && (rule_wd > 0))
769     {
770       cur_v = base_line + rule_dp;
771       HPDF_Page_SetLineWidth(yandy_page, rule_ht / 65535);
772       HPDF_Page_MoveTo (yandy_page, (cur_h / 65535 + 72), (841.89 - cur_v / 65535 - 72));
773       HPDF_Page_LineTo (yandy_page, (cur_h / 65535 + 72 + rule_wd / 65535), (841.89 - cur_v / 65535 - 72));
774       HPDF_Page_Stroke (yandy_page);
775       cur_v = base_line;
776       dvi_h = dvi_h + rule_wd;
777     }
778 lab13:
779     cur_h = cur_h + rule_wd;
780 lab15:
781     p = link(p);
782   }
783
784   decr(cur_s);
785 }
786 /* following needs access to dvi_buf=zdvibuf see coerce.h */
787 /* sec 0629 */
788 void pdf_vlist_out (void)
789 {
790   scaled left_edge;
791   scaled top_edge;
792   scaled save_h, save_v;
793   halfword this_box;
794 /*  glue_ord g_order;  */
795   int g_order;         /* 95/Jan/7 */
796 /*  char g_sign;  */
797   int g_sign;          /* 95/Jan/7 */
798   halfword p;
799   //integer save_loc;
800   halfword leader_box;
801   scaled leader_ht;
802   scaled lx;
803   bool outer_doing_leaders;
804   scaled edge;
805   real glue_temp;
806   real cur_glue;
807   scaled cur_g;
808
809   cur_g = 0;
810   cur_glue = 0.0;
811   this_box = temp_ptr;
812   g_order = glue_order(this_box);
813   g_sign = glue_sign(this_box);
814   p = list_ptr(this_box);
815   incr(cur_s);
816
817   left_edge = cur_h;
818   cur_v = cur_v - height(this_box);
819   top_edge = cur_v;
820
821   while (p != 0)
822   {
823     if ((p >= hi_mem_min))
824     {
825       confusion("vlistout");
826       return;       // abort_flag set
827     }
828     else
829     {
830       switch (type(p))
831       {
832         case hlist_node:
833         case vlist_node:
834           if (list_ptr(p) == 0)
835             cur_v = cur_v + height(p) + depth(p);
836           else
837           {
838             cur_v = cur_v + height(p);
839             //synch_v();
840             dvi_v = cur_v;
841             save_h = dvi_h;
842             save_v = dvi_v;
843             cur_h = left_edge + shift_amount(p);
844             temp_ptr = p;
845
846             if (type(p) == vlist_node)
847               pdf_vlist_out();
848             else
849               pdf_hlist_out();
850
851             dvi_h = save_h;
852             dvi_v = save_v;
853             cur_v = save_v + depth(p);
854             cur_h = left_edge;
855           }
856           break;
857
858         case rule_node:
859           {
860             rule_ht = height(p);
861             rule_dp = depth(p);
862             rule_wd = width(p);
863             goto lab14;
864           }
865           break;
866
867         case whatsit_node:
868           //out_what(p);
869           break;
870
871         case glue_node:
872           {
873             g = glue_ptr(p);
874             rule_ht = width(g) - cur_g;
875
876             if (g_sign != normal)
877             {
878               if (g_sign == stretching)
879               {
880                 if (stretch_order(g) == g_order)
881                 {
882                   cur_glue = cur_glue + stretch(g);
883                   glue_temp = glue_set(this_box) * cur_glue;
884
885                   if (glue_temp > 1000000000.0)
886                     glue_temp = 1000000000.0;
887                   else if (glue_temp < -1000000000.0)
888                     glue_temp = -1000000000.0;
889
890                   cur_g = round(glue_temp);
891                 }
892               }
893               else if (shrink_order(g) == g_order)   /* BUG FIX !!! */
894               {
895                 cur_glue = cur_glue - shrink(g);
896                 glue_temp = glue_set(this_box) * cur_glue;
897
898                 if (glue_temp > 1000000000.0)
899                   glue_temp = 1000000000.0;
900                 else if (glue_temp < -1000000000.0)
901                   glue_temp = -1000000000.0;
902
903                 cur_g = round(glue_temp);
904               }
905             }
906
907             rule_ht = rule_ht + cur_g;
908
909             if (subtype(p) >= a_leaders)
910             {
911               leader_box = leader_ptr(p);
912
913               if (type(leader_box) == rule_node)
914               {
915                 rule_wd = width(leader_box);
916                 rule_dp = 0;
917                 goto lab14;
918               }
919
920               leader_ht = height(leader_box) + depth(leader_box);
921
922               if ((leader_ht > 0) && (rule_ht > 0))
923               {
924                 rule_ht = rule_ht + 10;
925                 edge = cur_v + rule_ht;
926                 lx = 0;
927
928                 if (subtype(p) == a_leaders)
929                 {
930                   save_v = cur_v;
931                   cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
932
933                   if (cur_v < save_v)
934                     cur_v = cur_v + leader_ht;
935                 }
936                 else
937                 {
938                   lq = rule_ht / leader_ht;
939                   lr = rule_ht % leader_ht;
940
941                   if (subtype(p) == c_leaders)
942                     cur_v = cur_v + (lr / 2);
943                   else
944                   {
945                     lx = (2 * lr + lq + 1) / (2 * lq + 2);
946                     cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
947                   }
948                 }
949
950                 while (cur_v + leader_ht <= edge)
951                 {
952                   cur_h = left_edge + shift_amount(leader_box);
953                   //synch_h();
954                   dvi_h = cur_h;
955                   save_h = dvi_h;
956                   cur_v = cur_v + height(leader_box);
957                   //synch_v();
958                   dvi_v = cur_v;
959                   save_v = dvi_v;
960                   temp_ptr = leader_box;
961                   outer_doing_leaders = doing_leaders;
962                   doing_leaders = true;
963
964                   if (type(leader_box) == vlist_node)
965                     pdf_vlist_out();
966                   else
967                     pdf_hlist_out();
968
969                   doing_leaders = outer_doing_leaders;
970                   dvi_v = save_v;
971                   dvi_h = save_h;
972                   cur_h = left_edge;
973                   cur_v = save_v - height(leader_box) + leader_ht + lx;
974                 }
975
976                 cur_v = edge - 10;
977                 goto lab15;
978               }
979             }
980
981             goto lab13;
982           }
983           break;
984
985         case kern_node:
986           cur_v = cur_v + width(p);
987           break;
988
989         default:
990           break;
991       }
992       goto lab15;
993 lab14:
994       if ((rule_wd == -1073741824L))    /* -2^30 */
995         rule_wd = width(this_box);
996
997       rule_ht = rule_ht + rule_dp;
998       cur_v = cur_v + rule_ht;
999
1000       if ((rule_ht > 0) && (rule_wd > 0))
1001       {
1002         HPDF_Page_SetLineWidth(yandy_page, rule_ht / 65535);
1003         HPDF_Page_MoveTo(yandy_page, (cur_h / 65535 + 72), (841.89 - cur_v / 65535 - 72));
1004         HPDF_Page_LineTo(yandy_page, (cur_h / 65535 + 72 + rule_wd / 65535), (841.89 - cur_v / 65535 - 72));
1005         HPDF_Page_Stroke(yandy_page);
1006       }
1007
1008       goto lab15;
1009 lab13:
1010       cur_v = cur_v + rule_ht;
1011     }
1012 lab15:
1013     p = link(p);
1014   }
1015
1016   decr(cur_s);
1017 }