Exemple #1
0
static char*
tkcvstextgetl(TkCtext *t, Font *font, char *start, int *len)
{
	int w, n;
	char *lspc, *posn;

	w = t->width;
	if(w <= 0)
		w = 1000000;

	n = 0;
	lspc = nil;
	posn = start;
	while(*posn && *posn != '\n') {
		if(*posn == ' ')
			lspc = posn;
		n += stringnwidth(font, posn, 1);
		if(n >= w && posn != start) {
			if(lspc != nil)
				posn = lspc;
			*len = posn - start;
			if(lspc != nil)
				posn++;
			return posn;
		}
		posn++;
	}
	*len = posn - start;
	if(*posn == '\n')
		posn++;
	return posn;
}
Exemple #2
0
int
_frcanfit(Frame *f, Point pt, Frbox *b)
{
	int left, w, nr;
	uchar *p;
	Rune r;

	left = f->r.max.x-pt.x;
	if(b->nrune < 0)
		return b->minwid <= left;
	if(left >= b->wid)
		return b->nrune;
	for(nr=0,p=b->ptr; *p; p+=w,nr++){
		r = *p;
		if(r < Runeself)
			w = 1;
		else
			w = chartorune(&r, (char*)p);
		left -= stringnwidth(f->font, (char*)p, 1);
		if(left < 0)
			return nr;
	}
	drawerror(f->display, "_frcanfit can't");
	return 0;
}
Exemple #3
0
int
tkcvstextsrch(TkCitem *i, int x, int y)
{
	TkCtext *t;
	Font *font;
	Display *d;
	char *p, *next;
	int n, len, locked;

	t = TKobj(TkCtext, i);

	n = 0;
	font = i->env->font;
	d = i->env->top->display;
	p = t->text;
	if(p == nil)
		return 0;
	while(*p) {
		next = tkcvstextgetl(t, font, p, &len);
		if(y <= font->height) {
			locked = lockdisplay(d);
			for(n = 0; n < len && x > stringnwidth(font, p, n+1); n++)
				;
			if(locked)
				unlockdisplay(d);
			break;
		}
		y -= font->height;
		p = next;
	}	
	return p - t->text + n;
}
Exemple #4
0
Point
frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *text)
{
	Frbox *b;
	int nb, nr, w, x, trim;
	Point qt;
	uint p;
	char *ptr;

	p = 0;
	b = f->box;
	trim = 0;
	for(nb=0; nb<f->nbox && p<p1; nb++){
		nr = b->nrune;
		if(nr < 0)
			nr = 1;
		if(p+nr <= p0)
			goto Continue;
		if(p >= p0){
			qt = pt;
			_frcklinewrap(f, &pt, b);
			/* fill in the end of a wrapped line */
			if(pt.y > qt.y)
				draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt);
		}
		ptr = (char*)b->ptr;
		if(p < p0){	/* beginning of region: advance into box */
			ptr += nbytes(ptr, p0-p);
			nr -= (p0-p);
			p = p0;
		}
		trim = 0;
		if(p+nr > p1){	/* end of region: trim box */
			nr -= (p+nr)-p1;
			trim = 1;
		}
		if(b->nrune<0 || nr==b->nrune)
			w = b->wid;
		else
			w = stringnwidth(f->font, ptr, nr);
		x = pt.x+w;
		if(x > f->r.max.x)
			x = f->r.max.x;
		draw(f->b, Rect(pt.x, pt.y, x, pt.y+f->font->height), back, nil, pt);
		if(b->nrune >= 0)
			stringnbg(f->b, pt, text, ZP, f->font, ptr, nr, back, ZP);
		pt.x += w;
	    Continue:
		b++;
		p += nr;
	}
	/* if this is end of last plain text box on wrapped line, fill to end of line */
	if(p1>p0 &&  b>f->box && b<f->box+f->nbox && b[-1].nrune>0 && !trim){
		qt = pt;
		_frcklinewrap(f, &pt, b);
		if(pt.y > qt.y)
			draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt);
	}
	return pt;
}
Exemple #5
0
void
tkcvstextsize(TkCitem *i)
{
	Point o;
	Font *font;
	TkCtext *t;
	Display *d;
	char *next, *p;
	int len, pixw, locked;

	t = TKobj(TkCtext, i);

	font = i->env->font;
	d = i->env->top->display;
	t->pixwidth = 0;
	t->pixheight = 0;

	p = t->text;
	if(p != nil) {
		locked = lockdisplay(d);
		while(*p) {
			next = tkcvstextgetl(t, font, p, &len);
			pixw = stringnwidth(font, p, len);
			if(pixw > t->pixwidth)
				t->pixwidth = pixw;
			t->pixheight += font->height;
			p = next;
		}
		if(locked)
			unlockdisplay(d);
	}

	o = tkcvsanchor(i->p.drawpt[0], t->pixwidth, t->pixheight, t->anchor);

	i->p.bb.min.x = o.x;
	i->p.bb.min.y = o.y - Cvsicursor;
	i->p.bb.max.x = o.x + t->pixwidth;
	i->p.bb.max.y = o.y + t->pixheight + Cvsicursor;
	i->p.bb = insetrect(i->p.bb, -2*t->sbw);
	t->anchorp = subpt(o, i->p.drawpt[0]);
}
Exemple #6
0
void
tkcvstextdraw(Image *img, TkCitem *i, TkEnv *pe)
{
	TkEnv *e;
	TkCtext *t;
	Point o, dp;
	Rectangle r;
	char *p, *next;
	Image *pen;
	int len, lw, end, start;

	t = TKobj(TkCtext, i);

	e = i->env;
	pen = t->pen;
	if(pen == nil) {
		if (e->set & (1<<TkCfill))
			pen = tkgc(e, TkCfill);
		else
			pen = img->display->black;
	}


	o = addpt(t->anchorp, i->p.drawpt[0]);
	p = t->text;
	while(p && *p) {
		next = tkcvstextgetl(t, e->font, p, &len);
		dp = o;
		if(t->justify != Tkleft) {
			lw = stringnwidth(e->font, p, len);
			if(t->justify == Tkcenter)
				dp.x += (t->pixwidth - lw)/2;
			else
			if(t->justify == Tkright)
				dp.x += t->pixwidth - lw;
		}
		lw = p - t->text;
		if(t->self != -1 && lw+len > t->self) {
			if(t->sell >= t->self) {
				start = t->self - lw;
				end = t->sell - lw;
			}
			else {
				start = t->sell - lw;
				end = t->self - lw;
			}
			if(start < 0)
				r.min.x = o.x;
			else
				r.min.x = dp.x + stringnwidth(e->font, p, start);
			r.min.y = dp.y;
			if(end > len)
				r.max.x = o.x + t->pixwidth;
			else
				r.max.x = dp.x + stringnwidth(e->font, p, end);
			r.max.y = dp.y + e->font->height;
			tktextsdraw(img, r, pe, t->sbw);
			r.max.y = dp.y;
			if(start > 0)
				stringn(img, dp, pen, dp, e->font, p, start);
			if(end > start)
				stringn(img, r.min, tkgc(pe, TkCselectfgnd), r.min, e->font, p+start, end-start);
			if(len > end)
				stringn(img, r.max, pen, r.max, e->font, p+end, len-end);
		}
		else
			stringn(img, dp, pen, dp, e->font, p, len);
		if(t->focus) {
			lw = p - t->text;
			if(t->icursor >= lw && t->icursor <= lw+len) {
				lw = t->icursor - lw;
				if(lw > 0)
					lw = stringnwidth(e->font, p, lw);
				r.min.x = dp.x + lw;
				r.min.y = dp.y - 1;
				r.max.x = r.min.x + 2;
				r.max.y = r.min.y + e->font->height + 1;
				draw(img, r, pen, nil, ZP);
			}
		}
		o.y += e->font->height;
		p = next;
	}
}
Exemple #7
0
int
eenter(char *ask, char *buf, int len, Mouse *m)
{
	int done, down, tick, n, h, w, l, i;
	Image *b, *save, *backcol, *bordcol;
	Point p, o, t;
	Rectangle r, sc;
	Event ev;
	Rune k;

	o = screen->r.min;
	backcol = allocimagemix(display, DPurpleblue, DWhite);
	bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
	if(backcol == nil || bordcol == nil)
		return -1;

	while(ecankbd())
		ekbd();

	if(m) o = m->xy;

	if(buf && len > 0)
		n = strlen(buf);
	else {
		buf = nil;
		len = 0;
		n = 0;
	}

	k = -1;
	tick = n;
	save = nil;
	done = down = 0;

	p = stringsize(font, " ");
	h = p.y;
	w = p.x;

	b = screen;
	sc = b->clipr;
	replclipr(b, 0, b->r);

	while(!done){
		p = stringsize(font, buf ? buf : "");
		if(ask && ask[0]){
			if(buf) p.x += w;
			p.x += stringwidth(font, ask);
		}
		r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
		p.x = 0;
		r = rectsubpt(r, p);

		p = ZP;
		if(r.min.x < screen->r.min.x)
			p.x = screen->r.min.x - r.min.x;
		if(r.min.y < screen->r.min.y)
			p.y = screen->r.min.y - r.min.y;
		r = rectaddpt(r, p);
		p = ZP;
		if(r.max.x > screen->r.max.x)
			p.x = r.max.x - screen->r.max.x;
		if(r.max.y > screen->r.max.y)
			p.y = r.max.y - screen->r.max.y;
		r = rectsubpt(r, p);

		r = insetrect(r, -2);
		if(save == nil){
			save = allocimage(display, r, b->chan, 0, DNofill);
			if(save == nil){
				n = -1;
				break;
			}
			draw(save, r, b, nil, r.min);
		}
		draw(b, r, backcol, nil, ZP);
		border(b, r, 2, bordcol, ZP);
		p = addpt(r.min, Pt(6, 6));
		if(ask && ask[0]){
			p = string(b, p, bordcol, ZP, font, ask);
			if(buf) p.x += w;
		}
		if(buf){
			t = p;
			p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick));
			draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
			draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
			draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
			p = string(b, p, display->black, ZP, font, buf+tick);
		}
		flushimage(display, 1);

