URI:
       tfrdraw.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
       ---
       tfrdraw.c (4225B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <mouse.h>
            5 #include <frame.h>
            6 
            7 void
            8 _frdrawtext(Frame *f, Point pt, Image *text, Image *back)
            9 {
           10         Frbox *b;
           11         int nb;
           12 
           13         for(nb=0,b=f->box; nb<f->nbox; nb++, b++){
           14                 _frcklinewrap(f, &pt, b);
           15                 if(!f->noredraw && b->nrune >= 0)
           16                         stringbg(f->b, pt, text, ZP, f->font, (char*)b->ptr, back, ZP);
           17                 pt.x += b->wid;
           18         }
           19 }
           20 
           21 static int
           22 nbytes(char *s0, int nr)
           23 {
           24         char *s;
           25         Rune r;
           26 
           27         s = s0;
           28         while(--nr >= 0)
           29                 s += chartorune(&r, s);
           30         return s-s0;
           31 }
           32 
           33 void
           34 frdrawsel(Frame *f, Point pt, ulong p0, ulong p1, int issel)
           35 {
           36         Image *back, *text;
           37 
           38         if(f->ticked)
           39                 frtick(f, frptofchar(f, f->p0), 0);
           40 
           41         if(p0 == p1){
           42                 frtick(f, pt, issel);
           43                 return;
           44         }
           45 
           46         if(issel){
           47                 back = f->cols[HIGH];
           48                 text = f->cols[HTEXT];
           49         }else{
           50                 back = f->cols[BACK];
           51                 text = f->cols[TEXT];
           52         }
           53 
           54         frdrawsel0(f, pt, p0, p1, back, text);
           55 }
           56 
           57 Point
           58 frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *text)
           59 {
           60         Frbox *b;
           61         int nb, nr, w, x, trim;
           62         Point qt;
           63         uint p;
           64         char *ptr;
           65 
           66         if(p0 > p1)
           67                 sysfatal("libframe: frdrawsel0 p0=%lud > p1=%lud", p0, p1);
           68 
           69         p = 0;
           70         b = f->box;
           71         trim = 0;
           72         for(nb=0; nb<f->nbox && p<p1; nb++){
           73                 nr = b->nrune;
           74                 if(nr < 0)
           75                         nr = 1;
           76                 if(p+nr <= p0)
           77                         goto Continue;
           78                 if(p >= p0){
           79                         qt = pt;
           80                         _frcklinewrap(f, &pt, b);
           81                         /* fill in the end of a wrapped line */
           82                         if(pt.y > qt.y)
           83                                 draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt);
           84                 }
           85                 ptr = (char*)b->ptr;
           86                 if(p < p0){        /* beginning of region: advance into box */
           87                         ptr += nbytes(ptr, p0-p);
           88                         nr -= (p0-p);
           89                         p = p0;
           90                 }
           91                 trim = 0;
           92                 if(p+nr > p1){        /* end of region: trim box */
           93                         nr -= (p+nr)-p1;
           94                         trim = 1;
           95                 }
           96                 if(b->nrune<0 || nr==b->nrune)
           97                         w = b->wid;
           98                 else
           99                         w = stringnwidth(f->font, ptr, nr);
          100                 x = pt.x+w;
          101                 if(x > f->r.max.x)
          102                         x = f->r.max.x;
          103                 draw(f->b, Rect(pt.x, pt.y, x, pt.y+f->font->height), back, nil, pt);
          104                 if(b->nrune >= 0)
          105                         stringnbg(f->b, pt, text, ZP, f->font, ptr, nr, back, ZP);
          106                 pt.x += w;
          107             Continue:
          108                 b++;
          109                 p += nr;
          110         }
          111         /* if this is end of last plain text box on wrapped line, fill to end of line */
          112         if(p1>p0 &&  b>f->box && b<f->box+f->nbox && b[-1].nrune>0 && !trim){
          113                 qt = pt;
          114                 _frcklinewrap(f, &pt, b);
          115                 if(pt.y > qt.y)
          116                         draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt);
          117         }
          118         return pt;
          119 }
          120 
          121 void
          122 frredraw(Frame *f)
          123 {
          124         int ticked;
          125         Point pt;
          126 
          127         if(f->p0 == f->p1){
          128                 ticked = f->ticked;
          129                 if(ticked)
          130                         frtick(f, frptofchar(f, f->p0), 0);
          131                 frdrawsel0(f, frptofchar(f, 0), 0, f->nchars, f->cols[BACK], f->cols[TEXT]);
          132                 if(ticked)
          133                         frtick(f, frptofchar(f, f->p0), 1);
          134                 return;
          135         }
          136 
          137         pt = frptofchar(f, 0);
          138         pt = frdrawsel0(f, pt, 0, f->p0, f->cols[BACK], f->cols[TEXT]);
          139         pt = frdrawsel0(f, pt, f->p0, f->p1, f->cols[HIGH], f->cols[HTEXT]);
          140         pt = frdrawsel0(f, pt, f->p1, f->nchars, f->cols[BACK], f->cols[TEXT]);
          141 }
          142 
          143 static void
          144 _frtick(Frame *f, Point pt, int ticked)
          145 {
          146         Rectangle r;
          147 
          148         if(f->ticked==ticked || f->tick==0 || !ptinrect(pt, f->r))
          149                 return;
          150         pt.x -= f->tickscale;        /* looks best just left of where requested */
          151         r = Rect(pt.x, pt.y, pt.x+FRTICKW*f->tickscale, pt.y+f->font->height);
          152         /* can go into left border but not right */
          153         if(r.max.x > f->r.max.x)
          154                 r.max.x = f->r.max.x;
          155         if(ticked){
          156                 draw(f->tickback, f->tickback->r, f->b, nil, pt);
          157                 draw(f->b, r, f->tick, nil, ZP);
          158         }else
          159                 draw(f->b, r, f->tickback, nil, ZP);
          160         f->ticked = ticked;
          161 }
          162 
          163 void
          164 frtick(Frame *f, Point pt, int ticked)
          165 {
          166         if(f->tickscale != scalesize(f->display, 1)) {
          167                 if(f->ticked)
          168                         _frtick(f, pt, 0);
          169                 frinittick(f);
          170         }
          171         _frtick(f, pt, ticked);
          172 }
          173 
          174 Point
          175 _frdraw(Frame *f, Point pt)
          176 {
          177         Frbox *b;
          178         int nb, n;
          179 
          180         for(b=f->box,nb=0; nb<f->nbox; nb++, b++){
          181                 _frcklinewrap0(f, &pt, b);
          182                 if(pt.y == f->r.max.y){
          183                         f->nchars -= _frstrlen(f, nb);
          184                         _frdelbox(f, nb, f->nbox-1);
          185                         break;
          186                 }
          187                 if(b->nrune > 0){
          188                         n = _frcanfit(f, pt, b);
          189                         if(n == 0)
          190                                 break;
          191                         if(n != b->nrune){
          192                                 _frsplitbox(f, nb, n);
          193                                 b = &f->box[nb];
          194                         }
          195                         pt.x += b->wid;
          196                 }else{
          197                         if(b->bc == '\n'){
          198                                 pt.x = f->r.min.x;
          199                                 pt.y+=f->font->height;
          200                         }else
          201                                 pt.x += _frnewwid(f, pt, b);
          202                 }
          203         }
          204         return pt;
          205 }
          206 
          207 int
          208 _frstrlen(Frame *f, int nb)
          209 {
          210         int n;
          211 
          212         for(n=0; nb<f->nbox; nb++)
          213                 n += NRUNE(&f->box[nb]);
          214         return n;
          215 }