ref: d1cebf608b05e45b148108ac6c16ae94f6862097
dir: /sys/src/libframe/frptofchar.c/
#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; }