#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <frame.h>
Point
_frptofcharptb(Frame *f, ulong p, Point pt, int bn)
{
uchar *s;
Frbox *b;
int w, l;
Rune r;
for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
_frcklinewrap(f, &pt, b);
if(p < (l=NRUNE(b))){
if(b->nrune > 0)
for(s=b->ptr; p>0; s+=w, p--){
if((r = *s) < Runeself)
w = 1;
else
w = chartorune(&r, (char*)s);
pt.x += stringnwidth(f->font, (char*)s, 1);
if(r==0 || pt.x>f->r.max.x)
drawerror(f->display, "frptofchar");
}
break;
}
p -= l;
_fradvance(f, &pt, b);
}
return pt;
}
Point
frptofchar(Frame *f, ulong p)
{
return _frptofcharptb(f, p, f->r.min, 0);
}
Point
_frptofcharnb(Frame *f, ulong p, int nb) /* doesn't do final _fradvance to next line */
{
Point pt;
int nbox;
nbox = f->nbox;
f->nbox = nb;
pt = _frptofcharptb(f, p, f->r.min, 0);
f->nbox = nbox;
return pt;
}
static
Point
_frgrid(Frame *f, Point p)
{
p.y -= f->r.min.y;
p.y -= p.y%f->font->height;
p.y += f->r.min.y;
if(p.x > f->r.max.x)
p.x = f->r.max.x;
return p;
}
ulong
frcharofpt(Frame *f, Point pt)
{
Point qt;
int w, bn;
uchar *s;
Frbox *b;
ulong p;
Rune r;
pt = _frgrid(f, pt);
qt = f->r.min;
for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
_frcklinewrap(f, &qt, b);
if(qt.y >= pt.y)
break;
_fradvance(f, &qt, b);
p += NRUNE(b);
}
for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
_frcklinewrap(f, &qt, b);
if(qt.y > pt.y)
break;
if(qt.x+b->wid > pt.x){
if(b->nrune < 0)
_fradvance(f, &qt, b);
else{
s = b->ptr;
for(;;){
if((r = *s) < Runeself)
w = 1;
else
w = chartorune(&r, (char*)s);
if(r == 0)
drawerror(f->display, "end of string in frcharofpt");
qt.x += stringnwidth(f->font, (char*)s, 1);
s += w;
if(qt.x > pt.x)
break;
p++;
}
}
}else{
p += NRUNE(b);
_fradvance(f, &qt, b);
}
}
return p;
}
|