Plan 9 from Bell Labs’s /usr/web/sources/extra/art/box.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include "art.h"

Image *color;

/*
 * return the closest point on box ip to point testp.
 */
Dpoint nearbox(Item *ip, Dpoint testp){
	Dpoint p=testp, p0=ip->p[0], p1=ip->p[1];
	Flt d0, d1, d2, d3;
	if(p0.x>p1.x){ d0=p0.x; p0.x=p1.x; p1.x=d0; }
	if(p0.y>p1.y){ d0=p0.y; p0.y=p1.y; p1.y=d0; }
	if(p.x<p0.x) p.x=p0.x; else if(p.x>p1.x) p.x=p1.x;
	if(p.y<p0.y) p.y=p0.y; else if(p.y>p1.y) p.y=p1.y;
	d0=p.x-p0.x;
	d1=p1.x-p.x;
	d2=p.y-p0.y;
	d3=p1.y-p.y;
	if(d0<d1 && d0<d2 && d0<d3) return Dpt(p0.x, p.y);
	if(d1<d2 && d1<d3) return Dpt(p1.x, p.y);
	if(d2<d3) return Dpt(p.x, p0.y);
	return Dpt(p.x, p1.y);
}

void drawbox(Item *ip, Image *b, Image *color){
	Point p0=D2P(ip->p[0]);
	Point p1=D2P(ip->p[1]);

	line(b, p0, Pt(p1.x, p0.y), Endsquare, Endsquare, 0, color, ZP);
	line(b, Pt(p1.x, p0.y), p1, Endsquare, Endsquare, 0, color, ZP);
	line(b, p1, Pt(p0.x, p1.y), Endsquare, Endsquare, 0, color, ZP);
	line(b, Pt(p0.x, p1.y), p0, Endsquare, Endsquare, 0, color, ZP);
}

#define	right(p) Dpt((p).x+1, (p).y)
#define	up(p)    Dpt((p).x, (p).y+1)
#define	left(p)  Dpt((p).x-1, (p).y)
#define	down(p)  Dpt((p).x, (p).y-1)

void editbox(void){
	Item *s=selection;
	Dpoint hs, cen, p, p01, p10;
	Flt rad, r;
	int which;
	if(s->p[0].x>s->p[1].x){
		r=s->p[0].x;
		s->p[0].x=s->p[1].x;
		s->p[1].x=r;
	}
	if(s->p[0].y>s->p[1].y){
		r=s->p[0].y;
		s->p[0].y=s->p[1].y;
		s->p[1].y=r;
	}
	cen=dmidpt(s->p[0], s->p[1]);
	hs=dsub(s->p[1], cen);
	p=Dpt(cen.x-hs.x, cen.y-hs.y);   rad=dist(arg[0], p);       which=0;
	p=Dpt(cen.x-hs.x, cen.y     ); if((r=dist(arg[0], p))<rad){ which=1; rad=r; }
	p=Dpt(cen.x-hs.x, cen.y+hs.y); if((r=dist(arg[0], p))<rad){ which=2; rad=r; }
	p=Dpt(cen.x,      cen.y-hs.y); if((r=dist(arg[0], p))<rad){ which=3; rad=r; }
	p=    cen                    ; if((r=dist(arg[0], p))<rad){ which=4; rad=r; }
	p=Dpt(cen.x,      cen.y+hs.y); if((r=dist(arg[0], p))<rad){ which=5; rad=r; }
	p=Dpt(cen.x+hs.x, cen.y-hs.y); if((r=dist(arg[0], p))<rad){ which=6; rad=r; }
	p=Dpt(cen.x+hs.x, cen.y     ); if((r=dist(arg[0], p))<rad){ which=7; rad=r; }
	p=Dpt(cen.x+hs.x, cen.y+hs.y); if((r=dist(arg[0], p))<rad){ which=8; rad=r; }
	p01=Dpt(s->p[0].x, s->p[1].y);
	p10=Dpt(s->p[1].x, s->p[0].y);
	msg("case %d", which);
	switch(which){
	case 0:		/* s->p[1] fixed */
		hotline(s->p[1], left(s->p[1]), L);
		hotline(s->p[1], down(s->p[1]), L);
		track(movep, 0, s);
		break;
	case 1:		/* p10, s->p[1] fixed */
		hotline(p10, s->p[1], L|R);
		hotline(p10, down(p01), L);
		hotline(s->p[1], down(s->p[1]), L);
		track(movex0, 0, s);
		break;
	case 2:		/* p10 fixed */
		hotline(p10, right(p01), L);
		hotline(p10, down(p01), L);
		track(movex0y1, 0, s);
		break;
	case 3:		/* p01, s->p[1] fixed */
		hotline(p01, s->p[1], L|R);
		hotline(p01, left(p10), L);
		hotline(s->p[1], left(s->p[1]), L);
		track(movey0, 0, s);
		break;
	case 4:		/* all moving */
		track(moveall, 0, s);
		break;
	case 5:		/* p10, s->p[0] fixed */
		hotline(p10, s->p[0], L|R);
		hotline(p10, left(p01), L);
		hotline(s->p[0], left(s->p[0]), L);
		track(movey1, 0, s);
		break;
	case 6:		/* p01 fixed */
		hotline(p01, left(p10), L);
		hotline(p01, up(p10), L);
		track(movex1y0, 0, s);
		break;
	case 7:		/* p01, s->p[0] fixed */
		hotline(p01, s->p[0], L|R);
		hotline(p01, up(p10), L);
		hotline(s->p[0], up(s->p[0]), L);
		track(movex1, 0, s);
		break;
	case 8:		/* s->p[0] fixed */
		hotline(s->p[0], right(s->p[0]), L);
		hotline(s->p[0], up(s->p[0]), L);
		track(movep, 1, s);
		break;
	}
}
void translatebox(Item *ip, Dpoint delta){
	ip->p[0]=dadd(ip->p[0], delta);
	ip->p[1]=dadd(ip->p[1], delta);
}
void deletebox(Item *ip){
}
void writebox(Item *ip, int f){
	fprint(f, "b %.3f %.3f %.3f %.3f\n", ip->p[0].x, ip->p[0].y, ip->p[1].x, ip->p[1].y);
}
void activatebox(Item *ip){
	hotline(ip->p[0], Dpt(ip->p[0].x, ip->p[1].y), L|R);
	hotline(Dpt(ip->p[0].x, ip->p[1].y), ip->p[1], L|R);
	hotline(ip->p[1], Dpt(ip->p[1].x, ip->p[0].y), L|R);
	hotline(Dpt(ip->p[1].x, ip->p[0].y), ip->p[0], L|R);
}
/*
 * This should really check that the boundary of ip intersects r.
 * Now it checks that the interior of ip intersects r.
 */
int inboxbox(Item *ip, Drectangle r){
	return drectxrect(drcanon(Drpt(ip->p[0], ip->p[1])), r);
}
Drectangle bboxbox(Item *ip){
	return drcanon(Drpt(ip->p[0], ip->p[1]));
}
Dpoint nearvertbox(Item *ip, Dpoint testp){
	Dpoint hs, cen, p, close;
	Flt rad, r;
	cen=dmidpt(ip->p[0], ip->p[1]);
	hs=dsub(ip->p[1], cen);
	p=Dpt(cen.x-hs.x, cen.y-hs.y);   rad=dist(testp, p);       close=p;
	p=Dpt(cen.x-hs.x, cen.y     ); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=Dpt(cen.x-hs.x, cen.y+hs.y); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=Dpt(cen.x,      cen.y-hs.y); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=    cen                    ; if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=Dpt(cen.x,      cen.y+hs.y); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=Dpt(cen.x+hs.x, cen.y-hs.y); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=Dpt(cen.x+hs.x, cen.y     ); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	p=Dpt(cen.x+hs.x, cen.y+hs.y); if((r=dist(testp, p))<rad){ close=p; rad=r; }
	return close;
}
Itemfns boxfns={
	deletebox,
	writebox,
	activatebox,
	nearbox,
	drawbox,
	editbox,
	translatebox,
	inboxbox,
	bboxbox,
	nearvertbox,
};
Item *addbox(Item *head, Dpoint p0, Dpoint p1){
	return additem(head, BOX, 0., 0, 0, 0, &boxfns, 2, p0, p1);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].