#include #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]; 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; }