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

📄 redraw.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This function draws a single line of text on the screen, possibly with * some cursor optimization.  The cursor is repositioned before drawing * begins, so its position before doesn't really matter. */static void smartdrawtext(text, lno, showit)	REG char	*text;	/* the text to draw */	long		lno;	/* line number of the text */	int		showit;	/* boolean: output line? (else just remember it) */{#ifdef CRUNCH	move((int)(lno - topline), 0);	if (showit)	{		drawtext(text, lno, TRUE);	}#else /* not CRUNCH */	static char	old[256];	/* how the line looked last time */	char		new[256];	/* how it looks now */	char		*build;		/* used to put chars into new[] */	char		*scan;		/* used for moving thru new[] or old[] */	char		*end;		/* last non-blank changed char */	char		*shift;		/* used to insert/delete chars */	int		same;		/* length of a run of unchanged chars */	int		limitcol;	int		col;	int		i;	char		numstr[9];# ifndef NO_CHARATTR	/* if this line has attributes, do it the dumb way instead */	if (hasattr(lno, text))	{		move((int)(lno - topline), 0);		drawtext(text, lno, TRUE);		return;	}# endif# ifndef NO_SENTENCE	/* if this line is a format line, & we're hiding format lines, then	 * let the dumb drawtext() function handle it	 */	if (*o_hideformat && *text == '.')	{		move((int)(lno - topline), 0);		drawtext(text, lno, TRUE);		return;	}# endif# ifndef NO_VISIBLE	if (vizchange)	{		move((int)(lno - topline), 0);		drawtext(text, lno, TRUE);		smartlno = 0L;		return;	}# endif	/* skip stuff that was scrolled off left edge */	limitcol = leftcol;	for (col = 0;	     (i = *text) && col < limitcol; /* yes, ASSIGNMENT! */	     text++)	{		if (i == '\t' && !*o_list)		{			col = col + *o_tabstop - (col % *o_tabstop);		}		else if (i >= 0 && i < ' ' || i == '\177')		{			col += 2;		}		else		{			col++;		}	}	/* adjust for control char that was partially visible */	build = new;	while (col > limitcol)	{		*build++ = ' ';		limitcol++;	}	/* now for the visible characters */	limitcol = leftcol + COLS;	if (*o_number)		limitcol -= 8;	for (; (i = *text) && col < limitcol; text++)	{		if (i == '\t' && !*o_list)		{			i = col + *o_tabstop - (col % *o_tabstop);			while (col < i && col < limitcol)			{				*build++ = ' ';				col++;			}		}		else if (i >= 0 && i < ' ' || i == '\177')		{			col += 2;			*build++ = '^';			if (col <= limitcol)			{				*build++ = (i ^ '@');			}		}		else		{			col++;			*build++ = i;		}	}	if (col < limitcol && *o_list)	{		*build++ = '$';		col++;	}	end = build;	while (col < limitcol)	{		*build++ = ' ';		col++;	}	/* if we're just supposed to remember this line, then remember it */	if (!showit)	{		smartlno = lno;		strncpy(old, new, COLS);		return;	}	/* locate the last non-blank character */	while (end > new && end[-1] == ' ')	{		end--;	}	/* can we optimize the displaying of this line? */	if (lno != smartlno)	{		/* nope, can't optimize - different line */		move((int)(lno - topline), 0);		/* show the line number, if necessary */		if (*o_number)		{			sprintf(numstr, "%6ld |", lno);			qaddstr(numstr);		}		/* show the new line */		for (scan = new, build = old; scan < end; )		{			qaddch(*scan);			*build++ = *scan++;		}		if (end < new + COLS - (*o_number ? 8 : 0))		{			clrtoeol();			while (build < old + COLS)			{				*build++ = ' ';			}		}		smartlno = lno;		return;	}	/* skip any initial unchanged characters */	for (scan = new, build = old; scan < end && *scan == *build; scan++, build++)	{	}	i = (scan - new);	if (*o_number)		i += 8;	move((int)(lno - topline), i);	/* The in-between characters must be changed */	same = 0;	while (scan < end)	{		/* is this character a match? */		if (scan[0] == build[0])		{			same++;		}		else /* do we want to insert? */		if (scan < end - 1 && scan[1] == build[0] && (has_IC || has_IM))		{			nudgecursor(same, scan, new, lno);			same = 0;			insch(*scan);			for (shift = old + COLS; --shift > build; )			{				shift[0] = shift[-1];			}			*build = *scan;		}		else /* do we want to delete? */		if (build < old + COLS - 1 && scan[0] == build[1] && has_DC)		{			nudgecursor(same, scan, new, lno);			same = 0;			delch();			same++;			for (shift = build; shift < old + COLS - 1; shift++)			{				shift[0] = shift[1];			}			if (*o_number)				shift -= 8;			*shift = ' ';		}		else /* we must overwrite */		{			nudgecursor(same, scan, new, lno);			same = 0;			addch(*scan);			*build = *scan;		}		build++;		scan++;	}	/* maybe clear to EOL */	end = old + COLS - (*o_number ? 8 : 0);	while (build < end && *build == ' ')	{		build++;	}	if (build < end)	{		nudgecursor(same, scan, new, lno);		same = 0;		clrtoeol();		while (build < old + COLS)		{			*build++ = ' ';		}	}#endif /* not CRUNCH */}/* This function is used in visual mode for drawing the screen (or just parts * of the screen, if that's all thats needed).  It also takes care of * scrolling. */void redraw(curs, inputting)	MARK	curs;		/* where to leave the screen's cursor */	int	inputting;	/* boolean: being called from input() ? */{	char		*text;		/* a line of text to display */	static long	chgs;		/* previous changes level */	long		l;	int		i;#ifndef CRUNCH	static long	showtop;	/* top line in window */	static long	showbottom;	/* bottom line in window */#endif	/* if curs == MARK_UNSET, then we should reset internal vars */	if (curs == MARK_UNSET)	{		if (topline < 1 || topline > nlines)		{			topline = 1L;		}		else		{			move(LINES - 1, 0);			clrtoeol();		}		leftcol = 0;		mustredraw = TRUE;		redrawafter = INFINITY;		preredraw = 0L;		postredraw = 0L;		chgs = 0;		smartlno = 0L;#ifndef NO_VISIBLE		vizlow = vizhigh = 0L;		vizchange = FALSE;#endif#ifndef CRUNCH		showtop = 0;		showbottom = INFINITY;#endif		return;	}#ifndef NO_VISIBLE	/* adjustments to hilited area may force extra lines to be redrawn. */	setviz(curs);#endif	/* figure out which column the cursor will be in */	l = markline(curs);	text = fetchline(l);	mark2phys(curs, text, inputting);#ifndef NO_COLOR	fixcolor();#endif	/* adjust topline, if necessary, to get the cursor on the screen */	if (l >= topline && l <= botline)	{		/* it is on the screen already */		/* if the file was changed but !mustredraw, then redraw line */		if (!mustredraw && (chgs != changes#ifndef NO_VISIBLE			|| V_from#endif#ifndef CRUNCH			|| l < showtop || l > showbottom#endif							))		{			smartdrawtext(text, l, (chgs != changes));		}	}	else if (l < topline && l > topline - LINES && (has_SR || has_AL))	{		/* near top - scroll down */		if (!mustredraw)		{			move(0,0);			while (l < topline)			{				topline--;				if (has_SR)				{					do_SR();				}				else				{					insertln();				}				text = fetchline(topline);				drawtext(text, topline, FALSE);				do_UP();			}			/* blank out the last line */			move(LINES - 1, 0);			clrtoeol();		}		else		{			topline = l;			redrawrange(0L, INFINITY, INFINITY);		}	}	else if (l > topline && l < botline + LINES)	{		/* near bottom -- scroll up */		if (!mustredraw)		{			move(LINES - 1,0);			clrtoeol();			while (l > botline)			{				topline++; /* <-- also adjusts botline */				text = fetchline(botline);				drawtext(text, botline, FALSE);			}#ifndef CRUNCH			showbottom = l;#endif		}		else		{			topline = l - (LINES - 2);			redrawrange(0L, INFINITY, INFINITY);		}	}	else	{		/* distant line - center it & force a redraw */		topline = l - (LINES / 2) - 1;		if (topline < 1)		{			topline = 1;		}		redrawrange(0L, INFINITY, INFINITY);		changes++;	}#ifndef CRUNCH	/* make sure the current line is included in the "window" */	if (l < showtop)	{		redrawrange(l, showtop, showtop);		showtop = l;	}	if (l > showbottom)	{		redrawrange(showbottom, l, l);		showbottom = l;	}#endif	/* Now... do we really have to redraw? */	if (mustredraw)	{		/* If redrawfter (and friends) aren't set, assume we should		 * redraw everything.		 */		if (redrawafter == INFINITY)		{			redrawafter = 0L;			preredraw = postredraw = INFINITY;		}#ifndef CRUNCH		/* shrink the window, if possible */		if (showtop < topline)		{			showtop = topline;		}		if (showbottom > botline)		{			showbottom = botline;		}		if (postredraw == INFINITY)		{			/* these will be set to more reasonable values later */			showtop = INFINITY;			showbottom = 0L;		}#endif		/* adjust smartlno to correspond with inserted/deleted lines */		if (smartlno >= redrawafter)		{			if (smartlno < preredraw && postredraw != preredraw) /*!!!*/			{				smartlno = 0L;			}			else			{				smartlno += (postredraw - preredraw);			}		}		/* should we insert some lines into the screen? */		if (preredraw < postredraw && preredraw <= botline)		{			/* lines were inserted into the file */			/* decide where insertion should start */			if (preredraw < topline)			{				l = topline;			}			else			{				l = preredraw;			}			/* insert the lines... maybe */			if (l + postredraw - preredraw > botline || !has_AL || *o_number)			{				/* Whoa!  a whole screen full - just redraw */				preredraw = postredraw = INFINITY;			}			else			{				/* really insert 'em */				move((int)(l - topline), 0);				for (i = postredraw - preredraw; i > 0; i--)				{					insertln();				}				/* NOTE: the contents of those lines will be				 * drawn as part of the regular redraw loop.				 */				/* clear the last line */				move(LINES - 1, 0);				clrtoeol();			}		}		/* do we want to delete some lines from the screen? */		if (preredraw > postredraw && postredraw <= botline)		{			if (preredraw > botline || !has_DL || *o_number)			{				postredraw = preredraw = INFINITY;			}			else /* we'd best delete some lines from the screen */			{				/* clear the last line, so it doesn't look				 * ugly as it gets pulled up into the screen				 */				move(LINES - 1, 0);				clrtoeol();				/* delete the lines */				move((int)(postredraw - topline), 0);			 	for (l = postredraw;				     l < preredraw && l <= botline;				     l++)				{					deleteln();				}				/* draw the lines that are now newly visible				 * at the bottom of the screen				 */				i = LINES - 1 + (postredraw - preredraw);				move(i, 0);				for (l = topline + i; l <= botline; l++)				{					/* clear this line */					clrtoeol();					/* draw the line, or ~ for non-lines */					if (l <= nlines)					{						text = fetchline(l);						drawtext(text, l, FALSE);					}					else					{						addstr("~\n");					}				}			}		}		/* redraw the current line */		l = markline(curs);		pfetch(l);		smartdrawtext(ptext, l, TRUE);#ifndef CRUNCH		/* decide which lines must be in the "window" around the cursor */		l = markline(curs);		if ((*o_window & 0xff) + 1 == LINES)		{			showtop = 1;			showbottom = INFINITY;		}		else if (l < showtop || l > showbottom)		{			l -= (*o_window & 0xff) / 2;			if (l < topline)			{				l = topline;			}			if (l < showtop)			{				showtop = l;			}			l += (*o_window & 0xff) - 1;			if (l > botline)			{				showtop = showtop - l + botline;				l = botline;			}			if (l > showbottom)			{				showbottom = l;			}		}#endif		/* decide where we should start redrawing from */		if (redrawafter < topline)		{			l = topline;		}		else		{			l = redrawafter;		}		if (l <= botline && l < postredraw && (l != smartlno || botline != smartlno))		{			/* draw the other lines */			move((int)(l - topline), 0);			for (; l <= botline && l < postredraw; l++)			{				/* we already drew the current line, so skip it now */				if (l == smartlno)				{#if OSK					qaddch('\l');#else					qaddch('\n');#endif					continue;				}				/* draw the line, or ~ for non-lines */				if (l > nlines)				{					qaddch('~');					clrtoeol();					addch('\n');				}#ifndef CRUNCH				else if (l < showtop || l > showbottom)				{					qaddch('@');					clrtoeol();					addch('\n');				}#endif				else				{					text = fetchline(l);					drawtext(text, l, TRUE);				}			}		}		mustredraw = FALSE;	}	/* force total (non-partial) redraw next time if not set */	redrawafter = INFINITY;	preredraw = 0L;	postredraw = 0L;	/* move the cursor to where it belongs */	move((int)(markline(curs) - topline), physcol);	wqrefresh();	chgs = changes;}

⌨️ 快捷键说明

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