home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / DSMODS / COMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-10  |  19.4 KB  |  919 lines

  1. /*****************************************************************************/
  2. /* HISTORY:                                     */
  3. /*                                         */
  4. /*        bwdct()                                 */
  5. /* 11/10/89  -  fwdct()     - Added cpabt = 0;                     */
  6. /*                      Problems resulted in that the routine doesn't  */
  7. /*                  clear the flag if no errors occur, thereby     */
  8. /*                  leaving the old state in the flag.         */
  9. /*****************************************************************************/
  10. #include    "defs.h"
  11. #include    "comp.h"
  12.  
  13. #define        DEBUG        0
  14.  
  15. #define        Fac        4    /* Floating Accent bit mask    */
  16. #define        MIN_LEFT    10    /* minimum text buffer left    */
  17.  
  18. extern  char        *savecptr;
  19.  
  20. extern    unsigned char    HY_TYPE, fofg;
  21. extern    unsigned    hyph_index;
  22. extern    unsigned char    getfp(), *bwdct(), *prvp1(), *prvp2(), *prvp3(),
  23.             getLch();
  24.  
  25. /*    Locals        */
  26. static    unsigned    hypn = 0;    /* hyphenated line counter    */
  27.     unsigned char    *hyptr[65];
  28.  
  29. #if    DEBUG == 1
  30.     static    char    hbf[80];
  31.     static    char    *bfp, *hp1, *hp2;
  32. #endif
  33.  
  34. /*
  35.     Batch Composition & Line Break processor.
  36.     Only called by dotext(). Returns pointer to next text
  37.     if cpabt is 0 or 8 else -1L for all other true values
  38.     of cpabt.
  39. */
  40. unsigned char    *fend(text,done)
  41. struct textobj    *text;
  42. int        *done;
  43. {
  44.     unsigned char    *cptr;
  45.  
  46.     cpabt = 0;                /* no error so far...    */
  47.     if (current_char >= buf_end) {    
  48.         *done = 1;
  49.         return(-1L);
  50.     }                    
  51.     cptr        = savecptr;
  52.     buf_ptr[COMP]    = buf_end;
  53.     initfcmp();
  54.     movtotag(&cptr,COMP);
  55.     if (cpabt == -1)            /* reach break depth    */
  56.         cpabt = 0;            /* is not an error...    */
  57.  
  58.     if (!cpabt || cpabt == 8) {        /* no error or hit Rf    */
  59.         *done = (cptr >= buf_end);
  60.         savecptr = cptr;
  61.         cptr = free_start + (long)(cptr - current_char);
  62.     }
  63.     else {
  64.         CPrewindow(buf_end);
  65.         CPrewindow(text->begtext);
  66.         savecptr = current_char;
  67.         cptr = (unsigned char *)-1L;
  68.         *done = 0;
  69.     }
  70.     return(cptr);
  71. }
  72.  
  73. /*
  74.     Function to forward batch compose to tagged point of buffer. Set
  75.     cpabt:    8    -- Hit Region Feed
  76.         -1    -- reach defined break depth
  77.     Note:    Above true values except (-1) will be saved in cpabt flag.
  78. */
  79. movtotag(ptr,tag)
  80. unsigned char    **ptr;
  81. int        tag;
  82. {
  83.     unsigned char    em, rsovsp, c;
  84.     unsigned    hyw;
  85.  
  86. #if    DEBUG == 1
  87.     printf("\nIn movtotag..");
  88.     printf("\ncp.ll=%d cp.d=%ld cp.ls=%ld",cp.llen,cp.depth,cp.lnsp);
  89. #endif
  90.     while (!cpabt && *ptr < buf_ptr[tag])
  91.       switch(c = **ptr) {
  92.       case hrt: case Rf:
  93.         if (fwdct(ptr))
  94.             break;
  95.         hypn    = 0;
  96.         *ptr    += 3;
  97.         if (c == Rf)
  98.             cpabt = 8;
  99.         else
  100.         if (advdp())
  101.             cpabt = -1;
  102.         break;
  103.       case cr:
  104.         *ptr    += 2;
  105.         break;
  106.       case srt:
  107.         CPrewindow(*ptr);
  108.         *ptr    += 3;
  109.         if (tagc(*(free_start-2)))
  110.             em = 1;
  111.         else
  112.         if (*(free_start-1) == sHY) {    /* sHY+srt delete sHY    */
  113.             CPrewindow(free_start-1);
  114.             --cct;
  115.             if (buf_ptr[OVSP] == current_char)
  116.                 rsovsp = 1;
  117.             else
  118.             if (buf_ptr[PRFP] == current_char)
  119.                 rsovsp = 2;
  120.             else
  121.             if (buf_ptr[NLTP] == current_char)
  122.                 rsovsp = 3;
  123.             else    rsovsp = 0;
  124.             em = 2;
  125.         }
  126.         else    em =    *(free_start-1) == DH    ||
  127.                 *(free_start-1) == '-'    ||
  128.                 *(free_start-1) == Mdsh    ||    /* EM-    */
  129.                 *(free_start-1) == Ndsh        /* EN-    */
  130.                 ? 0:1;
  131.         if (current_char > *ptr)    /* delete srt+cr+lf    */
  132.             free_start    = *ptr;
  133.         else    current_char    = *ptr;
  134.         CPrewindow(current_char);
  135.         if (em == 1) {            /* adding space mode    */
  136.             *free_start++    = ' ';
  137.             CPrewindow(free_start-1);
  138.         }
  139.         else
  140.         if (em == 2) {            /* removing (-) mode    */
  141.             hyw = cwffp(HYfp);
  142.             if (cp.kernmd)
  143.                 kerning(HYfp,prvp1(free_start-1),&hyw);
  144.             clen += hyw;
  145.             if (rsovsp == 1)
  146.                 setbptr(OVSP);
  147.             else
  148.             if (rsovsp == 2)
  149.                 setbptr(PRFP);
  150.             else
  151.             if (rsovsp == 3)
  152.                 setbptr(NLTP);
  153.         }
  154.         *ptr = current_char;
  155.         break;
  156.       case sDH:
  157.         **ptr = DH;
  158.       case QL: case QR: case QC:
  159.       case DH:
  160.         ++(*ptr);
  161.         break;
  162.       default:
  163.         if (fwdct(ptr))
  164.             break;
  165.         ++(*ptr);
  166.         break;
  167.       }
  168. }
  169.  
  170. zerocpptrs()
  171. {
  172.     buf_ptr[NLTP]    = buf_ptr[OVSP]    =
  173.     buf_ptr[PRFP]    = buf_ptr[PRFS]    = 0L;
  174. }
  175.  
  176. /*
  177.     Function to handle line ending by
  178.     advancing Depth counter by Line Space
  179. */
  180. advdp()
  181. {
  182.     int    brk;
  183.  
  184.     if ((cdep + cp.lnsp) >= cp.depth)
  185.         brk    = 1;
  186.     else {
  187.         brk    = 0;
  188.         cdep    += cp.lnsp;
  189.         clen    = cp.llen;
  190.         smsz    = cp.ssiz;
  191.         lspc    = 0;
  192.         cct    = 0;
  193.         cmpval    = avcval = 0;
  194.         sflg    = inovs = false;
  195.         zerocpptrs();
  196.     }
  197.     return(brk);
  198. }
  199.  
  200. ckprefsp(p)
  201. char    *p;
  202. {
  203.     if (*p == ' ' && !buf_ptr[PRFS]) buf_ptr[PRFS] = p;
  204. }
  205.  
  206. ckrgeptr(p,tag)
  207. char    *p;
  208. int    tag;
  209. {
  210.     if (!buf_ptr[tag]) buf_ptr[tag] = p;
  211. }
  212.  
  213. /*
  214.     Function to advance line length counter by decreasing it by
  215.     the present character width.
  216.     Returns 1 if width is > Line Length else 0.
  217. */
  218. advll(cw,p)
  219. int    cw;
  220. char    *p;
  221. {
  222.     unsigned    ccnt;
  223.     int        tlen, rc;
  224.  
  225.     rc = 0;
  226.     if (!sflg && !inovs) {
  227.       if (cw > (int)clen) {
  228.         if (cp.jstmd == AJ)
  229.             sflg = 1;
  230.         else    goto ovs;
  231.       }
  232.       else    goto chk;
  233.     }
  234.     if (sflg == 1) {
  235.       tlen = clen + (cwfrw(cp.prfsp,1) * lspc);
  236.       if (tlen < 0 || cw > tlen) {
  237.         if (cp.ltsmd)
  238.             sflg = 2;
  239.         else {
  240.             sflg = 0;
  241.             goto ovs;
  242.         }
  243.       }
  244.       else {
  245.         ckrgeptr(p,PRFP);
  246.         ckprefsp(p);
  247.         goto nor;
  248.       }
  249.     }
  250.     if (sflg == 2) {
  251.       ccnt = cct ? cct - 1:0;
  252.       tlen = clen + (cwfrw(cp.prfsp,1) * lspc) +
  253.             (cwfrw(cp.nlts,1) * ccnt);
  254.       if (tlen < 0 || cw > tlen) {
  255.         sflg = 0;
  256.         goto ovs;
  257.       }
  258.       ckrgeptr(p,NLTP);
  259.       ckprefsp(p);
  260.     }
  261.     else
  262. chk:    if (inovs || (int)clen < 0)
  263. ovs:        rc = 1; 
  264. nor:    clen -= cw;
  265.     return(rc);
  266. }
  267.  
  268. /*
  269.     Function to find the present justification status
  270.     after moving backward.
  271. */
  272. findst()
  273. {
  274.     unsigned    ccnt;
  275.     int        tlen;
  276.  
  277.     if ((int)clen < 0) {
  278.       if (cp.jstmd != AJ)
  279.         goto ovs;
  280.       tlen = clen + (cwfrw(cp.prfsp,1) * lspc);
  281.       if (tlen >= 0) {
  282.         sflg    = 1;
  283.         inovs    = 0;
  284.       }
  285.       else 
  286.       if (cp.ltsmd) {
  287.         ccnt = cct ? cct - 1:0;
  288.         tlen += cwfrw(cp.nlts,1) * ccnt;
  289.         if (tlen >= 0) {
  290.             sflg    = 2;
  291.             inovs    = 0;
  292.         }
  293.         else    goto ovs;
  294.       }
  295.       else {
  296. ovs:        sflg    = 0;
  297.         inovs    = 1;
  298.       }
  299.     }
  300.     else    sflg = inovs = 0;
  301. }
  302.  
  303. /*
  304.     Function to test for short line length
  305. */
  306. cksll(cw)
  307. int    cw;
  308. {
  309.     return(!cct && cw > (int)clen);
  310. }
  311.  
  312. /*
  313.     Function to do forward counting on the character at pointer. Set
  314.     cpabt:    0    -- no error
  315.         1    -- char has no flash position
  316.         2    -- double floating accent found
  317.         3    -- double space char found
  318.         4    -- line measure too short
  319.         5    -- line break error (no space)
  320.         6    -- text buffer full
  321.         7    -- no memory for tag support
  322.         -1    -- reach defined break depth
  323.     Note:    Above true values except (-1) will be saved in cpabt flag.
  324. */
  325. fwdct(nptr)
  326. unsigned char **nptr;
  327. {
  328.     unsigned    i, cw, hyw, hycnt;
  329.     unsigned char    *ptr, *scc, *hyp, *ewp;
  330.     unsigned char    ccfp, hymd, cc;
  331.     char        ishy, nobrk, rshypn, fafg, sp_lts, fnd;
  332.  
  333. /*    cpabt   = 0;*/
  334.     ptr    = *nptr;
  335.     cw    = 0;
  336.     sp_lts    = 0;
  337.     if (*ptr == STAG)            /* Hit a Start    TAG    */
  338.         in_tag(*(++*nptr),1,1);
  339.     else
  340.     if (*ptr == ETAG)            /* Hit an End    TAG    */
  341.         out_tag(*(++*nptr),1,1);
  342.     else
  343.     if (fofg) {                /* validate Flash only    */
  344.         if (*ptr == sHY || !nofa(ptr,&ccfp))
  345.             goto bdchr;
  346.         else {
  347.             fofg = false;
  348.             goto extst;
  349.         }
  350.     }
  351.     else
  352.     if (*ptr == ' ') {            /* Hit a Spaceband    */
  353.         if (ptr > current_char) {    /* get prev. char pter    */
  354.           ewp = ptr-1;            /* in 2nd partition    */
  355.           while (ewp > current_char && tagc(*(ewp-1))) {
  356.             if (ptagc(*(ewp-1))) {
  357.                 --ewp;
  358.                 break;
  359.             }
  360.             else    ewp -= 2;
  361.           }
  362.           if (ewp < current_char)
  363.             goto prvbf;
  364.         }
  365.         else
  366. prvbf:          ewp = prvp3(free_start-1);    /* or 1st partition    */
  367.         if (*ewp == ' ') {
  368.             cpabt = 3;        /* double Spaces !    */
  369.             goto abort;
  370.         }
  371.         cw = cwfrw(spbval,0);
  372.         if (cksll(cw)) {
  373. sllen:            cpabt = 4;        /* short LineLen !    */
  374.             goto abort;
  375.         }
  376.         if (sflg == 2) {
  377.             sp_lts = 1;
  378.             goto mkbrk;
  379.         }
  380.     }
  381.     else {
  382.       if (ptr > current_char)        /* get prev. char pter    */
  383.         scc = prvp2(ptr-1);        /* for Kerning & CComp    */
  384.       else    scc = prvp1(free_start-1);
  385.       if (*ptr == sHY) {            /* Hit a Soft Hyphen    */
  386.         cw = cwffp(HYfp);
  387.         if (cp.kernmd)
  388.             kerning(HYfp,scc,&cw);
  389.         ++cct;
  390.       }
  391.       else
  392.       if (!allend(*ptr)) {            /* not a line ending...    */
  393.         fafg = gfpfa(&ccfp,ptr);
  394.         if (ccfp == 255) {
  395. bdchr:            cpabt = 1;        /* not valid char !    */
  396.             goto abort;
  397.         }
  398.         if (fafg && cpch(scc) && gfpfa(&fnd,scc)) {
  399.             cpabt = 2;
  400.             goto abort;        /* double Float Accent!    */
  401.         }
  402.         if (!fafg) {
  403.             ckcomp(scc);
  404.             if ((cw = cwffp(ccfp)) == -1)
  405.                 goto bdchr;
  406.             if (cp.kernmd)
  407.                 kerning(ccfp,scc,&cw);
  408.             if (cksll(cw))
  409.                 goto sllen;
  410.             ++cct;
  411.         }
  412.       }
  413.     }
  414. exchk:    if (advll(cw,ptr)) {            /* reach or in OVerSet    */
  415. #if    DEBUG == 1
  416.     printf("\nIn OVS cw=%d ptr=%lx c=%c",cw,ptr,*ptr);
  417. #endif
  418.         if (!inovs) inovs = true;
  419.         if (buf_ptr[OVSP] == 0L) {        /* save 1st OVS ptr  */
  420.             buf_ptr[OVSP] = ptr;
  421.             if (*ptr == ' ' && cp.jstmd != AJ) {
  422.                 buf_ptr[PRFP] = ptr;
  423.                 ++buf_ptr[OVSP];
  424.                 goto exfct;
  425.             }
  426.         }
  427.         if (*ptr == sHY && *(ptr+1) == srt)    /* skip sHY + srt... */
  428.             goto exfct;
  429.         if (clen >= 0x8000 && clen <= 0xac78)    /* too OVS force brk */
  430.             goto mkbrk;
  431.         if (*ptr != ' ' && !allend(*ptr))    /* non line break... */
  432.             goto extst;
  433. mkbrk:        if (!nofsp()) {            /* OK... Justify line    */
  434. #if    DEBUG == 1
  435.   printf("\nB in0: sp_lts=%d bp[PP]?=%d bp[PS]?=%d bp[NP]?=%d",
  436.     sp_lts,(buf_ptr[PRFP] != 0),(buf_ptr[PRFS] != 0),(buf_ptr[NLTP] != 0));
  437.   printf("\nB in1: sflg=%d inovs=%d bp[OV]=%lx *bp[OV]=%c clen=%d cct=%d",
  438.     sflg,inovs,buf_ptr[OVSP],(buf_ptr[OVSP] != 0) ? *buf_ptr[OVSP]:0,
  439.     clen,cct);
  440. #endif
  441.           inovs    = rshypn = 0;
  442.           hymd    = hycnt  = 0;
  443.           nobrk = 0;
  444.           CPrewindow(scc = ptr);
  445.           if (sp_lts)
  446.             setbptr(OVSP);
  447.           else    clen += cw;
  448.           if (buf_ptr[PRFS])
  449.             goto rmovs;
  450. rebrk:          hyp = free_start-1;
  451.           while (hyp > buf_start && !wbrk(hyp))
  452.             hyp = prvp1(hyp) - 1;
  453.           if (hyp < buf_start)
  454.             hyp = buf_start;
  455.           cc = getLch(hyp);
  456.           if (cc == ' ')
  457.             ++hyp;
  458.           else
  459.           if (cc == cr && getLch(hyp-1) == ' ')
  460.             hyp += 2;
  461.           else {
  462.             nobrk = 1;
  463.             if (allend(cc))
  464.                 hyp += 3;
  465.             else
  466.             if (cc == cr)
  467.                 hyp += 2;
  468.             else
  469.             if (cc == lf)
  470.                 ++hyp;
  471.           }
  472.           if (hypn >= cp.nsuchyp || *hyp == DH)
  473.             goto rmovs;
  474.           CPrewindow(ptr+1);        /* should be OK...    */
  475.           hypchk(hyp,ewp=free_start-1);    /* find HY break pts    */
  476.           hymd    = HY_TYPE;
  477.           hycnt = hyph_index;
  478. #if    DEBUG == 1
  479.     hp1 = hyp; hp2 = ewp;
  480.     for (bfp = hbf;hp1 <= hp2;*bfp++ = *hp1++);
  481.     *bfp = 0;
  482.     printf("\nword=%s hycnt=%d hymd=%d *h1=%c succ=%d nobrk=%d",
  483.         hbf,hycnt,hymd,hycnt ? *hyptr[0]:0x7e,hypn,nobrk);
  484. #endif
  485.           CPrewindow(ewp);        /* should be OK...    */
  486. rmovs:          ptr = free_start-1;        /* back out OVS range    */
  487. #if    DEBUG == 1
  488.     printf("\nBf rmovs.. hyp=%lx *hyp=%c bp[OV]=%lx *bp[OV]=%c",
  489.         ptr,*ptr,buf_ptr[OVSP],*buf_ptr[OVSP]);
  490. #endif
  491.           while (!cpabt && ptr >= buf_ptr[OVSP])
  492.             ptr = bwdct(ptr);
  493.           if (cpabt)
  494.             goto abort;
  495.           hyp = ptr;
  496. #if    DEBUG == 1
  497.     printf("\nAf rmovs.. hyp=%lx *hyp=%c bp[OV]=%lx *bp[OV]=%c",
  498.         hyp,*hyp,buf_ptr[OVSP],*buf_ptr[OVSP]);
  499. #endif
  500.           if (buf_ptr[PRFS]) {        /* space in Pref range    */
  501.             while (!cpabt && ptr > buf_ptr[PRFS])
  502.             ptr = bwdct(ptr);
  503.             if (cpabt)
  504.             goto abort;
  505. #if    DEBUG == 1
  506.     printf("\nSp Pref... ptr=%lx *ptr=%c cc=%lx *cc=%c",
  507.         ptr,*ptr,current_char,*current_char);
  508. #endif
  509. brksp:            if (getLch(ptr) == lf) --ptr;
  510.             CPrewindow(ptr);
  511.             ptr = current_char;
  512.             if (*ptr == ' ') {
  513.             CPrewindow(ptr+1);
  514.             --free_start;
  515.             }
  516.             else
  517.             if (*ptr == cr && getLch(free_start-1) == ' ')
  518.             --free_start;
  519.             else {
  520.             cpabt = 5;        /* no line break !    */
  521.             goto Equit;
  522.             }
  523.             --lspc;
  524.             clen += cwfrw(spbval,0);
  525.             if (hypn) rshypn = 1;
  526.           }
  527.           else
  528.           if (!hycnt || (!hymd && !cp.hypmd)) {    /* no HYphenation... */
  529.             if (sp_lts) {        /* space in -Lts range    */
  530. ltssp:            scc = ++current_char;
  531.             CPrewindow(scc);
  532.             cw = 0;
  533.             if (hypn) rshypn = 1;
  534.             }
  535.             else {
  536. nohyp:            if (*(ptr+1) == lf) ++ptr;
  537.             CPrewindow(ptr+1);
  538.             if (!nobrk) {        /* space in Just range    */
  539.               ptr = free_start-1;
  540.               while (!cpabt && ptr > buf_start && !wbrk(ptr))
  541.                 ptr = bwdct(ptr);
  542. #if    DEBUG == 1
  543.     printf("\nSp Just... ptr=%lx *ptr=%c cc=%lx *cc=%c",
  544.         ptr,*ptr,current_char,*current_char);
  545. #endif
  546.               if (cpabt)
  547.                 goto abort;
  548.               else    goto brksp;
  549.             }
  550.             if (nobrk    == 2        ||
  551.                 free_start    == buf_start    ||
  552.                 cct        < 2) {
  553.                 cpabt = 4;    /* short linelen !    */
  554.                 goto Equit;
  555.             }
  556. #if    DEBUG == 1
  557.     printf("\nDesperate HY..");
  558. #endif
  559.             hyp    = free_start-1;    /* where to rewind...    */
  560.             ptr    = prvp3(hyp);
  561.             if (ptr > buf_start) {    /* set desperate HY pts    */
  562.                 hyptr[1]= ptr;
  563.                 hyptr[0]= prvp3(--ptr);
  564.                 hycnt    = 2;
  565.             }
  566.             else {
  567.                 hyptr[0]= ptr;
  568.                 hycnt    = 1;
  569.             }
  570.             hymd    = 0;
  571.             nobrk    = 2;
  572.             goto brkhy;
  573.             }
  574.           }
  575.           else {
  576.             while (hycnt && (hyptr[hycnt-1]-1) > hyp)
  577.             --hycnt;
  578. #if    DEBUG == 1
  579.     printf("\nB-0 hycnt=%d hyp=%lx *hyp=%c *hyptr[hycnt-1]=%c",
  580.         hycnt,hyp,*hyp,hycnt ? *hyptr[hycnt-1]:0x7e);
  581. #endif
  582.             if (!hycnt)
  583.             goto nohyp;
  584.             if (cp.jstmd == AJ) {
  585.             if (!buf_ptr[NLTP] || buf_ptr[NLTP] > hyp)
  586.                 buf_ptr[NLTP] = hyp;
  587.             fnd = 0;
  588.             if (!buf_ptr[PRFP])
  589.                 goto nltshy;
  590.             for (i = 0;!fnd && i < hycnt;++i)
  591.             if (hyptr[i] >= buf_ptr[PRFP] &&
  592.                 hyptr[i] < buf_ptr[NLTP])
  593.                 fnd = 1;
  594.             if (fnd)
  595.                 hycnt = i;
  596.             else {
  597. nltshy:              for (i = 0;!fnd && i < hycnt;++i)
  598.               if (hyptr[i] >= buf_ptr[NLTP] &&
  599.                   hyptr[i] <= hyp)
  600.                 fnd = 1;
  601.               if (fnd)
  602.                 hycnt = i;
  603.               else
  604.               if (sp_lts)
  605.                 goto ltssp;
  606.             }
  607.             }
  608. brkhy:            for (;;) {
  609. #if    DEBUG == 1
  610.     printf("\nB-1 hycnt=%d *hyp=%c *hyptr[hycnt-1]=%c",
  611.         hycnt,*hyp,hycnt ? *hyptr[hycnt-1]:0x7e);
  612. #endif
  613.             while (!cpabt && hyp >= hyptr[hycnt-1])
  614.                 hyp = bwdct(hyp);
  615.             ptr = hyp;
  616.             if (cpabt)
  617.                 goto abort;
  618.             if (!(hymd & 3)) {
  619.               hyw = cwffp(HYfp);
  620.               if (cp.kernmd)
  621.                 kerning(HYfp,prvp1(hyp),&hyw);
  622.               clen -= hyw;
  623.             }
  624.             findst();
  625. #if    DEBUG == 1
  626.     printf("\nB-2 sflg=%d inovs=%d clen=%d cct=%d lspc=%d *hyp=%c",
  627.         sflg,inovs,clen,cct,lspc,*hyp);
  628. #endif
  629.             if (!inovs) {
  630.               CPrewindow(hyp+1);        /* should be OK...   */
  631.               ewp = prvp1(free_start-1);
  632.               if (hymd & 3) {        /* Hard - or M-,N-.. */
  633.                 if (setp.hylg == 5 &&
  634.                 *ewp == '-') {        /* Portuguese Hard - */
  635.                 CPrewindow(ewp);    /* bring Hard - down */
  636.                 goto inshy;        /* & insert Soft -.. */
  637.                 }
  638.                 else {
  639.                 ishy = 0;
  640.                 rshypn = 1;
  641.                 }
  642.               }
  643.               else
  644.               if (*ewp == DH) {        /* Disc hyphen found */
  645.                 ishy = 1;
  646.                 *ewp = sDH;
  647.                 clen += hyw;
  648.               }
  649.               else {            /* place Soft hyphen */
  650. inshy:                ishy = 1;
  651.                 *free_start++ = sHY;
  652.               }
  653.               if (ishy) {
  654.                 ++hypn;
  655.                 rshypn = 0;
  656.               }
  657.               break;
  658.             }
  659.             else
  660.             if (!(hymd & 3))
  661.                 clen += hyw;
  662.             if (!--hycnt) goto nohyp;
  663.             }
  664.           }
  665.           *free_start++ = srt;            /* insert srt/cr/lf  */
  666.           ckcrlf();
  667. #if    DEBUG == 1
  668.     printf("\nEnd B.. cct=%d\n",cct);
  669. #endif
  670.           if (rshypn) hypn = 0;
  671.           if (advdp()) {            /* down line space   */
  672.             cpabt = -1;            /* reach depth stop  */
  673.             goto Equit;
  674.           }
  675.           ptr        = current_char;
  676.           buf_ptr[CPBK] = scc;
  677.           movtotag(&ptr,CPBK);
  678.           if (cpabt)
  679.             goto Equit;
  680.           CPrewindow(buf_ptr[CPBK]);
  681.           if (inovs) {
  682.             scc    = current_char;
  683.             hymd    = hycnt    = 0;
  684.             rshypn    = sp_lts= 0;
  685.             nobrk    = 0;
  686. #if    DEBUG == 1
  687.     printf("\nStill OVS..Rebreak.. inovs=%d\n",inovs);
  688. #endif
  689.             goto rebrk;
  690.           }
  691.           if (!sp_lts) {
  692.             *nptr    = current_char;
  693.             if (nofa(ptr = *nptr,&ccfp))
  694.                 ++cct;
  695.             goto exchk;
  696.           }
  697.           else    *nptr    = current_char-1;
  698.         }
  699.         else {
  700.             clen += cw;
  701.             cpabt = 6;        /* text buffer full !    */
  702. abort:            if (getLch(ptr) == lf) ++ptr;
  703.             CPrewindow(ptr);
  704. Equit:            *nptr = current_char;
  705.         }
  706.     }
  707.     else
  708.     if (*ptr == ' ')
  709.         ++lspc;
  710.     else
  711. extst:    if (ptagc(*ptr))            /* Hit a PI    TAG    */
  712.         ptr = ++*nptr;
  713. exfct:
  714. #if    DEBUG == 1
  715.   printf("\nFwct sflg=%d inovs=%d clen=%d cw=%d lspc=%d cct=%d ptr=%lx c=%c",
  716.         sflg,inovs,clen,cw,lspc,cct,ptr,*ptr);
  717. #endif
  718.     return(cpabt);                /* return CP state...    */
  719. }
  720.  
  721. /*
  722.     Function to do backward counting on the character at pointer
  723. */
  724. unsigned char *bwdct(ptr)
  725. unsigned char *ptr;
  726. {
  727.     unsigned    cw;
  728.     unsigned char    ccfp, *pc, *pcp;
  729.  
  730. /*    cpabt = 0;*/
  731.     pc = prvp1(ptr);
  732.     if (*pc == STAG)            /* Hit a Start    TAG    */
  733.         out_tag(*ptr,1,0);
  734.     else
  735.     if (*pc == ETAG)            /* Hit an End    TAG    */
  736.         in_tag(*ptr,1,0);
  737.     else
  738.     if (ptagc(*pc)) {            /* Hit a PI    TAG    */
  739.         ptr = pc;
  740.         pcp = prvp1(pc-1);
  741.         goto nch;
  742.     }
  743.     else
  744.     if (allend(*ptr))
  745.         cpabt = 5;
  746.     else
  747.     if (!nocp(*ptr)) {
  748.       pcp = prvp1(pc-1);
  749.       if (*ptr == sHY) {
  750.         ckcomp(pcp);
  751.         cw = cwffp(HYfp);
  752.         if (cp.kernmd)
  753.             kerning(HYfp,pcp,&cw);
  754.         if (cct) --cct;
  755.       }
  756.       else
  757.       if (*ptr == ' ') {
  758.         cw = cwfrw(spbval,0);
  759.         if (lspc) --lspc;
  760.       }
  761.       else
  762. nch:      if (!gfpfa(&ccfp,ptr)) {
  763.         ckcomp(pcp);
  764.         cw = cwffp(ccfp);
  765.         if (cp.kernmd)
  766.             kerning(ccfp,pcp,&cw);
  767.         if (cct) --cct;
  768.       }
  769.       else    cw = 0;
  770.       clen    += cw;
  771.     }
  772. #if    DEBUG == 1
  773.     printf("\nBwct sflg=%d inovs=%d clen=%d cw=%d lspc=%d cct=%d p=%lx c=%c",
  774.         sflg,inovs,clen,cw,lspc,cct,ptr,*ptr);
  775. #endif
  776.     return(--pc >= buf_start ? pc : buf_start);
  777. }
  778.  
  779. wbrk(ccp)
  780. unsigned char    *ccp;
  781. {
  782.     unsigned char    pc, cc = getLch(ccp);
  783.     return(    (cc == ' ')    ||
  784.         (cc == cr    &&
  785.         ((pc = getLch(ccp-1)) == ' ' || allend(pc))) );
  786. }
  787.  
  788. cpch(ptr)
  789. unsigned char    *ptr;
  790. {
  791.     unsigned char    ch = *ptr;
  792.     return( ptagc    (ch)    ||        /* is  a PI TAG or    */
  793.         (!ctagc    (ch)    &&        /* [not a TAG marker    */
  794.         ch    != ' '    &&        /* not a spaceband    */
  795.         !nocp    (ch)    &&        /* is  a comp. char    */
  796.         !allend    (ch)) );        /* not a line ending]    */
  797. }
  798.  
  799. nofa(ptr,cfp)
  800. unsigned char    *ptr, *cfp;
  801. {
  802.     return(cpch(ptr) && !gfpfa(cfp,ptr));
  803. }
  804.  
  805. kerning(rfp,lptr,valp)
  806. unsigned char    rfp, *lptr;        /* rfp:right fp, lptr -> left c    */
  807. int        *valp;            /* valp -> value to (-) kerning */
  808. {
  809.     int        kv;
  810.     unsigned char    lfp;
  811.  
  812.     if (nofa(lptr,&lfp)) {            /* check left char...    */
  813.         getkerval(lfp,0);
  814.         getkerval(rfp,1);
  815.         kv = cmpknval();
  816.         if (kv >= *valp)
  817.             *valp = 0;
  818.         else    *valp -= kv;
  819.     }
  820. }
  821.  
  822. ckcomp(lcp)
  823. unsigned char    *lcp;
  824. {
  825.     int    tst;
  826.  
  827.     if (!cp.mcomp && !cp.acomp)
  828.         return;
  829.     tst = cpch(lcp);
  830.     if (cp.mcomp)
  831.         cmpval = tst ? cp.mcomp:0;
  832.     if (cp.acomp)
  833.         avcval = tst ? acmp:0;
  834. }
  835.  
  836. gfpfa(fp,cp)
  837. unsigned char    *fp, *cp;
  838. {
  839.     if (ptagc(*cp))
  840.         *fp = *(++cp);
  841.     else    *fp = getfp(*cp);
  842.     if (*fp != 255)
  843.         return(getfd(50,*fp) & Fac);
  844.     else    return(0);
  845. }
  846.  
  847. ckcrlf()
  848. {
  849.     if (*current_char != cr) {
  850.         addcrlf();
  851.         CPrewindow(current_char);
  852.     }
  853.     else    CPrewindow(current_char + 2);
  854. }
  855.  
  856. /*
  857.     Function to test text buffer limit. Returns true/false
  858. */
  859. nofsp()
  860. {
  861.     return(free_start >= current_char - MIN_LEFT);
  862. }
  863.  
  864. /*
  865.     Function to intialize all composition parameters for Fend.
  866. */
  867. initfcmp()
  868. {
  869.     cdep    = cp.lnsp;            /* set start depth    */
  870.     clen    = cp.llen;            /* set LineLen counter    */
  871.     smsz    = cp.ssiz;            /* set smallest SetSize    */
  872.     spbval    = cp.minsp + cp.prfsp;        /* set space value    */
  873.     HYfp    = getfp('-');
  874.     cmpval    = avcval = 0;
  875.     ckfont(cp.font);            /* set startup font    */
  876.     sflg    = inovs = false;
  877.     lspc    = cct    = 0;
  878.     zerocpptrs();
  879. }
  880.  
  881. unsigned char    *prvp1(ptr)
  882. unsigned char    *ptr;
  883. {
  884.     if (ptr > buf_start && tagc(*(ptr-1)))
  885.         --ptr;
  886.     return(ptr);
  887. }
  888.  
  889. unsigned char    *prvp2(ptr)
  890. unsigned char    *ptr;
  891. {
  892.     if (ptr > current_char && tagc(*(ptr-1)))
  893.         --ptr;
  894.     return(ptr);
  895. }
  896.  
  897. static
  898. unsigned char    *prvp3(ptr)
  899. unsigned char    *ptr;
  900. {
  901.     while (ptr > buf_start && tagc(*(ptr-1))) {
  902.         if (ptagc(*(ptr-1))) {
  903.             --ptr;
  904.             break;
  905.         }
  906.         else    ptr -= 2;
  907.     }
  908.     if (ptr < buf_start)
  909.         ptr = buf_start;
  910.     return(ptr);
  911. }
  912.  
  913. unsigned char    getLch(ptr)
  914. unsigned char    *ptr;
  915. {
  916.     ptr = prvp1(ptr);
  917.     return(*ptr);
  918. }
  919.