File:  [Research Unix] / researchv9 / jtools / src / pads / x11 / paint.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include "univ.h"
#define PADBORDER 3
#define CHARWIDTH fontwidth(&defont)

Line *Lsent;
Rectangle Trect;
Attrib Attributes;
int CharsWide;
Line FakeLine;
Bitmap *Osbm;
char Tilde;

DoubleOutline(b,r)
register Bitmap *b;
Rectangle r;
{
	outline(b,r);
	outline(b,inset(r,1));
}

HeavyBorder( p )
register Pad *p;
{
	DoubleOutline( &display, inset(p->rect,PADBORDER+1) );
}

Line *Linei(i)
register i;
{
	register Line *lsent = Lsent, *l;
	register long ct = 1, k = lsent->key;
	Line fake;

	if( !i ) return lsent;
	for( l = lsent->down; l != lsent; l = l->down, ++ct )
		if( k ? (l->key==i) : (ct==i) )
			return l;
	if( k && i<=k ){
		FakeLine.key = i;
		*(FakeLine.text = itoa((int)i)) = Tilde;
		return &FakeLine;
	}
	return 0;
}

Trunc(l)
Line *l;
{
	int a;
	return (a=l->attributes)&(FOLD|TRUNCATE) ? a&TRUNCATE : Attributes&TRUNCATE;
}

int Expanded;
short Tabs = 8;
Expand( blanks, tabs )
register char *blanks, *tabs;
{
	register int i, c;

	for( i = 0; (c = *tabs++) && i<250; )
		if( c == '\t' )
			do
				blanks[i++] = ' ';
			while( i % Tabs );
		else
			blanks[i++] = c;
	if( i==0 ) blanks[i++] = ' ';
	blanks[i] = '\0';
	Expanded = i;
}

Needs(i)
{
	register Line *l = Linei(i);
	char blanks[256];

	if( Trunc(l) ) return 1;
	Expand( blanks, l->text );
	return 1 + (Expanded-1)/CharsWide;
}

#define BARWIDTH 10
static Rectangle bar;

int ClipPaint(clip,p)			/* nobody said it would be easy */
register Pad *p;
Rectangle clip;
{
	register middle, lines, lo, hi, capacity;
	int change, i, selpainted;
	register Line *lsent, *l;
	char save, *terminate, blanks[256];
	Point pt;

	Tabs = p->tabs;
	Attributes = p->attributes;
	Tilde = Attributes&NO_TILDE ? 0 : '~';
	Lsent = lsent = &p->sentinel;
	if( !PadSized(p->rect) ) return 1;

	p->srect = Trect = inset( p->rect, PADBORDER+4 );
	p->srect.corner.x = (Trect.origin.x += BARWIDTH);
	Trect.origin.x += 2;
	p->srect.origin.y -= 1;
	p->srect.corner.y += 1;
	p->srect.origin.x -= 1;

	capacity = (Trect.corner.y-Trect.origin.y) /
		fontheight(&defont);
	CharsWide = (Trect.corner.x-Trect.origin.x) / CHARWIDTH - 1;

	middle = lines = 0;
	for( l = lsent->down; l != lsent; l = l->down ){
		++lines;
		if( l == Selected.line && rectinrect(p->rect,clip) )
			middle = lsent->key ? Selected.line->key : lines;
	}
	if( lsent->key ) lines = lsent->key;
	if( Scrolly ){
		Scrolly -= p->srect.origin.y;
		middle = 1 +
			muldiv(Scrolly,lines,p->srect.corner.y-p->srect.origin.y);
		if( middle > lines ) middle = lines;
	}
	if( !middle ){
		middle = (p->lo+p->hi)/2;
		if( middle<1 || middle>lines )
			middle = lsent->key ? 1 : lines;
	}
	lo = middle+1;
	hi = middle;
	do {
		change = 0;
		if( lo>0 && capacity>=Needs(lo-1)){
			capacity -= Needs(--lo);
			change = 1;
		}
		if( hi<lines && capacity>=Needs(hi+1)){
			capacity -= Needs(++hi);
			change = 1;
		}
	} while( change );
	if( lo>hi ){
		Selected.line = 0;
		return 1;
	}
	if( Scrolly && lo==p->lo && hi==p->hi ) return 1;
	p->lo = lo;
	p->hi = hi;
	for( l = lsent->down; l != lsent; l = l->down )
		l->rect = ZRectangle;
	if( Osbm && !eqrect(Osbm->rect,p->rect) && Osbm!=&display ){
		bfree(Osbm);
		Osbm = 0;
	}
	if( !Osbm && !(Osbm = balloc(p->rect)) ) Osbm = &display;
	rectf( Osbm, p->rect, F_CLR );
	DoubleOutline( Osbm, inset(p->rect, PADBORDER-1) );
	if( p == Current ) DoubleOutline( Osbm, inset(p->rect,PADBORDER+1) );
	rectf( Osbm, bar = scrollbar(p->srect,lo,hi+1,0,lines+1), F_XOR );
	pt = Trect.origin;
	selpainted = 0;
	for( ; lo <= hi; ++lo ){
		l = Linei(lo);
		l->rect.origin = pt;
		Expand( blanks, l->text );
		for( i = 0; i < Expanded; i += CharsWide ){
			if( i ){
				if( Trunc(l) ) break;
				pt.x += CHARWIDTH;
			}
			save = '\0';
			if( i+CharsWide < Expanded ){
				save = *(terminate=blanks+i+CharsWide);
				*terminate = '\0';
			}
			string( &defont, blanks+i, Osbm, pt, F_OR );
			pt.x = Trect.origin.x;
			l->rect.corner.y = (pt.y += fontheight(&defont));
			l->rect.corner.x = Trect.corner.x;
			if( save ) *terminate = save;
		}
		if( Selected.line == l ){
			rectf( Osbm, l->rect, F_XOR );	/* LineXOR(l); */
			selpainted = 1;
		}
	}
	if( !selpainted && Selected.pad == p ) Selected.line = 0;
	if( !Scrolly ) RequestLines(p);
	if( Osbm != &display )
	{
		Rectangle clipsrc;
		clipsrc = clip;
		rectclip(&clipsrc,Osbm->rect);
		PadBlt( Osbm, clipsrc, p->front );
		return 1;
/*		bitblt( Osbm, clipsrc, &display, clipsrc.origin, F_STORE );*/
	}
	return 0;
}

