Annotation of researchv9/jerq/src/sam/term/frinsert.c, revision 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.