#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <mouse.h>#include <frame.h> #define SLOP 25 void_fraddbox(Frame *f, int bn, int n) /* add n boxes after bn, shift the rest up, * box[bn+n]==box[bn] */{ int i; if(bn > f->nbox) drawerror(f->display, "_fraddbox"); if(f->nbox+n > f->nalloc) _frgrowbox(f, n+SLOP); for(i=f->nbox; --i>=bn; ) f->box[i+n] = f->box[i]; f->nbox+=n;} void_frclosebox(Frame *f, int n0, int n1) /* inclusive */{ int i; if(n0>=f->nbox || n1>=f->nbox || n1<n0) drawerror(f->display, "_frclosebox"); n1++; for(i=n1; i<f->nbox; i++) f->box[i-(n1-n0)] = f->box[i]; f->nbox -= n1-n0;} void_frdelbox(Frame *f, int n0, int n1) /* inclusive */{ if(n0>=f->nbox || n1>=f->nbox || n1<n0) drawerror(f->display, "_frdelbox"); _frfreebox(f, n0, n1); _frclosebox(f, n0, n1);} void_frfreebox(Frame *f, int n0, int n1) /* inclusive */{ int i; if(n1<n0) return; if(n0>=f->nbox || n1>=f->nbox) drawerror(f->display, "_frfreebox"); n1++; for(i=n0; i<n1; i++) if(f->box[i].nrune >= 0) free(f->box[i].ptr);} void_frgrowbox(Frame *f, int delta){ f->nalloc += delta; f->box = realloc(f->box, f->nalloc*sizeof(Frbox)); if(f->box == 0) drawerror(f->display, "_frgrowbox");} staticvoiddupbox(Frame *f, int bn){ uchar *p; if(f->box[bn].nrune < 0) drawerror(f->display, "dupbox"); _fraddbox(f, bn, 1); if(f->box[bn].nrune >= 0){ p = _frallocstr(f, NBYTE(&f->box[bn])+1); strcpy((char*)p, (char*)f->box[bn].ptr); f->box[bn+1].ptr = p; }} staticuchar*runeindex(uchar *p, int n){ int i, w; Rune rune; for(i=0; i<n; i++,p+=w) if(*p < Runeself) w = 1; else{ w = chartorune(&rune, (char*)p); USED(rune); } return p;} staticvoidtruncatebox(Frame *f, Frbox *b, int n) /* drop last n chars; no allocation done */{ if(b->nrune<0 || b->nrune<n) drawerror(f->display, "truncatebox"); b->nrune -= n; runeindex(b->ptr, b->nrune)[0] = 0; b->wid = stringwidth(f->font, (char *)b->ptr);} staticvoidchopbox(Frame *f, Frbox *b, int n) /* drop first n chars; no allocation done */{ char *p; if(b->nrune<0 || b->nrune<n) drawerror(f->display, "chopbox"); p = (char*)runeindex(b->ptr, n); memmove((char*)b->ptr, p, strlen(p)+1); b->nrune -= n; b->wid = stringwidth(f->font, (char *)b->ptr);} void_frsplitbox(Frame *f, int bn, int n){ dupbox(f, bn); truncatebox(f, &f->box[bn], f->box[bn].nrune-n); chopbox(f, &f->box[bn+1], n);} void_frmergebox(Frame *f, int bn) /* merge bn and bn+1 */{ Frbox *b; b = &f->box[bn]; _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1); strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr); b[0].wid += b[1].wid; b[0].nrune += b[1].nrune; _frdelbox(f, bn+1, bn+1);} int_frfindbox(Frame *f, int bn, ulong p, ulong q) /* find box containing q and put q on a box boundary */{ Frbox *b; for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++) p += NRUNE(b); if(p != q) _frsplitbox(f, bn++, (int)(q-p)); return bn;}
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <frame.h>
#define SLOP 25
void
_fraddbox(Frame *f, int bn, int n) /* add n boxes after bn, shift the rest up,
* box[bn+n]==box[bn] */
{
int i;
if(bn > f->nbox)
drawerror(f->display, "_fraddbox");
if(f->nbox+n > f->nalloc)
_frgrowbox(f, n+SLOP);
for(i=f->nbox; --i>=bn; )
f->box[i+n] = f->box[i];
f->nbox+=n;
}
void
_frclosebox(Frame *f, int n0, int n1) /* inclusive */
{
int i;
if(n0>=f->nbox || n1>=f->nbox || n1<n0)
drawerror(f->display, "_frclosebox");
n1++;
for(i=n1; i<f->nbox; i++)
f->box[i-(n1-n0)] = f->box[i];
f->nbox -= n1-n0;
}
void
_frdelbox(Frame *f, int n0, int n1) /* inclusive */
{
if(n0>=f->nbox || n1>=f->nbox || n1<n0)
drawerror(f->display, "_frdelbox");
_frfreebox(f, n0, n1);
_frclosebox(f, n0, n1);
}
void
_frfreebox(Frame *f, int n0, int n1) /* inclusive */
{
int i;
if(n1<n0)
return;
if(n0>=f->nbox || n1>=f->nbox)
drawerror(f->display, "_frfreebox");
n1++;
for(i=n0; i<n1; i++)
if(f->box[i].nrune >= 0)
free(f->box[i].ptr);
}
void
_frgrowbox(Frame *f, int delta)
{
f->nalloc += delta;
f->box = realloc(f->box, f->nalloc*sizeof(Frbox));
if(f->box == 0)
drawerror(f->display, "_frgrowbox");
}
static
void
dupbox(Frame *f, int bn)
{
uchar *p;
if(f->box[bn].nrune < 0)
drawerror(f->display, "dupbox");
_fraddbox(f, bn, 1);
if(f->box[bn].nrune >= 0){
p = _frallocstr(f, NBYTE(&f->box[bn])+1);
strcpy((char*)p, (char*)f->box[bn].ptr);
f->box[bn+1].ptr = p;
}
}
static
uchar*
runeindex(uchar *p, int n)
{
int i, w;
Rune rune;
for(i=0; i<n; i++,p+=w)
if(*p < Runeself)
w = 1;
else{
w = chartorune(&rune, (char*)p);
USED(rune);
}
return p;
}
static
void
truncatebox(Frame *f, Frbox *b, int n) /* drop last n chars; no allocation done */
{
if(b->nrune<0 || b->nrune<n)
drawerror(f->display, "truncatebox");
b->nrune -= n;
runeindex(b->ptr, b->nrune)[0] = 0;
b->wid = stringwidth(f->font, (char *)b->ptr);
}
static
void
chopbox(Frame *f, Frbox *b, int n) /* drop first n chars; no allocation done */
{
char *p;
if(b->nrune<0 || b->nrune<n)
drawerror(f->display, "chopbox");
p = (char*)runeindex(b->ptr, n);
memmove((char*)b->ptr, p, strlen(p)+1);
b->nrune -= n;
b->wid = stringwidth(f->font, (char *)b->ptr);
}
void
_frsplitbox(Frame *f, int bn, int n)
{
dupbox(f, bn);
truncatebox(f, &f->box[bn], f->box[bn].nrune-n);
chopbox(f, &f->box[bn+1], n);
}
void
_frmergebox(Frame *f, int bn) /* merge bn and bn+1 */
{
Frbox *b;
b = &f->box[bn];
_frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1);
strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr);
b[0].wid += b[1].wid;
b[0].nrune += b[1].nrune;
_frdelbox(f, bn+1, bn+1);
}
int
_frfindbox(Frame *f, int bn, ulong p, ulong q) /* find box containing q and put q on a box boundary */
{
Frbox *b;
for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++)
p += NRUNE(b);
if(p != q)
_frsplitbox(f, bn++, (int)(q-p));
return bn;
}