1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/* Copyright (c) 1992 AT&T - All rights reserved. */
#include <u.h>
#include <libc.h>
#include <libg.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->a.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; 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->a.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;
}
|