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

📄 ev_display.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (range.ei_op & EI_OP_EV_OVERLAY) {		    extern Op_bdry_handle	ev_find_glyph();		    Op_bdry_handle		glyph_op_bdry;		    range.ei_op &= ~EI_OP_EV_OVERLAY;		    glyph_op_bdry = ev_find_glyph(chain, line_seq[line].pos);		    if (glyph_op_bdry) {			glyph = (Ev_overlay_handle)				LINT_CAST(glyph_op_bdry->more_info);			glyph_pos = glyph_op_bdry->pos;			if (esbuf.last_plus_one > glyph_pos) {			    ESBUF_SET_POSITION(glyph_pos);			}		    }		}		rop_to_use =		    (range.ei_op & (EI_OP_CLEAR_INTERIOR|EI_OP_CLEARED_RECT))		    ? (PIX_SRC|PIX_DST) : PIX_SRC;		esbuf_last_plus_one = esbuf.last_plus_one;		esbuf_sizeof_buf = esbuf.sizeof_buf;		if (esbuf_last_plus_one > line_seq[line+1].pos) {		    esbuf.last_plus_one = line_seq[line+1].pos;		    esbuf.sizeof_buf = esbuf.last_plus_one - esbuf.first;		}		result = ei_process(		    eih, range.ei_op, &esbuf, result.pos.x, result.pos.y,		    rop_to_use, view->pw, rect, view->rect.r_left);		/* BUG ALERT:		 * if we constrained esbuf.last_plus_one with the start		 * of the next line, ei_process returned EI_PR_BUF_EMPTIED		 * when it should have been EI_PR_HIT_RIGHT.		 */		if (esbuf.last_plus_one < esbuf_last_plus_one		&&  result.break_reason & EI_PR_BUF_EMPTIED) {		    result.break_reason = EI_PR_HIT_RIGHT;		}		esbuf.last_plus_one = esbuf_last_plus_one;		esbuf.sizeof_buf = esbuf_sizeof_buf;		switch (result.break_reason) {		  case EI_PR_BUF_EMPTIED:		    if (esbuf.last_plus_one == glyph_pos) {			ev_do_glyph(view, &glyph_pos, &glyph, &result);		    }		    if (esbuf.last_plus_one == range.last_plus_one) {			ev_range_info(chain_private->op_bdry,			    ES_INFINITY, &range);			range.ei_op |= ei_op;		    }		    goto NextBuffer;		  case EI_PR_NEWLINE:		    if (esbuf.last_plus_one == glyph_pos) {			ev_do_glyph(view, &glyph_pos, &glyph, &result);		    }		    if (break_action & EV_QUIT) {			goto Done;		    }		    result.last_plus_one++;		    ADVANCE_TO_NEW_LINE;		    rect->r_width += (rect->r_left - view->rect.r_left);		    rect->r_left = view->rect.r_left;		    if (result.last_plus_one == range.last_plus_one) {			ev_range_info(chain_private->op_bdry,			    ES_INFINITY, &range);			range.ei_op |= ei_op;		    }		    break;		  case EI_PR_HIT_RIGHT:		    result.bounds.r_width = min(result.bounds.r_width,			view->rect.r_width -			(int) ev_get(view, EV_RIGHT_MARGIN));		    switch (private->right_break) {		      case EV_CLIP: {			struct ei_span_result	span_result;			if (break_action & EV_QUIT			&& ! (break_action & EV_Q_DORBREAK))			    goto Done;			span_result = ei_span_of_group(			    eih, &esbuf, EI_SPAN_RIGHT_ONLY|EI_SPAN_LINE,			    result.last_plus_one);			if (span_result.first != ES_CANNOT_SET) {			    result.last_plus_one = span_result.last_plus_one;			    ESBUF_SET_POSITION(result.last_plus_one);			    if (result.last_plus_one >= range.last_plus_one) {				ev_range_info(chain_private->op_bdry,					      result.last_plus_one, &range);				range.ei_op |= ei_op;			    }			}			break;		      }		      case EV_WRAP_AT_WORD: {			Rect			tmp_rect;			tmp_rect = ev_rect_for_line(view, line);			if (result.last_plus_one > line_seq[line+1].pos			||  rect_right(&tmp_rect) <= rect_right(rect)) {			    result.last_plus_one = line_seq[line+1].pos;			}			if (break_action & EV_QUIT			&& ! (break_action & EV_Q_DORBREAK))			    goto Done;			if (result.last_plus_one < esbuf.first) {			    last_plus_one = result.last_plus_one-1;			    goto NextBuffer;			}			ESBUF_SET_POSITION(result.last_plus_one);			if (result.last_plus_one >= range.last_plus_one) {			    ev_range_info(chain_private->op_bdry,					  result.last_plus_one, &range);			    range.ei_op |= ei_op;			}			break;		      } /* end case EV_WRAP_AT_WORD */		      default:			if (break_action & EV_QUIT			&& ! (break_action & EV_Q_DORBREAK))			    goto Done;			break;		    } /* switch right_break */		    ADVANCE_TO_NEW_LINE;		    if (break_action & (EV_QUIT|EV_Q_DORBREAK)) {			goto Done;		    }		    rect->r_width += (rect->r_left - view->rect.r_left);		    rect->r_left = view->rect.r_left;		    break; /* case EI_PR_HIT_RIGHT */		  case EI_PR_HIT_BOTTOM:		    goto Done;		  default: break;		}		esbuf.buf += result.last_plus_one - esbuf.first;		esbuf.sizeof_buf -= result.last_plus_one - esbuf.first;		esbuf.first = result.last_plus_one;	    }NextBuffer:	    if (esbuf.last_plus_one >= stop_plus_one) {		if (glyph_pos == ES_INFINITY)		    goto Done;		if (glyph_pos < stop_plus_one)		    /* BUG ALERT! (Maybe)		     * Processing quit because of some other condition.		     * It is probably safe to quit, so lets try that.		     */		    goto Done;		/* Have to keep painting until all of text under		 * glyph has been displayed.		 */		glyph_save_result = result;		stop_plus_one = glyph_pos;	    }	}Done:	rect->r_left = save_left;	rect->r_width = save_width;	ASSUME(line_table_is_consistent(view->line_table));	return((glyph_save_result.break_reason == EI_PR_OUT_OF_RANGE)		? result : glyph_save_result);}extern Ev_expand_statusev_expand(view, start, stop_plus_one, out_buf, out_buf_len, total_chars)	register Ev_handle	 view;	Es_index		 start;	/* Entity to start expanding at */	Es_index		 stop_plus_one; /* 1st ent not expanded */	char			*out_buf;	int			 out_buf_len;	int			*total_chars;/* Expand the contents of the view from first to stop_plus_one into * the set of characters used to paint them, placing the expanded * text into out_buf, returning the number of character placed into * out_buf in total_chars, and returning status. */{	Ev_chain			chain = view->view_chain;	char				buf[EV_BUFSIZE];	char				dummy_buf[EV_BUFSIZE];	Es_buf_object			esbuf;	Rect				rect;	struct ei_process_result	result;	struct ei_process_result	expand_result;	struct ei_span_result		span_result;	int				dummy_total = 0;	Ev_expand_status		status = EV_EXPAND_OKAY;	if (!out_buf)	    out_buf = dummy_buf;	if (!total_chars)	    total_chars = &dummy_total;	*total_chars = 0;	if (start >= stop_plus_one)	    return(status);	rect = view->rect;	/*	 *  Find the first Es_index in file line.	 */	esbuf.esh = chain->esh;	esbuf.buf = buf;	esbuf.sizeof_buf = sizeof(buf);	esbuf.first = esbuf.last_plus_one = 0;	span_result = ei_span_of_group(	    chain->eih, &esbuf, EI_SPAN_LINE|EI_SPAN_LEFT_ONLY, start);	/*	 *  Find the x position of start.	 */	result.last_plus_one = span_result.first;	result.pos.x = rect.r_left = view->rect.r_left;	result.pos.y = rect.r_top = view->rect.r_top;	result.break_reason = EI_PR_HIT_RIGHT;	es_set_position(chain->esh, span_result.first);	while (result.break_reason == EI_PR_HIT_RIGHT) {	    result = ev_ei_process(view, result.last_plus_one, start);	    if (result.break_reason == EI_PR_NEWLINE	    ||  result.break_reason == EI_PR_END_OF_STREAM) {		/* ei_span_of_group() failed; return error. */		status = EV_EXPAND_OTHER_ERROR;		return(status);	    }	}	/*	 *  Expand from start to stop_plus_one into out_buf.	 */	expand_result.last_plus_one = 0;	expand_result.pos.x = rect.r_left = view->rect.r_left;	expand_result.pos.y = rect.r_top = view->rect.r_top;	expand_result.break_reason = EI_PR_HIT_RIGHT;	/* Offset first, last_plus_one by what's in the buffer */	(void) es_make_buf_include_index(&esbuf, start, 0);	esbuf.last_plus_one = min(stop_plus_one, start+esbuf.sizeof_buf);	while ((expand_result.break_reason == EI_PR_HIT_RIGHT	|| expand_result.break_reason == EI_PR_NEWLINE)	&& out_buf_len > expand_result.last_plus_one	&& esbuf.first < esbuf.last_plus_one) {	    expand_result = ei_expand(		chain->eih, &esbuf, &rect, result.pos.x,		out_buf + expand_result.last_plus_one,		out_buf_len - expand_result.last_plus_one,		view->rect.r_left);	    if (expand_result.break_reason == EI_PR_HIT_RIGHT) {		result.pos.x = view->rect.r_left;	    }	    *total_chars += expand_result.last_plus_one;	}	switch (expand_result.break_reason) {	  case EI_PR_BUF_FULL:	    status = EV_EXPAND_FULL_BUF;	    break;	  case EI_PR_BUF_EMPTIED:	    break;	  default:	    status = EV_EXPAND_OTHER_ERROR;	}	return(status);}#ifdef DEBUGstatic int special;static int max_valid_val = 100000;static intline_table_is_consistent(table)	Ev_line_table		table;{	int			lt_index, prev_val = -1;	Ev_impl_line_seq	line_seq = (Ev_impl_line_seq) table.seq;	if (special == -1)	    return(TRUE);	for (lt_index = 0; lt_index < table.last_plus_one; lt_index++) {	    if (line_seq[lt_index].pos <= prev_val) {		if ((line_seq[lt_index].pos != prev_val) ||		    (line_seq[lt_index].pos != ES_INFINITY)) {		    LINT_IGNORE(ASSUME(0));		    return(FALSE);		}	    }	    prev_val = line_seq[lt_index].pos;	    ASSUME(prev_val < max_valid_val || prev_val == ES_INFINITY);	}	return(TRUE);}#endifev_line_for_y(view, y)	Ev_handle	view;	int		y;{	return((y - view->rect.r_top) / ei_line_height(view->view_chain->eih));}Es_indexev_index_for_line(view, line)	Ev_handle	view;	int		line;{	Ev_impl_line_seq	line_seq = (Ev_impl_line_seq)						view->line_table.seq;	if (line < 0 || line >= view->line_table.last_plus_one)	    line = 0;	return(line_seq[line].pos);}Es_indexev_considered_for_line(view, line)	Ev_handle	view;	int		line;{	Ev_impl_line_seq	line_seq = (Ev_impl_line_seq)						view->line_table.seq;	if (line < 0 || line >= view->line_table.last_plus_one)	    line = 0;	return(line_seq[line].pos + line_seq[line].considered);}struct rectev_rect_for_line(view, line)	Ev_handle	view;	int		line;{	struct rect	result;	result = view->rect;	result.r_height = ei_line_height(view->view_chain->eih);	result.r_top += line * result.r_height;	return(result);}ev_extend_to_view_bottom(view, rect)	Ev_handle	 view;	struct rect	*rect;{	rect->r_height =	    view->rect.r_height - (rect->r_top - view->rect.r_top);}Ev_handleev_resolve_xy_to_view(views, x, y)	Ev_chain		 views;	register int		 x, y;{	register Ev_handle	result;	FORALLVIEWS(views, result) {	    if (rect_includespoint(&result->rect, x, y))		return(result);	}	return(EV_NULL);}/* * Following rect_* should be in rect package! */static intrect_nearest_edge(minimum, delta, val)	int	minimum, delta, val;{	return((val <= minimum) ? minimum	       : ((val > (minimum+delta)) ? (minimum+delta) : val));}Ev_handleev_nearest_view(views, x, y, x_used, y_used)	Ev_chain		 views;	register int		 x, y;	register int		*x_used, *y_used;{	register Ev_handle	 result = ev_resolve_xy_to_view(views, x, y);	register Ev_handle	 view;	int			 near_x, near_y;	int			 min_dist_sq = 0x7FFFFFFF;	register int		 dist_sq, temp;	if (result == EV_NULL) {	    FORALLVIEWS(views, view) {		near_x = rect_nearest_edge(view->rect.r_left,					   view->rect.r_width, x);		near_y = rect_nearest_edge(view->rect.r_top,					   view->rect.r_height, y);		temp = (near_x - x);		dist_sq = temp*temp;		temp = (near_y - y);		dist_sq += temp*temp;		if (dist_sq < min_dist_sq) {		    min_dist_sq = dist_sq;		    result = view;		    if (x_used) *x_used = near_x;		    if (y_used) *y_used = near_y;		}	    }	} else {	    if (x_used) *x_used = x;	    if (y_used) *y_used = y;	}	return(result);}Es_indexev_resolve_xy(view, x, y)	Ev_handle	 view;	int		 x, y;{	Es_handle			esh = view->view_chain->esh;	Es_index			result = ES_INFINITY;	int				lt_index;	struct rect			rect;	Ev_impl_line_seq		line_seq;	struct ei_process_result	p_result;	if (view == EV_NULL)	    return(result);	line_seq = (Ev_impl_line_seq) view->line_table.seq;	lt_index = ev_line_for_y(view, y);	rect = ev_rect_for_line(view, lt_index);	rect.r_width = x - rect.r_left;	if (line_seq[lt_index].pos != ES_INFINITY) {	    if (lt_index+1 == view->line_table.last_plus_one) {		/* Incorrect to measure last line in line_table. */		p_result.break_reason = EI_PR_HIT_BOTTOM;		p_result.last_plus_one = line_seq[lt_index].pos;	    } else {		es_set_position(esh, line_seq[lt_index].pos);		p_result = ev_display_internal(		    view, &rect, lt_index, ES_INFINITY,		    EI_OP_MEASURE, EV_QUIT);	    }	    if (p_result.break_reason == EI_PR_OUT_OF_RANGE ||		p_result.break_reason & EI_PR_END_OF_STREAM) {		goto AtEnd;	    } else {		ASSUME(p_result.break_reason < EI_PR_NEXT_FREE);		result = p_result.last_plus_one;		if ((p_result.break_reason & EI_PR_HIT_RIGHT)		&&  result >= line_seq[lt_index+1].pos) {		    --result;		}	    }	} else {AtEnd:	    result = es_get_length(esh);	}	return(result);}		/* Missing window system utilities. */intrect_is_fully_visible(pw, rect)	register struct pixwin	*pw;	register struct rect	*rect;/* * It only makes sense to call this routine inside a pw_lock/unlock pair, else *   the answer can be obsoleted by another window's movement in the tree. */{	struct rectlist		 intersection;	int			 result;	if (pw->pw_clipdata->pwcd_regionrect &&	    !rect_includesrect(pw->pw_clipdata->pwcd_regionrect, rect))	    return(0);	intersection = rl_null;	rl_rectintersection(	    rect, &pw->pw_clipdata->pwcd_clipping, &intersection);	rl_coalesce(&intersection);	result = rl_equalrect(rect, &intersection);	rl_free(&intersection);	return(result);}

⌨️ 快捷键说明

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