OSDN Git Service

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