pic: use troff drawing commands for filling objects
[troff.git] / troff / n7.c
blobf824580ff9b02ea0f7e4115e2f04ffd8c2428546
1 #include "tdef.h"
2 #include "fns.h"
3 #include "ext.h"
5 #define GETCH gettch
6 Tchar gettch(void);
8 /*
9 * troff7.c
11 * text
14 int brflg;
16 void tbreak(void)
18 int pad, k;
19 Tchar *i, j;
20 int resol;
21 int un0 = un;
23 trap = 0;
24 if (nb)
25 return;
26 if (dip == d && numtabp[NL].val == -1) {
27 newline(1);
28 return;
30 if (!nc) {
31 setnel();
32 if (!wch)
33 return;
34 if (pendw)
35 getword(1);
36 movword();
37 } else if (pendw && !brflg) {
38 getword(1);
39 movword();
41 *linep = dip->nls = 0;
42 if (NROFF && dip == d)
43 horiz(po);
44 if (lnmod)
45 donum();
46 lastl = ne;
47 if (brflg != 1) {
48 totout = 0;
49 } else if (ad) {
50 if ((lastl = ll - un) < ne)
51 lastl = ne;
53 if (admod && ad && (brflg != 2)) {
54 lastl = ne;
55 adsp = adrem = 0;
56 if (admod == 1)
57 un += quant(nel / 2, HOR);
58 else if (admod == 2)
59 un += nel;
61 totout++;
62 brflg = 0;
63 if (lastl + un > dip->maxl)
64 dip->maxl = lastl + un;
65 horiz(un);
66 if (NROFF) {
67 if (adrem % t.Adj)
68 resol = t.Hor;
69 else
70 resol = t.Adj;
71 } else
72 resol = HOR;
74 lastl = ne + (nwd-1) * adsp + adrem;
75 for (i = line; nc > 0; ) {
76 if ((cbits(j = *i++)) == ' ') {
77 pad = 0;
78 do {
79 pad += width(j);
80 nc--;
81 } while ((cbits(j = *i++)) == ' ');
82 i--;
83 pad += adsp;
84 --nwd;
85 if (adrem) {
86 if (adrem < 0) {
87 pad -= resol;
88 adrem += resol;
89 } else if ((totout & 01) || adrem / resol >= nwd) {
90 pad += resol;
91 adrem -= resol;
94 pchar((Tchar) WORDSP);
95 horiz(pad);
96 } else {
97 pchar(j);
98 nc--;
101 if (ic) {
102 if ((k = ll - un0 - lastl + ics) > 0)
103 horiz(k);
104 pchar(ic);
106 if (icf)
107 icf++;
108 else
109 ic = 0;
110 ne = nwd = 0;
111 un = in;
112 setnel();
113 newline(0);
114 if (dip != d) {
115 if (dip->dnl > dip->hnl)
116 dip->hnl = dip->dnl;
117 } else {
118 if (numtabp[NL].val > dip->hnl)
119 dip->hnl = numtabp[NL].val;
121 for (k = ls - 1; k > 0 && !trap; k--)
122 newline(0);
123 spread = 0;
126 void donum(void)
128 int i, nw;
129 int lnv = numtabp[LN].val;
131 nrbits = nmbits;
132 nw = width('1' | nrbits);
133 if (nn) {
134 nn--;
135 goto d1;
137 if (lnv % ndf) {
138 numtabp[LN].val++;
140 un += nw * (nmwid + nms + ni);
141 return;
143 i = 0;
144 do { /* count digits in numtabp[LN].val */
145 i++;
146 } while ((lnv /= 10) > 0);
147 horiz(nw * (ni + max(nmwid-i, 0)));
148 nform = 0;
149 fnumb(numtabp[LN].val, pchar);
150 un += nw * nms;
151 numtabp[LN].val++;
155 void text(void)
157 Tchar i;
158 static int spcnt;
160 nflush++;
161 numtabp[HP].val = 0;
162 if ((dip == d) && (numtabp[NL].val == -1)) {
163 newline(1);
164 return;
166 setnel();
167 if (ce || !fi) {
168 nofill();
169 return;
171 if (pendw)
172 goto t4;
173 if (pendt)
174 if (spcnt)
175 goto t2;
176 else
177 goto t3;
178 pendt++;
179 if (spcnt)
180 goto t2;
181 while ((cbits(i = GETCH())) == ' ') {
182 spcnt++;
183 numtabp[HP].val += sps;
184 widthp = sps;
186 if (nlflg) {
188 nflush = pendt = ch = spcnt = 0;
189 callsp();
190 return;
192 ch = i;
193 if (spcnt) {
195 tbreak();
196 if (nc || wch)
197 goto rtn;
198 un += spcnt * sps;
199 spcnt = 0;
200 setnel();
201 if (trap)
202 goto rtn;
203 if (nlflg)
204 goto t1;
207 if (spread)
208 goto t5;
209 if (pendw || !wch)
211 if (getword(0))
212 goto t6;
213 if (!movword())
214 goto t3;
216 if (nlflg)
217 pendt = 0;
218 adsp = adrem = 0;
219 if (ad) {
220 if (nwd == 1)
221 adsp = nel;
222 else
223 adsp = nel / (nwd - 1);
224 adsp = (adsp / HOR) * HOR;
225 adrem = nel - adsp*(nwd-1);
227 brflg = 1;
228 tbreak();
229 spread = 0;
230 if (!trap)
231 goto t3;
232 if (!nlflg)
233 goto rtn;
235 pendt = 0;
236 ckul();
237 rtn:
238 nflush = 0;
242 void nofill(void)
244 int j;
245 Tchar i;
247 if (!pendnf) {
248 over = 0;
249 tbreak();
250 if (trap)
251 goto rtn;
252 if (nlflg) {
253 ch = nflush = 0;
254 callsp();
255 return;
257 adsp = adrem = 0;
258 nwd = 10000;
260 while ((j = (cbits(i = GETCH()))) != '\n') {
261 if (j == ohc)
262 continue;
263 if (j == CONT) {
264 pendnf++;
265 nflush = 0;
266 flushi();
267 ckul();
268 return;
270 j = width(i);
271 widthp = j;
272 numtabp[HP].val += j;
273 storeline(i, j);
275 if (ce) {
276 ce--;
277 if ((i = quant(nel / 2, HOR)) > 0)
278 un += i;
280 if (!nc)
281 storeline((Tchar)FILLER, 0);
282 brflg = 2;
283 tbreak();
284 ckul();
285 rtn:
286 pendnf = nflush = 0;
290 void callsp(void)
292 int i;
294 if (flss)
295 i = flss;
296 else
297 i = lss;
298 flss = 0;
299 casesp1(i);
303 void ckul(void)
305 if (ul && (--ul == 0)) {
306 cu = 0;
307 font = sfont;
308 mchbits();
310 if (it && --it == 0 && itmac)
311 control(itmac, 0);
315 void storeline(Tchar c, int w)
317 int diff;
319 if (linep >= line + lnsize - 2) {
320 lnsize += LNSIZE;
321 diff = linep - line;
322 if (( line = (Tchar *)realloc((char *)line, lnsize * sizeof(Tchar))) != NULL) {
323 if (linep && diff)
324 linep = line + diff;
325 } else {
326 if (over) {
327 return;
328 } else {
329 flusho();
330 ERROR "Line overflow." WARN;
331 over++;
332 *linep++ = LEFTHAND;
333 w = width(LEFTHAND);
334 nc++;
335 c = '\n';
339 *linep++ = c;
340 ne += w;
341 nel -= w;
342 nc++;
346 void newline(int a)
348 int i, j, nlss;
349 int opn;
351 if (a)
352 goto nl1;
353 if (dip != d) {
354 j = lss;
355 pchar1((Tchar)FLSS);
356 if (flss)
357 lss = flss;
358 i = lss + dip->blss;
359 dip->dnl += i;
360 pchar1((Tchar)i);
361 pchar1((Tchar)'\n');
362 lss = j;
363 dip->blss = flss = 0;
364 if (dip->alss) {
365 pchar1((Tchar)FLSS);
366 pchar1((Tchar)dip->alss);
367 pchar1((Tchar)'\n');
368 dip->dnl += dip->alss;
369 dip->alss = 0;
371 if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap && dip->dimac)
372 if (control(dip->dimac, 0)) {
373 trap++;
374 dip->ditf++;
376 return;
378 j = lss;
379 if (flss)
380 lss = flss;
381 nlss = dip->alss + dip->blss + lss;
382 numtabp[NL].val += nlss;
383 if (TROFF && ascii) {
384 dip->alss = dip->blss = 0;
386 pchar1((Tchar)'\n');
387 flss = 0;
388 lss = j;
389 if (numtabp[NL].val < pl)
390 goto nl2;
391 nl1:
392 ejf = dip->hnl = numtabp[NL].val = 0;
393 ejl = frame;
394 if (donef) {
395 if ((!nc && !wch) || ndone)
396 done1(0);
397 ndone++;
398 donef = 0;
399 if (frame == stk)
400 nflush++;
402 opn = numtabp[PN].val;
403 numtabp[PN].val++;
404 if (npnflg) {
405 numtabp[PN].val = npn;
406 npn = npnflg = 0;
408 nlpn:
409 if (numtabp[PN].val == pfrom) {
410 print++;
411 pfrom = -1;
412 } else if (opn == pto) {
413 print = 0;
414 opn = -1;
415 chkpn();
416 goto nlpn;
418 if (print)
419 ptpage(numtabp[PN].val); /* supposedly in a clean state so can pause */
420 if (stop && print) {
421 dpn++;
422 if (dpn >= stop) {
423 dpn = 0;
424 ptpause();
427 nl2:
428 trap = 0;
429 if (numtabp[NL].val == 0) {
430 if ((j = findn(0)) != NTRAP)
431 trap = control(mlist[j], 0);
432 } else if ((i = findt(numtabp[NL].val - nlss)) <= nlss) {
433 if ((j = findn1(numtabp[NL].val - nlss + i)) == NTRAP) {
434 flusho();
435 ERROR "Trap botch." WARN;
436 done2(-5);
438 trap = control(mlist[j], 0);
443 int findn1(int a)
445 int i, j;
447 for (i = 0; i < NTRAP; i++) {
448 if (mlist[i]) {
449 if ((j = nlist[i]) < 0)
450 j += pl;
451 if (j == a)
452 break;
455 return i;
459 void chkpn(void)
461 pto = *(pnp++);
462 pfrom = pto>=0 ? pto : -pto;
463 if (pto == -INT_MAX) {
464 flusho();
465 done1(0);
467 if (pto < 0) {
468 pto = -pto;
469 print++;
470 pfrom = 0;
475 int findt(int a)
477 int i, j, k;
479 k = INT_MAX;
480 if (dip != d) {
481 if (dip->dimac && (i = dip->ditrap - a) > 0)
482 k = i;
483 return k;
485 for (i = 0; i < NTRAP; i++) {
486 if (mlist[i]) {
487 if ((j = nlist[i]) < 0)
488 j += pl;
489 if ((j -= a) <= 0)
490 continue;
491 if (j < k)
492 k = j;
495 i = pl - a;
496 if (k > i)
497 k = i;
498 return k;
502 int findt1(void)
504 int i;
506 if (dip != d)
507 i = dip->dnl;
508 else
509 i = numtabp[NL].val;
510 return findt(i);
514 void eject(Stack *a)
516 int savlss;
518 if (dip != d)
519 return;
520 ejf++;
521 if (a)
522 ejl = a;
523 else
524 ejl = frame;
525 if (trap)
526 return;
528 savlss = lss;
529 lss = findt(numtabp[NL].val);
530 newline(0);
531 lss = savlss;
532 if (numtabp[NL].val && !trap)
533 goto e1;
537 int movword(void)
539 int w;
540 Tchar i, *wp;
541 int savwch, hys;
543 over = 0;
544 wp = wordp;
545 if (!nwd) {
546 while (cbits(*wp++) == ' ') {
547 wch--;
548 wne -= sps;
550 wp--;
552 if (wne > nel && !hyoff && hyf && (!nwd || nel > 3 * sps) &&
553 (!(hyf & 02) || (findt1() > lss)))
554 hyphen(wp);
555 savwch = wch;
556 hyp = hyptr;
557 nhyp = 0;
558 while (*hyp && *hyp <= wp)
559 hyp++;
560 while (wch) {
561 if (hyoff != 1 && *hyp == wp) {
562 hyp++;
563 if (!wdstart || (wp > wdstart + 1 && wp < wdend &&
564 (!(hyf & 04) || wp < wdend - 1) && /* 04 => last 2 */
565 (!(hyf & 010) || wp > wdstart + 2))) { /* 010 => 1st 2 */
566 nhyp++;
567 storeline((Tchar)IMP, 0);
570 i = *wp++;
571 w = width(i);
572 wne -= w;
573 wch--;
574 storeline(i, w);
576 if (nel >= 0) {
577 nwd++;
578 return 0; /* line didn't fill up */
580 if (TROFF)
581 xbits((Tchar)HYPHEN, 1);
582 hys = width((Tchar)HYPHEN);
584 if (!nhyp) {
585 if (!nwd)
586 goto m3;
587 if (wch == savwch)
588 goto m4;
590 if (*--linep != IMP)
591 goto m5;
592 if (!(--nhyp))
593 if (!nwd)
594 goto m2;
595 if (nel < hys) {
596 nc--;
597 goto m1;
600 if ((i = cbits(*(linep - 1))) != '-' && i != EMDASH) {
601 *linep = (*(linep - 1) & SFMASK) | HYPHEN;
602 w = width(*linep);
603 nel -= w;
604 ne += w;
605 linep++;
608 nwd++;
610 wordp = wp;
611 return(1); /* line filled up */
613 nc--;
614 w = width(*linep);
615 ne -= w;
616 nel += w;
617 wne += w;
618 wch++;
619 wp--;
620 goto m1;
624 void horiz(int i)
626 vflag = 0;
627 if (i)
628 pchar(makem(i));
632 void setnel(void)
634 if (!nc) {
635 linep = line;
636 if (un1 >= 0) {
637 un = un1;
638 un1 = -1;
640 nel = ll - un;
641 ne = adsp = adrem = 0;
646 int getword(int x)
648 int j, k;
649 Tchar i, *wp;
650 int noword;
651 int obits;
653 noword = 0;
654 if (x)
655 if (pendw) {
656 *pendw = 0;
657 goto rtn;
659 if (wordp = pendw)
660 goto g1;
661 hyp = hyptr;
662 wordp = word;
663 over = wne = wch = 0;
664 hyoff = 0;
665 obits = chbits;
666 while (1) { /* picks up 1st char of word */
667 j = cbits(i = GETCH());
668 if (j == '\n') {
669 wne = wch = 0;
670 noword = 1;
671 goto rtn;
673 if (j == ohc) {
674 hyoff = 1; /* 1 => don't hyphenate */
675 continue;
677 if (j == ' ') {
678 numtabp[HP].val += sps;
679 widthp = sps;
680 storeword(i, sps);
681 continue;
683 break;
685 storeword(' ' | obits, sps);
686 if (spflg) {
687 storeword(' ' | obits, sps);
688 spflg = 0;
691 if (j == CONT) {
692 pendw = wordp;
693 nflush = 0;
694 flushi();
695 return 1;
697 if (hyoff != 1) {
698 if (j == ohc) {
699 hyoff = 2;
700 *hyp++ = wordp;
701 if (hyp > hyptr + NHYP - 1)
702 hyp = hyptr + NHYP - 1;
703 goto g1;
705 if (((j == '-' || j == EMDASH)) && !(i & ZBIT)) /* zbit avoids \X */
706 if (wordp > word + 1) {
707 hyoff = 2;
708 *hyp++ = wordp + 1;
709 if (hyp > hyptr + NHYP - 1)
710 hyp = hyptr + NHYP - 1;
713 j = width(i);
714 numtabp[HP].val += j;
715 storeword(i, j);
717 j = cbits(i = GETCH());
718 if (j != ' ') {
719 static char *sentchar = ".?!"; /* sentence terminators */
720 if (j != '\n')
721 goto g0;
722 wp = wordp-1; /* handle extra space at end of sentence */
723 while (wp >= word) {
724 j = cbits(*wp--);
725 if (j=='"' || j=='\'' || j==')' || j==']' || j=='*' || j==DAGGER)
726 continue;
727 for (k = 0; sentchar[k]; k++)
728 if (j == sentchar[k]) {
729 spflg++;
730 break;
732 break;
735 *wordp = 0;
736 numtabp[HP].val += sps;
737 rtn:
738 for (wp = word; *wp; wp++) {
739 if (ismot(j))
740 break; /* drechsler */
741 j = cbits(*wp);
742 if (j == ' ')
743 continue;
744 if (!(isascii(j) && isdigit(j)) && j != '-')
745 break;
747 if (*wp == 0) /* all numbers, so don't hyphenate */
748 hyoff = 1;
749 wdstart = 0;
750 wordp = word;
751 pendw = 0;
752 *hyp++ = 0;
753 setnel();
754 return noword;
758 void storeword(Tchar c, int w)
760 Tchar *savp;
761 int i;
763 if (wordp >= word + wdsize - 2) {
764 wdsize += WDSIZE;
765 savp = word;
766 if (( word = (Tchar *)realloc((char *)word, wdsize * sizeof(Tchar))) != NULL) {
767 if (wordp)
768 wordp = word + (wordp - savp);
769 if (pendw)
770 pendw = word + (pendw - savp);
771 if (wdstart)
772 wdstart = word + (wdstart - savp);
773 if (wdend)
774 wdend = word + (wdend - savp);
775 for (i = 0; i < NHYP; i++)
776 if (hyptr[i])
777 hyptr[i] = word + (hyptr[i] - savp);
778 } else {
779 if (over) {
780 return;
781 } else {
782 flusho();
783 ERROR "Word overflow." WARN;
784 over++;
785 c = LEFTHAND;
786 w = width(LEFTHAND);
790 widthp = w;
791 wne += w;
792 *wordp++ = c;
793 wch++;
797 Tchar gettch(void)
799 extern int c_isalnum;
800 Tchar i;
801 int j;
803 if (TROFF)
804 return getch();
806 i = getch();
807 j = cbits(i);
808 if (ismot(i) || fbits(i) != ulfont)
809 return(i);
810 if (cu) {
811 if (trtab[j] == ' ') {
812 setcbits(i, '_');
813 setfbits(i, FT); /* default */
815 return(i);
817 /* should test here for characters that ought to be underlined */
818 /* in the old nroff, that was the 200 bit on the width! */
819 /* for now, just do letters, digits and certain special chars */
820 if (j <= 127) {
821 if (!isalnum(j))
822 setfbits(i, FT);
823 } else {
824 if (j < c_isalnum)
825 setfbits(i, FT);
827 return(i);