frdelete.c - sam - An updated version of the sam text editor.
 (HTM) git clone git://vernunftzentrum.de/sam.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
       frdelete.c (3129B)
       ---
            1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
            2 #include <u.h>
            3 #include <libg.h>
            4 #include <frame.h>
            5 
            6 int
            7 frdelete(Frame *f, uint64_t p0, uint64_t p1)
            8 {
            9     Point pt0, pt1, ppt0;
           10     Frbox *b;
           11     int n0, n1, n;
           12     Rectangle r;
           13     int nn0;
           14 
           15     if(p0>=f->nchars || p0==p1 || f->b==0)
           16         return 0;
           17     if(p1 > f->nchars)
           18         p1 = f->nchars;
           19     n0 = _frfindbox(f, 0, (uint64_t)0, p0);
           20     n1 = _frfindbox(f, n0, p0, p1);
           21     pt0 = _frptofcharnb(f, p0, n0);
           22     pt1 = frptofchar(f, p1);
           23     if(f->p0!=p0 || f->p1!=p1)  /* likely they ARE equal */
           24         frselectp(f, F&~D); /* can do better some day */
           25     frselectf(f, pt0, pt1, 0);
           26     if(n0 == f->nbox)
           27         berror("off end in frdelete");
           28     nn0 = n0;
           29     ppt0 = pt0;
           30     _frfreebox(f, n0, n1-1);
           31     f->modified = true;
           32 
           33     /*
           34      * Invariants:
           35      *  pt0 points to beginning, pt1 points to end
           36      *  n0 is box containing beginning of stuff being deleted
           37      *  n1, b are box containing beginning of stuff to be kept after deletion
           38      *  region between pt0 and pt1 is clear
           39      */
           40     b = &f->box[n1];
           41     while(pt1.x!=pt0.x && n1<f->nbox){
           42         _frcklinewrap0(f, &pt0, b);
           43         _frcklinewrap(f, &pt1, b);
           44         if(b->nrune > 0){
           45             n = _frcanfit(f, pt0, b);
           46             if(n==0)
           47                 berror("_frcanfit==0");
           48             if(n != b->nrune){
           49                 _frsplitbox(f, n1, n);
           50                 b = &f->box[n1];
           51             }
           52             r.min = pt1;
           53             r.max = pt1;
           54             r.max.x += b->wid;
           55             r.max.y += f->fheight;
           56             bitblt2(f->b, pt0, f->b, r, S, 0, f->bg);
           57             if(pt0.y == pt1.y)
           58                 r.min.x = r.max.x-(pt1.x-pt0.x);
           59             bitblt2(f->b, r.min, f->b, r, 0, 0, f->bg);
           60         }
           61         _fradvance(f, &pt1, b);
           62         pt0.x += _frnewwid(f, pt0, b);
           63         f->box[n0++] = f->box[n1++];
           64         b++;
           65     }
           66     if(pt1.y != pt0.y){
           67         Point pt2;
           68 
           69         pt2 = _frptofcharptb(f, 32767, pt1, n1);
           70         if(pt2.y > f->r.max.y)
           71             berror("frptofchar in frdelete");
           72         if(n1 < f->nbox){
           73             int q0, q1, q2;
           74 
           75             q0 = pt0.y+f->fheight;
           76             q1 = pt1.y+f->fheight;
           77             q2 = pt2.y+f->fheight;
           78             bitblt2(f->b, pt0, f->b, Rect(pt1.x, pt1.y, f->r.max.x, q1), S, 0, f->bg);
           79             bitblt2(f->b, Pt(f->r.min.x, q0), f->b, Rect(f->r.min.x, q1, f->r.max.x, q2), S, 0, f->bg);
           80             frselectf(f, Pt(pt2.x, pt2.y-(pt1.y-pt0.y)), pt2, 0);
           81         }else
           82             frselectf(f, pt0, pt2, 0);
           83     }
           84     _frclosebox(f, n0, n1-1);
           85     if(nn0>0 && f->box[nn0-1].nrune>=0 && ppt0.x-f->box[nn0-1].wid>=(int)f->left){
           86         --nn0;
           87         ppt0.x -= f->box[nn0].wid;
           88     }
           89     _frclean(f, ppt0, nn0, n0<f->nbox-1? n0+1 : n0);
           90     if(f->p1 > p1)
           91         f->p1 -= p1-p0;
           92     else if(f->p1 > p0)
           93         f->p1 = p0;
           94     if(f->p0 > p1)
           95         f->p0 -= p1-p0;
           96     else if(f->p0 > p0)
           97         f->p0 = p0;
           98     frselectp(f, F&~D);
           99     f->nchars -= p1-p0;
          100     pt0 = frptofchar(f, f->nchars);
          101     n = f->nlines;
          102     f->nlines = (pt0.y-f->r.min.y)/f->fheight+(pt0.x>f->left);
          103     return n - f->nlines;
          104 }