this patch fixes subpixel highlighting. it also elimintes the read from the screen's memory to draw the new text. on many new graphics cards (e.g. nvidia.) this improves draw performance. commented out are two lines that also address this problem, but they cause some flicker. the new function is somewhat large due to the fact that there are really 5 regions to draw. (1) unhighlighted boxes (2) one partially highlighted box (3) 0-n highlighted boxes (4) 0,1 partially highlighted box (may be the same box as 2) (5) 0,n unhighlighted boxes. frdrawsel0 does a similar but inverse, redrawing the background but not the text. Notes: Tue Sep 18 00:59:09 EDT 2007 geoff Tue Sep 18 01:00:08 EDT 2007 geoff deferring this at least until it's refactored, per rsc. Reference: /n/sources/patch/saved/libframe-subpixfix Date: Mon Aug 20 03:30:57 CES 2007 Signed-off-by: quanstro@quanstro.net Reviewed-by: geoff --- /sys/include/frame.h Mon Aug 20 03:15:18 2007 +++ /sys/include/frame.h Mon Aug 20 03:15:17 2007 @@ -80,7 +80,7 @@ int _frnewwid(Frame*, Point, Frbox*); int _frnewwid0(Frame*, Point, Frbox*); void _frclean(Frame*, Point, int, int); -void _frredraw(Frame*, Point, Image*, Image*); +void _frredraw(Frame*, Point, Image*, Image*, Image*); void _fraddbox(Frame*, int, int); Point _frptofcharptb(Frame*, ulong, Point, int); Point _frptofcharnb(Frame*, ulong, int); --- /sys/src/cmd/rio/wind.c Mon Aug 20 03:15:33 2007 +++ /sys/src/cmd/rio/wind.c Mon Aug 20 03:15:26 2007 @@ -709,8 +709,11 @@ wrepaint(Window *w) { wsetcols(w); - if(!w->mouseopen) - _frredraw(w, w->Frame.r.min, w->cols[TEXT], nil); + if(!w->mouseopen){ + _frredraw(w, w->Frame.r.min, w->cols[TEXT], w->cols[BACK], w->cols[HIGH]); +// _frredraw(w, w->Frame.r.min, w->cols[TEXT], w->cols[BACK]); +// frdrawsel(w, frptofchar(w, w->p0), w->p0, w->p1, 1); + } if(w == input){ wborder(w, Selborder); wsetcursor(w, 0); --- /sys/src/libframe/frinsert.c Mon Aug 20 03:15:41 2007 +++ /sys/src/libframe/frinsert.c Mon Aug 20 03:15:39 2007 @@ -262,7 +262,7 @@ else col = f->cols[BACK]; frselectpaint(f, ppt0, ppt1, col); - _frredraw(&frame, ppt0, f->cols[TEXT], col); + _frredraw(&frame, ppt0, f->cols[TEXT], col, col); _fraddbox(f, nn0, frame.nbox); for(n=0; nbox[nn0+n] = frame.box[n]; --- /sys/src/libframe/frdraw.c Mon Aug 20 03:15:51 2007 +++ /sys/src/libframe/frdraw.c Mon Aug 20 03:15:49 2007 @@ -6,7 +6,7 @@ #include void -_frredraw(Frame *f, Point pt, Image *text, Image *back) +_frredraw0(Frame *f, Point pt, Image *text, Image *back) { Frbox *b; int nb; @@ -31,6 +31,78 @@ while(--nr >= 0) s += chartorune(&r, s); return s-s0; +} + +void +_frredraw(Frame *f, Point pt, Image *text, Image *back, Image *hiback) +{ + Frbox *b; + int nb, nr, trim; + Point qt, xt; + uint p; + char *ptr; + + if(f->p0 == f->p1){ + _frredraw0(f, pt, text, back); + return; + } + + p = nr = 0; + /* draw up to the box with the selection */ + for(nb=0,b=f->box; nbnbox; nb++, b++){ + nr = NRUNE(b); + _frcklinewrap(f, &pt, b); + if(p+nr > f->p0) + break; + if(b->nrune >= 0) + stringbg(f->b, pt, text, ZP, f->font, (char *)b->ptr, back, ZP); + pt.x += b->wid; + p += nr; + } + + qt = pt; + ptr = (char*)b->ptr; + if(p < f->p0){ /* beginning of region: advance into box */ + if(b->nrune >= 0){ + stringnbg(f->b, pt, text, ZP, f->font, ptr, f->p0-p, back, ZP); + pt.x += stringnwidth(f->font, ptr, f->p0-p); + } + ptr += nbytes(ptr, f->p0-p); + nr -= (f->p0-p); + p = f->p0; + } + + for(; nbnbox && pp1; ){ + trim = 0; + if(p+nr > f->p1){ /* end of region: trim box */ + trim = (p+nr)-f->p1; + nr -= trim; + } + if(b->nrune < 0) + goto next; + xt = stringnbg(f->b, pt, text, ZP, f->font, ptr, nr, hiback, ZP); + if(trim) + stringbg(f->b, xt, text, ZP, f->font, ptr+nr, back, ZP); + next: + pt = qt; + pt.x += b->wid; + p += nr; + + nb++; + b++; + ptr = (char*)b->ptr; + nr = NRUNE(b); + _frcklinewrap(f, &pt, b); + qt = pt; + } + + for(; nbnbox; nb++, b++){ + _frcklinewrap(f, &pt, b); + if(b->nrune >= 0){ + stringbg(f->b, pt, text, ZP, f->font, (char *)b->ptr, back, ZP); + } + pt.x += b->wid; + } } void