Make rio and libframe play nicer with fonts with fractional alpha channels, by always using stringbg and not string. Using plain string will redraw the text on top of what is already there. If the text is partially transparent, the underlying text bleeds through. Since rio grays out text in non-foreground windows, using plain string results in text getting darker and darker as you switch between text windows. This attempt certainly fixes bugs present in previous attempts involving selected text and losing the tick. I have tested it quite a bit and believe it has a good chance of being correct. Reference: /n/sources/patch/applied/alphafont Date: Wed Nov 28 00:51:14 CET 2007 Signed-off-by: rsc@swtch.com --- /sys/include/frame.h Wed Nov 28 00:48:13 2007 +++ /sys/include/frame.h Wed Nov 28 00:48:13 2007 @@ -58,7 +58,7 @@ void frselect(Frame*, Mousectl*); void frselectpaint(Frame*, Point, Point, Image*); void frdrawsel(Frame*, Point, ulong, ulong, int); -void frdrawsel0(Frame*, Point, ulong, ulong, Image*, Image*); +Point frdrawsel0(Frame*, Point, ulong, ulong, Image*, Image*); void frinit(Frame*, Rectangle, Font*, Image*, Image**); void frsetrects(Frame*, Rectangle, Image*); void frclear(Frame*, int); @@ -80,13 +80,14 @@ int _frnewwid(Frame*, Point, Frbox*); int _frnewwid0(Frame*, Point, Frbox*); void _frclean(Frame*, Point, int, int); -void _frredraw(Frame*, Point, Image*, Image*); +void _frdrawtext(Frame*, Point, Image*, Image*); void _fraddbox(Frame*, int, int); Point _frptofcharptb(Frame*, ulong, Point, int); Point _frptofcharnb(Frame*, ulong, int); int _frstrlen(Frame*, int); void frtick(Frame*, Point, int); void frinittick(Frame*); +void frredraw(Frame*); #define NRUNE(b) ((b)->nrune<0? 1 : (b)->nrune) #define NBYTE(b) strlen((char*)(b)->ptr) --- /sys/src/libframe/frinsert.c Wed Nov 28 00:48:14 2007 +++ /sys/src/libframe/frinsert.c Wed Nov 28 00:48:14 2007 @@ -262,7 +262,7 @@ else col = f->cols[BACK]; frselectpaint(f, ppt0, ppt1, col); - _frredraw(&frame, ppt0, f->cols[TEXT], col); + _frdrawtext(&frame, ppt0, f->cols[TEXT], col); _fraddbox(f, nn0, frame.nbox); for(n=0; nbox[nn0+n] = frame.box[n]; --- /sys/src/libframe/frdraw.c Wed Nov 28 00:48:14 2007 +++ /sys/src/libframe/frdraw.c Wed Nov 28 00:48:14 2007 @@ -6,7 +6,7 @@ #include void -_frredraw(Frame *f, Point pt, Image *text, Image *back) +_frdrawtext(Frame *f, Point pt, Image *text, Image *back) { Frbox *b; int nb; @@ -15,7 +15,7 @@ for(nb=0,b=f->box; nbnbox; nb++, b++){ _frcklinewrap(f, &pt, b); if(b->nrune >= 0){ - stringbg(f->b, pt, text, ZP, f->font, (char *)b->ptr, back, ZP); + stringbg(f->b, pt, text, ZP, f->font, (char*)b->ptr, back, ZP); } pt.x += b->wid; } @@ -57,7 +57,7 @@ frdrawsel0(f, pt, p0, p1, back, text); } -void +Point frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *text) { Frbox *b; @@ -78,7 +78,7 @@ if(p >= p0){ qt = pt; _frcklinewrap(f, &pt, b); - // fill in the end of a wrapped line + /* fill in the end of a wrapped line */ if(pt.y > qt.y) draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt); } @@ -115,6 +115,29 @@ if(pt.y > qt.y) draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt); } + return pt; +} + +void +frredraw(Frame *f) +{ + int ticked; + Point pt; + + if(f->p0 == f->p1){ + ticked = f->ticked; + if(ticked) + frtick(f, frptofchar(f, f->p0), 0); + frdrawsel0(f, frptofchar(f, 0), 0, f->nchars, f->cols[BACK], f->cols[TEXT]); + if(ticked) + frtick(f, frptofchar(f, f->p0), 1); + return; + } + + pt = frptofchar(f, 0); + pt = frdrawsel0(f, pt, 0, f->p0, f->cols[BACK], f->cols[TEXT]); + pt = frdrawsel0(f, pt, f->p0, f->p1, f->cols[HIGH], f->cols[HTEXT]); + pt = frdrawsel0(f, pt, f->p1, f->nchars, f->cols[BACK], f->cols[TEXT]); } void --- /sys/src/cmd/rio/wind.c Wed Nov 28 00:48:15 2007 +++ /sys/src/cmd/rio/wind.c Wed Nov 28 00:48:15 2007 @@ -710,7 +710,7 @@ { wsetcols(w); if(!w->mouseopen) - _frredraw(w, w->Frame.r.min, w->cols[TEXT], nil); + frredraw(w); if(w == input){ wborder(w, Selborder); wsetcursor(w, 0);