URI:
       tfrbox.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tfrbox.c (3008B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <mouse.h>
            5 #include <frame.h>
            6 
            7 #define        SLOP        25
            8 
            9 void
           10 _fraddbox(Frame *f, int bn, int n)        /* add n boxes after bn, shift the rest up,
           11                                  * box[bn+n]==box[bn] */
           12 {
           13         int i;
           14 
           15         if(bn > f->nbox)
           16                 drawerror(f->display, "_fraddbox");
           17         if(f->nbox+n > f->nalloc)
           18                 _frgrowbox(f, n+SLOP);
           19         for(i=f->nbox; --i>=bn; )
           20                 f->box[i+n] = f->box[i];
           21         f->nbox+=n;
           22 }
           23 
           24 void
           25 _frclosebox(Frame *f, int n0, int n1)        /* inclusive */
           26 {
           27         int i;
           28 
           29         if(n0>=f->nbox || n1>=f->nbox || n1<n0)
           30                 drawerror(f->display, "_frclosebox");
           31         n1++;
           32         for(i=n1; i<f->nbox; i++)
           33                 f->box[i-(n1-n0)] = f->box[i];
           34         f->nbox -= n1-n0;
           35 }
           36 
           37 void
           38 _frdelbox(Frame *f, int n0, int n1)        /* inclusive */
           39 {
           40         if(n0>=f->nbox || n1>=f->nbox || n1<n0)
           41                 drawerror(f->display, "_frdelbox");
           42         _frfreebox(f, n0, n1);
           43         _frclosebox(f, n0, n1);
           44 }
           45 
           46 void
           47 _frfreebox(Frame *f, int n0, int n1)        /* inclusive */
           48 {
           49         int i;
           50 
           51         if(n1<n0)
           52                 return;
           53         if(n0>=f->nbox || n1>=f->nbox)
           54                 drawerror(f->display, "_frfreebox");
           55         n1++;
           56         for(i=n0; i<n1; i++)
           57                 if(f->box[i].nrune >= 0)
           58                         free(f->box[i].ptr);
           59 }
           60 
           61 void
           62 _frgrowbox(Frame *f, int delta)
           63 {
           64         f->nalloc += delta;
           65         f->box = realloc(f->box, f->nalloc*sizeof(Frbox));
           66         if(f->box == 0)
           67                 drawerror(f->display, "_frgrowbox");
           68 }
           69 
           70 static
           71 void
           72 dupbox(Frame *f, int bn)
           73 {
           74         uchar *p;
           75 
           76         if(f->box[bn].nrune < 0)
           77                 drawerror(f->display, "dupbox");
           78         _fraddbox(f, bn, 1);
           79         if(f->box[bn].nrune >= 0){
           80                 p = _frallocstr(f, NBYTE(&f->box[bn])+1);
           81                 strcpy((char*)p, (char*)f->box[bn].ptr);
           82                 f->box[bn+1].ptr = p;
           83         }
           84 }
           85 
           86 static
           87 uchar*
           88 runeindex(uchar *p, int n)
           89 {
           90         int i, w;
           91         Rune rune;
           92 
           93         for(i=0; i<n; i++,p+=w)
           94                 if(*p < Runeself)
           95                         w = 1;
           96                 else{
           97                         w = chartorune(&rune, (char*)p);
           98                         USED(rune);
           99                 }
          100         return p;
          101 }
          102 
          103 static
          104 void
          105 truncatebox(Frame *f, Frbox *b, int n)        /* drop last n chars; no allocation done */
          106 {
          107         if(b->nrune<0 || b->nrune<n)
          108                 drawerror(f->display, "truncatebox");
          109         b->nrune -= n;
          110         runeindex(b->ptr, b->nrune)[0] = 0;
          111         b->wid = stringwidth(f->font, (char *)b->ptr);
          112 }
          113 
          114 static
          115 void
          116 chopbox(Frame *f, Frbox *b, int n)        /* drop first n chars; no allocation done */
          117 {
          118         char *p;
          119 
          120         if(b->nrune<0 || b->nrune<n)
          121                 drawerror(f->display, "chopbox");
          122         p = (char*)runeindex(b->ptr, n);
          123         memmove((char*)b->ptr, p, strlen(p)+1);
          124         b->nrune -= n;
          125         b->wid = stringwidth(f->font, (char *)b->ptr);
          126 }
          127 
          128 void
          129 _frsplitbox(Frame *f, int bn, int n)
          130 {
          131         dupbox(f, bn);
          132         truncatebox(f, &f->box[bn], f->box[bn].nrune-n);
          133         chopbox(f, &f->box[bn+1], n);
          134 }
          135 
          136 void
          137 _frmergebox(Frame *f, int bn)                /* merge bn and bn+1 */
          138 {
          139         Frbox *b;
          140 
          141         b = &f->box[bn];
          142         _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1);
          143         strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr);
          144         b[0].wid += b[1].wid;
          145         b[0].nrune += b[1].nrune;
          146         _frdelbox(f, bn+1, bn+1);
          147 }
          148 
          149 int
          150 _frfindbox(Frame *f, int bn, ulong p, ulong q)        /* find box containing q and put q on a box boundary */
          151 {
          152         Frbox *b;
          153 
          154         for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++)
          155                 p += NRUNE(b);
          156         if(p != q)
          157                 _frsplitbox(f, bn++, (int)(q-p));
          158         return bn;
          159 }