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

📄 gview.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
	r.min.x = screen->r.max.x - rt_border + framewd;	r.max.y = y0 + dy;	r.max.x = screen->r.max.x;	for (i=0; i<n; i++) {		draw(screen, r, clrtab[i].im, display->opaque, r.min);		r.min.y = r.max.y;		r.max.y += dy;	}	return dy;}Image* palette_color(Point pt, int dy, int n){				/* mouse at pt, patch size dy, n colors */	int yy;	if (screen->r.max.x - pt.x > rt_border - framewd)		return 0;	yy = pt.y - (screen->r.min.y + top_border);	if (yy<0 || yy>=n*dy)		return 0;	return clrtab[yy/dy].im;}void all_set_clr(fpolygons* fps, Image* clr){	fpolygon* p;	for (p=fps->p; p!=0; p=p->link)		p->clr = clr;}	void do_recolor(int but, Mouse* m, int alluniv){	int nclr = clr_id(DWhite);	int dy = draw_palette(nclr);	Image* clr;	if (!get_1click(but, m, 0)) {		eresized(0);		return;	}	clr = palette_color(m->xy, dy, nclr);	if (clr != 0) {		if (alluniv)			all_set_clr(&univ, clr);		else	cur_sel.fp->clr = clr;	}	eresized(0);	lift_button(but, m, Never);}/****************************** Move and rotate  ******************************/void prepare_mv(const fpolygon* fp){	Rectangle r = screen->r;	Image* scr0;	int dt = 1 + fp->thick;	r.min.x+=lft_border-dt;  r.min.y+=top_border-dt;	r.max.x-=rt_border-dt;   r.max.y-=bot_border-dt;	if (mv_bkgd!=0 && mv_bkgd->repl==0)		freeimage(mv_bkgd);	mv_bkgd = allocimage(display, r, CMAP8, 0, DNofill);	if (mv_bkgd==0)		mv_bkgd = display->white;	else {	transform tr = cur_trans();		draw(mv_bkgd, r, screen, display->opaque, r.min);		draw(mv_bkgd, sel_dot_box(&tr), sel_bkg, display->opaque, ZP);		scr0 = screen;		screen = mv_bkgd;		draw_fpoly(fp, &tr, display->white);		screen = scr0;	}}void move_fp(fpolygon* fp, double dx, double dy){	fpoint *p, *pn=fp->p+fp->n;	for (p=fp->p; p<=pn; p++) {		(p->x) += dx;		(p->y) += dy;	}	(fp->bb.min.x)+=dx;  (fp->bb.min.y)+=dy;	(fp->bb.max.x)+=dx;  (fp->bb.max.y)+=dy;}void rotate_fp(fpolygon* fp, fpoint o, double theta){	double s=sin(theta), c=cos(theta);	fpoint *p, *pn=fp->p+fp->n;	for (p=fp->p; p<=pn; p++) {		double x=p->x-o.x, y=p->y-o.y;		(p->x) = o.x + c*x - s*y;		(p->y) = o.y + s*x + c*y;	}	set_fbb(fp);}/* Move the selected fpolygon so the selected point tracks the mouse, and return   the total amount of movement.  Button but has already been held down for at   least Mv_delay milliseconds and the mouse might have moved some distance.*/fpoint do_move(int but, Mouse* m){	transform tr = cur_trans();	int bbit = Button_bit(but);	fpolygon* fp = cur_sel.fp;	fpoint loc, loc0=cur_sel.p;	double tsav = cur_sel.t;	unselect(&tr);	do {	latest_mouse(but, m);		(fp->thick)++;		/* line() DISAGREES WITH ITSELF */		draw_fpoly(fp, &tr, mv_bkgd);		(fp->thick)--;		do_untransform(&loc, &tr, &m->xy);		move_fp(fp, loc.x-cur_sel.p.x, loc.y-cur_sel.p.y);		cur_sel.p = loc;		draw_fpoly(fp, &tr, fp->clr);	} while (m->buttons & bbit);	cur_sel.t = tsav;	reselect(&tr);	loc.x -= loc0.x;	loc.y -= loc0.y;	return loc;}double dir_angle(const Point* pt, const transform* tr){	fpoint p;	double dy, dx;	do_untransform(&p, tr, pt);	dy=p.y-cur_sel.p.y;  dx=p.x-cur_sel.p.x;	return (dx==0 && dy==0) ? 0.0 : atan2(dy, dx);}/* Rotate the selected fpolygon around the selection point so as to track the   direction angle from the selected point to m->xy.  Stop when button but goes   up and return the total amount of rotation in radians.*/double do_rotate(int but, Mouse* m){	transform tr = cur_trans();	int bbit = Button_bit(but);	fpolygon* fp = cur_sel.fp;	double theta0 = dir_angle(&m->xy, &tr);	double th, theta = theta0;	do {	latest_mouse(but, m);		(fp->thick)++;		/* line() DISAGREES WITH ITSELF */		draw_fpoly(fp, &tr, mv_bkgd);		(fp->thick)--;		th = dir_angle(&m->xy, &tr);		rotate_fp(fp, cur_sel.p, th-theta);		theta = th;		draw_fpoly(fp, &tr, fp->clr);	} while (m->buttons & bbit);	unselect(&tr);	cur_sel = prev_sel;	reselect(&tr);	return theta - theta0;}/********************************* Edit menu  *********************************/typedef enum e_index {		Erecolor, Ethick, Edelete, Eundo, Erotate, Eoptions,		Emove} e_index;char* e_items[Eoptions+1];Menu e_menu = {e_items, 0, 0};typedef struct e_action {	e_index typ;			/* What type of action */	fpolygon* fp;			/* fpolygon the action applies to */	Image* clr;			/* color to use if typ==Erecolor */	double amt;			/* rotation angle or line thickness */	fpoint pt;			/* movement vector or rotation center */	struct e_action* link;		/* next in a stack */} e_action;e_action* unact = 0;			/* heads a linked list of actions */e_action* do_undo(e_action*);		/* pop off an e_action and (un)do it */e_action* save_act(e_action*,e_index);	/* append new e_action for status quo */void save_mv(fpoint movement){	unact = save_act(unact, Emove);	unact->pt = movement;}void init_e_menu(void){	char* u = "can't undo";	e_items[Erecolor] = "recolor";	e_items[Edelete] = "delete";	e_items[Erotate] = "rotate";	e_items[Eoptions-cantmv] = 0;	e_items[Ethick] = (cur_sel.fp->thick >0) ? "thin" : "thick";	if (unact!=0)		switch (unact->typ) {		case Erecolor: u="uncolor"; break;		case Ethick: u=(unact->fp->thick==0) ? "unthin" : "unthicken";			break;		case Edelete: u="undelete"; break;		case Emove: u="unmove"; break;		case Erotate: u="unrotate"; break;		}	e_items[Eundo] = u;}void do_emenu(int but, Mouse* m){	int h;	if (cur_sel.t < 0)		return;	init_e_menu();	h = emenuhit(but, m, &e_menu);	switch(h) {	case Ethick: unact = save_act(unact, h);		cur_sel.fp->thick ^= 1;		eresized(0);		break;	case Edelete: unact = save_act(unact, h);		fp_remove(&univ, cur_sel.fp);		unselect(0);		eresized(0);		break;	case Erecolor: unact = save_act(unact, h);		do_recolor(but, m, 0);		break;	case Erotate: unact = save_act(unact, h);		prepare_mv(cur_sel.fp);		if (get_1click(but, m, 0)) {			unact->pt = cur_sel.p;			unact->amt = do_rotate(but, m);		}		break;	case Eundo: unact = do_undo(unact);		break;	}}/******************************* Undoing edits  *******************************/e_action* save_act(e_action* a0, e_index typ){					/* append new e_action for status quo */	e_action* a = malloc(sizeof(e_action));	a->link = a0;	a->pt.x = a->pt.y = 0.0;	a->amt = cur_sel.fp->thick;	a->clr = cur_sel.fp->clr;	a->fp = cur_sel.fp;	a->typ = typ;	return a;}/* This would be trivial except it's nice to preserve the selection in order to make   it easy to undo a series of moves.  (There's no do_unrotate() because it's harder   and less important to preserve the selection in that case.)*/void do_unmove(e_action* a){	double tsav = cur_sel.t;	unselect(0);	move_fp(a->fp, -a->pt.x, -a->pt.y);	if (a->fp == cur_sel.fp) {		cur_sel.p.x -= a->pt.x;		cur_sel.p.y -= a->pt.y;	}	cur_sel.t = tsav;	reselect(0);}e_action* do_undo(e_action* a0)		/* pop off an e_action and (un)do it */{	e_action* a = a0;	if (a==0)		return 0;	switch(a->typ) {	case Ethick: a->fp->thick = a->amt;		eresized(0);		break;	case Erecolor: a->fp->clr = a->clr;		eresized(0);		break;	case Edelete: 		a->fp->link = univ.p;		univ.p = a->fp;		grow_bb(&univ.bb, &a->fp->bb);		eresized(0);		break;	case Emove:		do_unmove(a);		eresized(0);		break;	case Erotate:		unselect(0);		rotate_fp(a->fp, a->pt, -a->amt);		eresized(0);		break;	}	a0 = a->link;	free(a);	return a0;}/********************************* Main menu  *********************************/enum m_index {     Mzoom_in,  Mzoom_out,  Munzoom,  Mslant,    Munslant,		Msquare_up,  Mrecenter,  Mrecolor,  Mrestack,  Mread,		Mwrite,      Mexit};char* m_items[] = {"zoom in", "zoom out", "unzoom", "slant",   "unslant",		"square up", "recenter", "recolor", "restack", "read",		"write",     "exit", 0};Menu m_menu = {m_items, 0, 0};void do_mmenu(int but, Mouse* m){	int e, h = emenuhit(but, m, &m_menu);	switch (h) {	case Mzoom_in:		disp_zoomin(egetrect(but,m));		eresized(0);		break;	case Mzoom_out:		disp_zoomout(egetrect(but,m));		eresized(0);		break;	case Msquare_up:		disp_squareup();		eresized(0);		break;	case Munzoom:		init_disp();		eresized(0);		break;	case Mrecenter:		if (get_1click(but, m, &bullseye)) {			recenter_disp(m->xy);			eresized(0);			lift_button(but, m, Never);		}		break;	case Mslant:		if (cur_sel.t>=0 && prev_sel.t>=0) {			slant_disp(prev_sel.p, cur_sel.p);			eresized(0);		}		break;	case Munslant:		univ.slant_ht = univ.disp.max.y - univ.disp.min.y;		eresized(0);		break;	case Mrecolor:		do_recolor(but, m, 1);		break;	case Mrestack:		fps_invert(&univ);		eresized(0);		break;	case Mread:		e = doinput(prompt_text("File:"));		if (e==0)			eresized(0);		else if (e<0)			show_mytext(" - can't read");		else {			char ebuf[80];			snprintf(ebuf, 80, " - error line %d", e);			show_mytext(ebuf);		}		break;	case Mwrite:		if (!dooutput(prompt_text("File:")))			show_mytext(" - can't write");		break;	case Mexit:		exits("");	}}/****************************** Handling events  ******************************/void doevent(void){	ulong etype;	int mobile;	ulong mvtime;	Event	ev;	etype = eread(Emouse|Ekeyboard, &ev);	if(etype & Emouse) {		if (ev.mouse.buttons & But1) {			do_select(ev.mouse.xy);			mvtime = Never;			mobile = !cantmv && cur_sel.t>=0;			if (mobile) {				mvtime = ev.mouse.msec + Mv_delay;				prepare_mv(cur_sel.fp);			}			if (!lift_button(1, &ev.mouse, mvtime) && mobile)				save_mv(do_move(1, &ev.mouse));		} else if (ev.mouse.buttons & But2)			do_emenu(2, &ev.mouse);		else if (ev.mouse.buttons & But3)			do_mmenu(3, &ev.mouse);	}	/* no need to check (etype & Ekeyboard)--there are no keyboard commands */}/******************************** Main program ********************************/extern char* argv0;void usage(void){	int i;	fprintf(stderr,"Usage %s [options] [infile]\n", argv0);	fprintf(stderr,"option ::= -l logfile | -m | -p\n""\n""Read a polygonal line graph in an ASCII format (one x y pair per line, delimited\n""by spaces with a label after each polyline), and view it interactively.  Use\n""standard input if no infile is specified.\n""Option -l specifies a file in which to log the coordinates of each point selected.\n""(Clicking a point with button one selects it and displays its coordinates and\n""the label of its polylone.)  Option -m allows polylines to be moved and rotated.\n""The -p option plots only the vertices of the polygons.\n""The polyline labels can use the following color names:"	);	for (i=0; clrtab[i].c!=DNofill; i++)		fprintf(stderr,"%s%8s", (i%8==0 ? "\n" : "  "), clrtab[i].nam);	fputc('\n', stderr);	exits("usage");}void main(int argc, char *argv[]){	int e;	ARGBEGIN {	case 'm':		cantmv=0;		break;	case 'l':		logfil = fopen(ARGF(),"w");		break;	case 'p':		plotdots++;		break;	default:		usage();	} ARGEND;	if(initdraw(0, 0, "gview") < 0)		exits("initdraw");	einit(Emouse|Ekeyboard);	do {		e = doinput(*argv ? *argv : "-");		if (e < 0) {			fprintf(stderr,"Cannot read input file %s\n", *argv);			exits("no valid input file");		} else if (e > 0) {			fprintf(stderr,"Bad syntax at line %d of file %s\n", e, *argv ? *argv : "-");			exits("bad syntax in input");		}	} while (*argv && *++argv);	init_disp();	init_clrtab();	set_default_clrs(&univ, 0);	adjust_border(display->defaultfont);	cur_sel.t = prev_sel.t = -1;	eresized(0);	for(;;)		doevent();}

⌨️ 快捷键说明

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