#define rc (r.corner)
#define ro (r.origin)
#define pc (p->rect.corner)
#define po (p->rect.origin)

PadBlt(b,r,p)
register Bitmap *b;
Rectangle r;
register Pad *p;
{
	extern Pad Sentinel;

	if( p == &Sentinel ){
		bitblt( b, r, &display, r.origin, F_STORE );
		return;
	}
	if( !rectXrect(p->rect, r) ){
		PadBlt( b, r, p->front );
		return;
	}
	if(ro.y < po.y){
		PadBlt( b, Rpt(ro,Pt(rc.x,po.y)), p->front );
		ro.y = po.y;
	}
	if(rc.y > pc.y){
		PadBlt( b, Rpt(Pt(ro.x,pc.y),rc), p->front );
		rc.y = pc.y;
	}
	if(ro.x < po.x){
		PadBlt( b, Rpt(ro,Pt(po.x,rc.y)), p->front );
		ro.x = po.x;
	}
	if(rc.x > pc.x){
		PadBlt( b, Rpt(Pt(pc.x,ro.y),rc), p->front );
		rc.x = pc.x;
	}
}

Paint(p)
Pad *p;
{
	ClipPaint(p->rect,p);
}

LineReq(p, lo, hi, fake)
register Pad *p;
register long lo, hi;
{
	Line *InsPos();

	if( lo == 0 ) lo = 1;
	if( !p || !p->object || hi < lo ) return;
	PutRemote( P_LINEREQ );
	SendLong( p->object );
	SendLong( p->object );
	SendLong( lo );
	SendLong( hi );
	if( fake )
		for( FakeLine.key = lo; FakeLine.key <= hi; ++FakeLine.key ){
			*(FakeLine.text = itoa((int)FakeLine.key)) = Tilde;
			InsAbove(InsPos(p,&FakeLine),&FakeLine);
		}
}
	
CRequestLines(p)
register Pad *p;
{
	register Line *l;
	register reqhi = -1, reqlo = 0, k, i;

	for( i = p->lo; i <= p->hi; ++i ){
		l = Linei(i);
		k = l->key;
		if( l->attributes&FAKELINE ){
			l->attributes &= ~FAKELINE;
			if( k == reqhi+1 )
				reqhi = k;
			else {
				LineReq(p, reqlo, reqhi, 0);
				reqlo = reqhi = k;
			}
		}
	}
	LineReq(p, reqlo, reqhi, 0);
}

RequestLines(p)
register Pad *p;
{
	register Line *lsent = Lsent, *l;
	register reqlo, cutlo, cuthi, k, cushion;

	if( !lsent || !p ) return;
	if( !lsent->key ){
		if( p->attributes&FAKELINE )
			CRequestLines(p);
		return;
	}
	cushion = Configuration&BIGMEMORY ? 1000 : 10;
	reqlo = p->lo;
	cutlo = p->lo - cushion;
	cuthi = p->hi + cushion;
	for( l = lsent->down; l != lsent; l = l->down ){
		k = l->key;
		if( k>=reqlo && k<=p->hi ){
			LineReq(p, reqlo, k-1, 1);
			reqlo = k+1;
		} else if( k<cutlo || k>cuthi )
			DelLine(l);
	}
	LineReq(p, reqlo, p->hi, 1);
		
}

Pointing()
{
	register Pad *p = PickPad(mouse.xy);
	register Line *l, *ll, *lsent = &p->sentinel, *sel;
	register int i, paint = 0;
	Point pt, ppt;
	extern Rectangle KBDrect;

	if( ptinrect(mouse.xy, KBDrect) ) return;
	if( !p ){
		Select( (Line*)0, (Pad*)0 );
		SetCurrent( (Pad *)0 );
		return;
	}
	if( p != Current ){
		MakeCurrent(p);
		while( butts==BUTT1 ) jnap(2);	/* for rollover */
		return;
	}
	pt = mouse.xy;
	for( ; butts==BUTT1; jnap(2)){
		paint = 0;
		ppt = pt;
		pt = mouse.xy;
		if( ptinrect(pt,p->srect) ){
			if( !ptinrect(ppt,p->srect) && ptinrect(ppt,p->rect) ){
				pt.y = (bar.origin.y+bar.corner.y)/2;
				cursset( pt );
			}
			Scrolly = pt.y;
			Paint(p);
		} else {
			sel = 0;
			for( l = lsent->down, i = 1; l!=lsent ; l = l->down, ++i ){
				if( ptinrect( mouse.xy, l->rect ) ){
					sel = l;
					break;
				}
			}
			Select( sel, p);
			if( sel )
				if( p->sentinel.key
				 ? (sel->key == p->lo || sel->key == p->hi )
				 : (i == p->lo || i == p->hi) ){
					paint = 1;
					Scrolly = 0;
			}
		}
	}
	if( paint )
		Paint(p);
	if( Scrolly ){
		Scrolly = 0;
		RequestLines(p);
	}
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.