#include #include #include #include Point _frptofcharptb(Frame *f, ulong p, Point pt, int bn) { uchar *s; Frbox *b; int w, l; Rune r; for(b = &f->box[bn]; bnnbox; 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 += charwidth(f->font, r); if(r==0 || pt.x>f->r.max.x) berror("frptofchar"); } break; } p -= l; _fradvance(f, &pt, b); } return pt; } Point frptofchar(Frame *f, ulong p) { return _frptofcharptb(f, p, Pt(f->left, f->r.min.y), 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, Pt(f->left, f->r.min.y), 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.x = f->left; qt.y = f->r.min.y; for(b=f->box,bn=0,p=0; bnnbox && qt.y= pt.y) break; _fradvance(f, &qt, b); p += NRUNE(b); } for(; bnnbox && 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) berror("end of string in frcharofpt"); s += w; qt.x += charwidth(f->font, r); if(qt.x > pt.x) break; p++; } } }else{ p += NRUNE(b); _fradvance(f, &qt, b); } } return p; }