⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mug.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		i = d.y;		if(i < 0){			/*			 * should really check i/2, but this is safe and feedback			 * makes the control feel right			 */			i = -min(-i, a[Right]);			i = max(i, a[Left]);		}		i = max(i, a[Top]);		if(i >= Dy(r))			break;		r.min.y += i;		/* divide the half bit equally */		toggle = 1-toggle;		if(toggle){			r.min.x += i/2;			r.max.x = r.min.x+Dy(r);		}else{			r.max.x -= i/2;			r.min.x = r.max.x-Dy(r);		}		break;	case RTopRight:		i = (-d.x+d.y)/2;		if(i>=Dx(r) || i>=Dy(r))			break;		i = -min(-i, a[Right]);		i = max(i, a[Top]);		r.max.x -= i;		r.min.y += i;		break;	case RLeft:		i = d.x;		if(i < 0){			i = -min(-i, a[Bottom]);			i = max(i, a[Top]);		}		i = max(i, a[Left]);		if(i >= Dx(r))			break;		r.min.x += i;		/* divide the half bit equally */		toggle = 1-toggle;		if(toggle){			r.min.y += i/2;			r.max.y = r.min.y+Dx(r);		}else{			r.max.y -= i/2;			r.min.y = r.max.y-Dx(r);		}		break;	case RMiddle:		if(d.x >= 0)			d.x = min(d.x, a[Right]);		else			d.x = max(d.x, a[Left]);		if(d.y >= 0)			d.y = min(d.y, a[Bottom]);		else			d.y = max(d.y, a[Top]);		r = rectaddpt(r, d);		break;	case RRight:		i = d.x;		if(i > 0){			i = min(i, a[Bottom]);			i = -max(-i, a[Top]);		}		i = min(i, a[Right]);		if(-i >= Dx(r))			break;		r.max.x += i;		/* divide the half bit equally */		toggle = 1-toggle;		if(toggle){			r.min.y -= i/2;			r.max.y = r.min.y+Dx(r);		}else{			r.max.y += i/2;			r.min.y = r.max.y-Dx(r);		}		break;	case RBotLeft:		i = (d.x+-d.y)/2;		if(i>=Dx(r) || i>=Dy(r))			break;		i = max(i, a[Left]);		i = -min(-i, a[Bottom]);		r.min.x += i;		r.max.y -= i;		break;	case RBot:		i = d.y;		if(i > 0){			i = min(i, a[Right]);			i = -max(-i, a[Left]);		}		i = min(i, a[Bottom]);		if(i >= Dy(r))			break;		r.max.y += i;		/* divide the half bit equally */		toggle = 1-toggle;		if(toggle){			r.min.x -= i/2;			r.max.x = r.min.x+Dy(r);		}else{			r.max.x += i/2;			r.min.x = r.max.x-Dy(r);		}		break;	case RBotRight:		i = (-d.x+-d.y)/2;		if(i>=Dx(r) || i>=Dy(r))			break;		i = -min(-i, a[Right]);		i = -min(-i, a[Bottom]);		r.max.x -= i;		r.max.y -= i;		break;	}	if(Dx(r)<3 || Dy(r)<3){		*rp = oldr;		return 0;	}	*rp = r;	return !eqrect(r, oldr);}voidrlist(Rectangle r, Rectangle *ra){	Rectangle tr;	tr = r;	tr.max.y = r.min.y+Dy(r)/4;	ra[0] = tr;	ra[0].max.x = tr.min.x+Dx(tr)/4;	ra[1] = tr;	ra[1].min.x = ra[0].max.x;	ra[1].max.x = tr.max.x-Dx(tr)/4;	ra[2] = tr;	ra[2].min.x = ra[1].max.x;	tr.min.y = tr.max.y;	tr.max.y = r.max.y-Dy(r)/4;	ra[3] = tr;	ra[3].max.x = tr.min.x+Dx(tr)/4;	ra[4] = tr;	ra[4].min.x = ra[3].max.x;	ra[4].max.x = tr.max.x-Dx(tr)/4;	ra[5] = tr;	ra[5].min.x = ra[4].max.x;	tr.min.y = tr.max.y;	tr.max.y = r.max.y;	ra[6] = tr;	ra[6].max.x = tr.min.x+Dx(tr)/4;	ra[7] = tr;	ra[7].min.x = ra[6].max.x;	ra[7].max.x = tr.max.x-Dx(tr)/4;	ra[8] = tr;	ra[8].min.x = ra[7].max.x;}intabs(int a){	if(a < 0)		return -a;	return a;}voidusage(void){	fprint(2, "usage: mug [file.bit]\n");	exits("usage");}voideresized(int new){	if(new && getwindow(display, Refmesg) < 0)		fprint(2,"can't reattach to window");	drawscreen(1);}/*interface notescursor changes while in rbig to indicate region.only button 1 works for resizing regiononly button 1 works for moving thingy in rampbutton-3 menu: Reset, Depth, Undo, Save, Write*/Cursor tl = {	{-4, -4},	{0xfe, 0x00, 0x82, 0x00, 0x8c, 0x00, 0x87, 0xff, 	 0xa0, 0x01, 0xb0, 0x01, 0xd0, 0x01, 0x11, 0xff, 	 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 	 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x1f, 0x00, },	{0x00, 0x00, 0x7c, 0x00, 0x70, 0x00, 0x78, 0x00, 	 0x5f, 0xfe, 0x4f, 0xfe, 0x0f, 0xfe, 0x0e, 0x00, 	 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 	 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, }};Cursor t = {	{-7, -8},	{0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x06, 0xc0, 	 0x1c, 0x70, 0x10, 0x10, 0x0c, 0x60, 0xfc, 0x7f, 	 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff, 	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 	 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x03, 0x80, 	 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00, 	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }};Cursor tr = {	{-11, -4},	{0x00, 0x7f, 0x00, 0x41, 0x00, 0x31, 0xff, 0xe1, 	 0x80, 0x05, 0x80, 0x0d, 0x80, 0x0b, 0xff, 0x88, 	 0x00, 0x88, 0x0, 0x88, 0x00, 0x88, 0x00, 0x88, 	 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xf8, },	{0x00, 0x00, 0x00, 0x3e, 0x00, 0x0e, 0x00, 0x1e, 	 0x7f, 0xfa, 0x7f, 0xf2, 0x7f, 0xf0, 0x00, 0x70, 	 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 	 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, }};Cursor r = {	{-8, -7},	{0x07, 0xc0, 0x04, 0x40, 0x04, 0x40, 0x04, 0x58, 	 0x04, 0x68, 0x04, 0x6c, 0x04, 0x06, 0x04, 0x02, 	 0x04, 0x06, 0x04, 0x6c, 0x04, 0x68, 0x04, 0x58, 	 0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x07, 0xc0, },	{0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 	 0x03, 0x90, 0x03, 0x90, 0x03, 0xf8, 0x03, 0xfc, 	 0x03, 0xf8, 0x03, 0x90, 0x03, 0x90, 0x03, 0x80, 	 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }};Cursor br = {	{-11, -11},	{0x00, 0xf8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 	 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 	 0xff, 0x88, 0x80, 0x0b, 0x80, 0x0d, 0x80, 0x05, 	 0xff, 0xe1, 0x00, 0x31, 0x00, 0x41, 0x00, 0x7f, },	{0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 	 0x0, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 	 0x00, 0x70, 0x7f, 0xf0, 0x7f, 0xf2, 0x7f, 0xfa, 	 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x3e, 0x00, 0x00, }};Cursor b = {	{-7, -7},	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 	 0xfc, 0x7f, 0x0c, 0x60, 0x10, 0x10, 0x1c, 0x70, 	 0x06, 0xc0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, },	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	 0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 	 0x03, 0x80, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }};Cursor bl = {	{-4, -11},	{0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 	 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 	 0x11, 0xff, 0xd0, 0x01, 0xb0, 0x01, 0xa0, 0x01, 	 0x87, 0xff, 0x8c, 0x00, 0x82, 0x00, 0xfe, 0x00, },	{0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 	 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 	 0x0e, 0x00, 0x0f, 0xfe, 0x4f, 0xfe, 0x5f, 0xfe, 	 0x78, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x00, 0x0, }};Cursor l = {	{-7, -7},	{0x03, 0xe0, 0x02, 0x20, 0x02, 0x20, 0x1a, 0x20, 	 0x16, 0x20, 0x36, 0x20, 0x60, 0x20, 0x40, 0x20, 	 0x60, 0x20, 0x36, 0x20, 0x16, 0x20, 0x1a, 0x20, 	 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x03, 0xe0, },	{0x00, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 	 0x09, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x3f, 0xc0, 	 0x1f, 0xc0, 0x09, 0xc0, 0x09, 0xc0, 0x01, 0xc0, 	 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, }};Cursor boxcursor = {	{-7, -7},	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,	 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },	{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,	 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00, }};Cursor clearcursor;Cursor *corners[10] = {	&tl,	&t,	&tr,	&l,	&boxcursor,	&r,	&bl,	&b,	&br,	nil,	/* default arrow */};char *item[] = {	"Reset",	"Depth",	"Undo",	"Write",	"Exit",	nil};Menu menu = {	item, 	nil,	2};/*BUG make less flashy */voidmoveface(Image *back, Point lastp, Image *face, Point p, Point d){	draw(screen, rectaddpt(back->r, subpt(lastp, d)), back, nil, back->r.min);	draw(back, back->r, screen, nil, addpt(back->r.min, subpt(p, d)));	border(screen, rectaddpt(face->r, subpt(p, d)),		 -1, display->black, ZP);	draw(screen, rectaddpt(face->r, subpt(p, d)), 		face, nil, face->r.min);}intdragface(Mouse *m, Image *im, Point d, int x){	int i;	Point lastp;	static Image *back;	if(back == nil){		back = allocimage(display, Rect(-1,-1,49,49), display->image->chan, 0, DNofill);		if(back == nil)			sysfatal("dragface backing store: %r");	}	lastp = m->xy;	draw(back, back->r, screen, nil, addpt(back->r.min, subpt(lastp, d)));	esetcursor(&clearcursor);	do{		moveface(back, lastp, im, m->xy, d);		lastp = m->xy;	}while(*m=emouse(), m->buttons==1);	draw(screen, rectaddpt(back->r, subpt(lastp, d)), back, nil, back->r.min);	esetcursor(nil);	if(m->buttons==0){		for(i=0; i<nelem(face); i++)			if(ptinrect(m->xy, rface[i]))				return i;		if(ptinrect(m->xy, rsmall))			return -1;		return x;	}	while(*m=emouse(), m->buttons)		;	return x;}voidinitstate(void){	state.black = 0.0;	state.white = 1.0;	state.stretch = 1.0;	state.depth = 4;	state.gamma = 1.0;	setgtab(&state);	state.selr = insetrect(orig->r, 5);	sdx = Dx(state.selr);	sdy = Dy(state.selr);	if(sdx > sdy)		state.selr.max.x = state.selr.min.x+sdy;	else		state.selr.max.y = state.selr.min.y+sdx;}voidmain(int argc, char **argv){	int ccursor, i, fd, k, n, y;	uchar *data;	double gammatab[256];	Event e;	Mouse m;	Point lastp, p;	Rectangle nselr, rbig9[9];	ARGBEGIN{	default:		usage();	}ARGEND	if(argc > 1)		usage();	if(argc == 1){		if((fd = open(argv[0], OREAD)) < 0)			sysfatal("open %s: %r", argv[0]);	}else		fd = 0;	initdraw(0, 0, "mug");	if((orig = readimage(display, fd, 0)) == nil)		sysfatal("readimage: %r");	orig = grey8image(orig);	initramp();	initclamp();	initval2cmap();	bkgd = allocimagemix(display, DPaleyellow, DWhite);	small = allocimage(display, Rect(0,0,48,48), GREY4, 0, DWhite);	tmp8 = allocimage(display, Rect(0,0,48,48), GREY8, 0, DWhite);	red = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DRed);	green = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DGreen);	blue = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DBlue);	if(bkgd==nil || small==nil || tmp8==nil || red==nil || green==nil || blue==nil)		sysfatal("allocimage: %r");	n = Dx(orig->r)*Dy(orig->r);	data = emalloc(n*sizeof data[0]);	rdata = emalloc(n*sizeof rdata[0]);	if(unloadimage(orig, orig->r, data, n) != n)		sysfatal("unloadimage: %r");		for(i=0; i<256; i++)		gammatab[i] = pow((255-i)/(double)255.0, GAMMA);	for(i=0; i<n; i++)		rdata[i] = gammatab[255-data[i]];	initstate();	process(rdata, orig->r, state.selr, small);	drawscreen(1);	flushimage(display, 1);	einit(Emouse|Ekeyboard);	ccursor = 9;	for(;;){		if((n=eread(Emouse|Ekeyboard, &e))==Ekeyboard)			continue;		if(n != Emouse)			break;		m = e.mouse;		if(m.buttons&4){			ccursor = 9;			esetcursor(corners[ccursor]);			switch(emenuhit(3, &m, &menu)){			case -1:				continue;			case 0:	/* Reset */				mark();				initstate();				small = allocimage(display, Rect(0,0,48,48), CHAN1(CGrey, state.depth), 0, DWhite);				if(small == nil)					sysfatal("allocimage: %r");				process(rdata, orig->r, state.selr, small);				drawface(-1);				drawscreen(0);				break;			case 1:	/* Depth */				mark();				/* osmall = small, so no freeimage */				state.depth /= 2;				if(state.depth == 0)					state.depth = 8;				small = allocimage(display, Rect(0,0,48,48), CHAN1(CGrey, state.depth), 0, DWhite);				if(small == nil)					sysfatal("allocimage: %r");				process(rdata, orig->r, state.selr, small);				drawface(-1);				break;			case 2:	/* Undo */				undo();				break;			case 3:	/* Write */				writeface(nil, small);				break;			case 4:	/* Exit */				exits(nil);				break;			}		}					if(ptinrect(m.xy, rbig)){			rlist(rectaddpt(state.selr, subpt(rbig.min, orig->r.min)), rbig9);			for(i=0; i<9; i++)				if(ptinrect(m.xy, rbig9[i]))					break;			if(i != ccursor){				ccursor = i;				esetcursor(corners[ccursor]);			}			if(i==9)				continue;			if(m.buttons & 1){				mark();				lastp = m.xy;				while(m=emouse(), m.buttons&1){					if(move(state.selr, orig->r, subpt(m.xy, lastp), i, &nselr)){						moveframe(state.selr, nselr);						state.selr = nselr;						lastp = m.xy;						process(rdata, orig->r, state.selr, small);						drawface(-1);					}				}			}			continue;		}		if(ccursor != 9){	/* default cursor */			ccursor = 9;			esetcursor(corners[ccursor]);		}		if(ptinrect(m.xy, rramp)){			if(m.buttons != 1)				continue;			mark();			y = gamma2y(state.gamma);			if(abs(y-(m.xy.y-rramp.min.y)) > 5)				continue;			k = section(m.xy.x-rramp.min.x);			drawrampbar(green, &state);			lastp = m.xy;			while(m=emouse(), m.buttons&1){				if(!ptinrect(m.xy, rramp))					continue;				switch(k){				case -1:					continue;				case 0:					if((m.xy.x-rramp.min.x)/255.0 < state.white){						state.black = (m.xy.x-rramp.min.x)/255.0;						break;					}					continue;				case 1:					state.gamma = y2gamma(m.xy.y-rramp.min.y);					setgtab(&state);					break;				case 2:					if((m.xy.x-rramp.min.x)/255.0 > state.black){						state.white = (m.xy.x-rramp.min.x)/255.0;						break;					}					continue;				case 10:					state.black += (m.xy.x-lastp.x)/255.0;					state.white += (m.xy.x-lastp.x)/255.0;					state.gamma = y2gamma(p.y);					break;				}				process(rdata, orig->r, state.selr, small);				drawface(-1);				drawrampbar(green, &state);			}			if(m.buttons == 0){				process(rdata, orig->r, state.selr, small);				drawface(-1);				drawrampbar(red, &state);			}else				undo();			continue;		}			if(ptinrect(m.xy, rsmall)){			if(m.buttons != 1)				continue;			n=dragface(&m, small, subpt(m.xy, rsmall.min), -1);			if(n == -1)				continue;			saveface(nil, n);		}			for(i=0; i<nelem(face); i++)			if(ptinrect(m.xy, rface[i]))				break;		if(i<nelem(face) && face[i] != nil){			if(m.buttons != 1)				continue;			n=dragface(&m, face[i]->small, subpt(m.xy, rface[i].min), i);			if(n == i)				continue;			saveface(face[i], n);			continue;		}		do			m = emouse();		while(m.buttons==1);	}	exits(nil);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -