Annotation of researchv9/jerq/src/sam/term/frinsert.c, revision 1.1.1.1

1.1       root        1: #include "frame.h"
                      2: 
                      3: #define        DELTA   25
                      4: static Frame           frame;
                      5: Point
                      6: bxscan(f, sp, ppt)
                      7:        Frame *f;
                      8:        uchar **sp;
                      9:        Point *ppt;
                     10: {
                     11:        register w, c, nb;
                     12:        register uchar *p;
                     13:        register Box *b;
                     14:        register uchar *s;
                     15:        int n;
                     16:        frame.r=f->r;
                     17:        frame.b=f->b;
                     18:        frame.font=f->font;
                     19:        frame.maxcharwid=f->maxcharwid;
                     20:        frame.maxtab=f->maxtab;
                     21:        frame.left=f->left;
                     22:        frame.nbox=0;
                     23:        for(n=0, nb=0; (*sp)[n]; nb++,frame.nbox++){
                     24:                if(nb==frame.nalloc)
                     25:                        growbox(&frame, DELTA);
                     26:                s=&(*sp)[n];
                     27:                b=&frame.box[nb];
                     28:                if(*s=='\t' || *s=='\n'){
                     29:                        b->bc=*s;
                     30:                        b->wid=5000;
                     31:                        b->minwid=(*s=='\n')? 0 : frame.font->info[' '].width;
                     32:                        b->len=-1;
                     33:                        n++;
                     34:                }else{
                     35:                        for(w=0,p=s; (c=*s) && c!='\t' && c!='\n'; s++)
                     36:                                w+=frame.font->info[c].width;
                     37:                        *s=0;
                     38:                        b->ptr=allocstr((int)(s-p+1));
                     39:                        copystr(p, b->ptr);
                     40:                        *s=c;
                     41:                        b->wid=w;
                     42:                        n+=b->len=s-p;
                     43:                }
                     44:        }
                     45:        frame.nchars=n;
                     46:        b=&frame.box[0];
                     47:        cklinewrap0(f, ppt, b);
                     48:        return draw(&frame, *ppt);
                     49: }
                     50: frinsert(f, sp, p0)
                     51:        register Frame *f;
                     52:        uchar **sp;
                     53:        Posn p0;
                     54: {
                     55:        Point pt0, pt1, ppt0, ppt1, pt;
                     56:        register Box *b;
                     57:        register n, n0, nn0;
                     58:        Rectangle r;
                     59:        int y;
                     60:        static struct{
                     61:                Point pt0, pt1;
                     62:        }*pts;
                     63:        static int nalloc=0;
                     64:        int npts;
                     65:        if(p0>f->nchars || **sp==0 || f->b==0)
                     66:                return;
                     67:        nn0=n0=findbox(f, 0, 0, p0);
                     68:        ppt0=pt0=ptofcharnb(f, p0, n0);
                     69:        ppt1=pt1=bxscan(f, sp, &ppt0);
                     70:        if(n0<f->nbox){
                     71:                cklinewrap(f, &pt0, b=&f->box[n0]);     /* for selectf() */
                     72:                cklinewrap0(f, &ppt1, b);
                     73:        }
                     74:        /*
                     75:         * ppt0 and ppt1 are start and end of insertion as they will appear when
                     76:         * insertion is complete. pt0 is current location of insertion position
                     77:         * (p0); pt1 is terminal point (without line wrap) of insertion.
                     78:         */
                     79:        if(p0==f->p0 && p0==f->p1)              /* quite likely */
                     80:                selectf(f, pt0, pt0, F_XOR);
                     81:        else
                     82:                selectp(f, F_XOR);
                     83:        /*
                     84:         * Find point where old and new x's line up
                     85:         * Invariants:
                     86:         *      pt0 is where the next box (b, n0) is now
                     87:         *      pt1 is where it will be after then insertion
                     88:         * If pt1 goes off the rectangle, we can toss everything from there on
                     89:         */
                     90:        for(b=&f->box[n0],npts=0;
                     91:             pt1.x!=pt0.x && pt1.y!=f->r.corner.y && n0<f->nbox; b++,n0++,npts++){
                     92:                cklinewrap(f, &pt0, b);
                     93:                cklinewrap0(f, &pt1, b);
                     94:                if(b->len>0){
                     95:                        n=canfit(f, pt1, b);
                     96:                        if(n==0)
                     97:                                panic("canfit==0");
                     98:                        if(n!=b->len){
                     99:                                splitbox(f, n0, n);
                    100:                                b=&f->box[n0];
                    101:                        }
                    102:                }
                    103:                if(npts==nalloc){
                    104:                        gcrealloc((char **)&pts,
                    105:                                npts*sizeof(pts[0]), (npts+DELTA)*sizeof(pts[0]));
                    106:                        nalloc+=DELTA;
                    107:                        b=&f->box[n0];
                    108:                }
                    109:                pts[npts].pt0=pt0, pts[npts].pt1=pt1;
                    110:                /* has a text box overflowed off the frame? */
                    111:                if(pt1.y==f->r.corner.y)
                    112:                        break;
                    113:                advance(f, &pt0, b);
                    114:                pt1.x+=newwid(f, pt1, b);
                    115:        }
                    116:        if(pt1.y>f->r.corner.y)
                    117:                panic("frinsert pt1 too far");
                    118:        if(pt1.y==f->r.corner.y && n0<f->nbox){
                    119:                f->nchars-=frstrlen(f, n0);
                    120:                delbox(f, n0, f->nbox-1);
                    121:        }
                    122:        if(n0==f->nbox)
                    123:                f->nlines=(pt1.y-f->r.origin.y)/f->font->height+(pt1.x>f->left);
                    124:        else if(pt1.y!=pt0.y){
                    125:                int q0, q1;
                    126:                y=f->r.corner.y;
                    127:                q0=pt0.y+f->font->height, q1=pt1.y+f->font->height;
                    128:                f->nlines+=(q1-q0)/f->font->height;
                    129:                if(f->nlines>f->maxlines)
                    130:                        chopframe(f, ppt1, p0, nn0);
                    131:                if(pt1.y<y){
                    132:                        r=f->r, r.origin.y=q0, r.corner.y=y-(q1-q0);
                    133:                        if(q1<y)
                    134:                                bitblt(B, r, B, Pt(f->r.origin.x, q1), F_STORE);
                    135:                        r.origin=pt0; r.corner.y=q0;
                    136:                        bitblt(B, r, B, pt1, F_STORE);
                    137:                }
                    138:        }
                    139:        /*
                    140:         * Move the old stuff down to make room.  The loop will move the stuff
                    141:         * between the insertion and the point where the x's lined up.
                    142:         * The bitblts above moved everything down after the point they lined up.
                    143:         */
                    144:        for((y=pt1.y==f->r.corner.y?pt1.y:0),b=&f->box[n0-1]; --npts>=0; --b){
                    145:                pt=pts[npts].pt1;
                    146:                if(b->len>0){
                    147:                        r.origin=r.corner=pts[npts].pt0;
                    148:                        r.corner.x+=b->wid, r.corner.y+=f->font->height;
                    149:                        bitblt(B, r, B, pt, F_STORE);
                    150:                        if(pt.y<y){     /* clear bit hanging off right */
                    151:                                r.origin=r.corner=pt;
                    152:                                r.origin.x+=b->wid;
                    153:                                r.corner.x=f->r.corner.x;
                    154:                                r.corner.y+=f->font->height;
                    155:                                rectf(B, r, F_CLR);
                    156:                        }
                    157:                        y=pt.y;
                    158:                }else{
                    159:                        r.origin=r.corner=pt;
                    160:                        r.corner.x+=b->wid, r.corner.y+=f->font->height;
                    161:                        if(r.corner.x>=f->r.corner.x)
                    162:                                r.corner.x=f->r.corner.x;
                    163:                        rectf(B, r, F_CLR);
                    164:                        y=pt.x==f->left? pt.y : 0;
                    165:                }
                    166:        }
                    167:        selectf(f, ppt0, ppt1, F_CLR);
                    168:        redraw(&frame, ppt0);
                    169:        addbox(f, nn0, frame.nbox);
                    170:        for(n=0; n<frame.nbox; n++)
                    171:                f->box[nn0+n]=frame.box[n];
                    172:        if(nn0>0 && f->box[nn0-1].len>=0 && ppt0.x-f->box[nn0-1].wid>=(int)f->left){
                    173:                --nn0;
                    174:                ppt0.x-=f->box[nn0].wid;
                    175:        }
                    176:        n0+=frame.nbox;
                    177:        clean(f, ppt0, nn0, n0<f->nbox-1? n0+1 : n0);
                    178:        f->nchars+=frame.nchars;
                    179:        if(f->p0>=p0)
                    180:                f->p0+=frame.nchars;
                    181:        if(f->p0>f->nchars)
                    182:                f->p0=f->nchars;
                    183:        if(f->p1>=p0)
                    184:                f->p1+=frame.nchars;
                    185:        if(f->p1>f->nchars)
                    186:                f->p1=f->nchars;
                    187:        if(pt0.x!=pt1.x)
                    188:                f->lastlinefull=pt0.x==f->left;
                    189:        selectp(f, F_XOR);
                    190: }
                    191: chopframe(f, pt, p, bn)
                    192:        register Frame *f;
                    193:        Point pt;
                    194:        register Posn p;
                    195:        int bn;
                    196: {
                    197:        register Box *b;
                    198:        for(b=&f->box[bn]; ; b++){
                    199:                if(b>=&f->box[f->nbox])
                    200:                        panic("endofframe");
                    201:                cklinewrap(f, &pt, b);
                    202:                if(pt.y>=f->r.corner.y)
                    203:                        break;
                    204:                p+=LEN(b);
                    205:                advance(f, &pt, b);
                    206:        }
                    207:        f->nchars=p;
                    208:        f->nlines=f->maxlines;
                    209: if(b<&f->box[f->nbox])                         /* BUG */
                    210:        delbox(f, (int)(b-f->box), f->nbox-1);
                    211: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.