nodraw:
		i = Ekeyboard;
		if(m != nil)
			i |= Emouse;

		replclipr(b, 0, sc);
		i = eread(i, &ev);

		/* screen might have been resized */
		if(b != screen || !eqrect(screen->clipr, sc)){
			freeimage(save);
			save = nil;
		}
		b = screen;
		sc = b->clipr;
		replclipr(b, 0, b->r);

		switch(i){
		default:
			done = 1;
			n = -1;
			break;
		case Ekeyboard:
			k = ev.kbdc;
			if(buf == nil || k == Keof || k == '\n'){
				done = 1;
				break;
			}
			if(k == Knack || k == Kesc){
				done = !n;
				buf[n = tick = 0] = 0;
				break;
			}
			if(k == Ksoh || k == Khome){
				tick = 0;
				continue;
			}
			if(k == Kenq || k == Kend){
				tick = n;
				continue;
			}
			if(k == Kright){
				if(tick < n)
					tick += chartorune(&k, buf+tick);
				continue;
			}
			if(k == Kleft){
				for(i = 0; i < n; i += l){
					l = chartorune(&k, buf+tick);
					if(i+l >= tick){
						tick = i;
						break;
					}
				}
				continue;
			}
			if(k == Ketb){
				while(tick > 0){
					tick--;
					if(tick == 0 ||
					   strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1]))
						break;
				}
				buf[n = tick] = 0;
				break;
			}
			if(k == Kbs){
				if(tick <= 0)
					continue;
				for(i = 0; i < n; i += l){
					l = chartorune(&k, buf+i);
					if(i+l >= tick){
						memmove(buf+i, buf+i+l, n - (i+l));
						buf[n -= l] = 0;
						tick -= l;
						break;
					}
				}
				break;
			}
			if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
				continue;
			if((len-n) <= (l = runelen(k)))
				continue;
			memmove(buf+tick+l, buf+tick, n - tick);
			runetochar(buf+tick, &k);
			buf[n += l] = 0;
			tick += l;
			break;
		case Emouse:
			*m = ev.mouse;
			if(!ptinrect(m->xy, r)){
				down = 0;
				goto nodraw;
			}
			if(m->buttons & 7){
				down = 1;
				if(buf && m->xy.x >= (t.x - w)){
					down = 0;
					for(i = 0; i < n; i += l){
						l = chartorune(&k, buf+i);
						t.x += stringnwidth(font, buf+i, 1);
						if(t.x > m->xy.x)
							break;
					}
					tick = i;
				}
				continue;
			}
			done = down;
			break;
		}
		if(save){
			draw(b, save->r, save, nil, save->r.min);
			freeimage(save);
			save = nil;
		}
	}

	replclipr(b, 0, sc);

	freeimage(backcol);
	freeimage(bordcol);
	flushimage(display, 1);

	return n;
}
Exemple #8
0
int
tktdispwidth(Tk *tk, TkTtabstop *tb, TkTitem *i, Font *f, int x, int pos, int nchars)
{
	int w, del, locked;
	TkTtabstop *tbprev;
	Display *d;
	TkText *tkt;
	TkEnv env;

	tkt = TKobj(TkText, tk);
	d = tk->env->top->display;
	if (tb == nil)
		tb = tkt->tabs;

	switch(i->kind) {
	case TkTrune:
		pos = tktutfpos(i->istring, pos);
		/* FALLTHRU */
	case TkTascii:
		if(f == nil) {
			if(!tktanytags(i))
				f = tk->env->font;
			else {
				tkttagopts(tk, i, nil, &env, nil, 1);
				f = env.font;
			}
		}
		locked = 0;
		if(!(tkt->tflag&TkTdlocked))
			locked = lockdisplay(d);
		if(nchars >= 0)
			w = stringnwidth(f, i->istring+pos, nchars);
		else
			w = stringwidth(f, i->istring+pos);
		if(locked)
			unlockdisplay(d);
		break;
	case TkTtab:
		if(tb == nil)
			w = 0;
		else {
			tbprev = nil;
			while(tb->pos <= x && tb->next != nil) {
					tbprev = tb;
					tb = tb->next;
				}
			w = tb->pos - x;
			if(w <= 0) {
				del = tb->pos;
				if(tbprev != nil)
					del -= tbprev->pos;
				while(w <= 0)
					w += del;
			}
			/* todo: other kinds of justification */
		}
		break;
	case TkTwin:
		if(i->iwin->sub == 0)
			w = 0;
		else
			w = i->iwin->sub->act.width + 2*i->iwin->padx + 2*i->iwin->sub->borderwidth;
		break;
	default:
		w = 0;
	}
	return w;
}