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

📄 ev_op_bdry.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)ev_op_bdry.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986, 1987 by Sun Microsystems, Inc. *//* * Maintenance of fingers into an entity stream. * Each finger represents a boundary at which an incremental change to the *   rendering is recorded, e.g. begin/end primary/secondary selection. * Each such change may, but need not, change the pixel painting operations *   used by the rendering. * Note that a particular position may occur in multiple fingers. */#include <suntool/primal.h>#include <suntool/ev_impl.h>extern Es_index	ev_position_for_physical_line();pkg_private void	ev_clear_from_margins();static Ev_finger_handle	ev_insert_finger();static Ev_mark_object	last_generated_id;#define FORALL(index_var)						\	for (index_var = 0; index_var < fingers->last_plus_one; index_var++)extern Ev_finger_handleev_add_finger(fingers, pos, client_data, id_handle)	Ev_finger_table		*fingers;	register Es_index	 pos;	opaque_t		 client_data;	Ev_mark			 id_handle;{	register Es_index	*seq = fingers->seq;	register int		 addr_delta = fingers->sizeof_element;	register int		 index;#ifdef notdef	FORALL(index) {	    if (*seq > pos)		break;	    seq = FT_NEXT_ADDR(seq, addr_delta);	}#endif notdef	index = ft_bounding_index((Ft_table)fingers, pos);	if (index == fingers->last_plus_one) {	    index = 0;	} else if (index < fingers->last_plus_one) {	    index++;	}	if (!EV_MARK_MOVE_AT_INSERT(*id_handle)) {	    for (seq = FT_ADDR(fingers, index-1, addr_delta); index > 0; index--, seq = FT_PREV_ADDR(seq, addr_delta)) {		if (*seq != pos)		    break;		if (!EV_MARK_MOVE_AT_INSERT(((Ev_finger_handle)seq)->info))		    break;	    }	}	return(ev_insert_finger(fingers, pos, client_data,				(unsigned)index, id_handle));}extern Ev_markev_init_mark(mark)	register Ev_mark	mark;{	*mark = 0;}#define EXPAND_BY 30static Ev_finger_handleev_insert_finger(fingers, pos, client_data, before, id_handle)	register Ev_finger_table	*fingers;	Es_index			 pos;	opaque_t			 client_data;			/* insert before this index: */	unsigned			 before;	register Ev_mark		 id_handle;{	register Ev_finger_handle	finger;	register int			expand_by = EXPAND_BY;	/* If the table has gotten large, expand faster */	if (fingers->last_plus_one > 99) {	    expand_by = fingers->last_plus_one >> 1;	}	(void) ft_shift_up(fingers, (int)before, (int)before+1, expand_by);	finger = (Ev_finger_handle) FT_ADDRESS(fingers, before);	finger->pos = pos;	finger->client_data = client_data;	if (id_handle == 0) {	    last_generated_id++;	    finger->info = last_generated_id;	} else if (EV_MARK_IS_NULL(id_handle)) {	    last_generated_id++;	    *id_handle = EV_MARK_MOVE_AT_INSERT(*id_handle) |			 EV_MARK_ID(last_generated_id);	    finger->info = *id_handle;	} else	    finger->info = *id_handle;	return(finger);}Ev_finger_handleev_find_finger(fingers, mark)	Ev_finger_table		*fingers;	Ev_mark_object		 mark;{	register int		 i = ev_find_finger_internal(fingers, &mark);	return((i < fingers->last_plus_one)		? (Ev_finger_handle)FT_ADDRESS(fingers, i)		: (Ev_finger_handle)0);}static intev_find_finger_internal(fingers, mark)	Ev_finger_table		*fingers;	Ev_mark		 	 mark;{	register Ev_finger_handle	 finger =					 (Ev_finger_handle) fingers->seq;	register int			 i, mark_id;	if ((mark_id = EV_MARK_ID(*mark)) != 0) {	    if (EV_MARK_ID(finger->info) == mark_id) {	        return(0);	    }	    i = ft_bounding_index(fingers, ES_INFINITY -1);	    if (i != fingers->last_plus_one) {		finger = (Ev_finger_handle) FT_ADDRESS(fingers, i);		if (EV_MARK_ID(finger->info) == mark_id) {		    return(i);		} {		    finger = (Ev_finger_handle) fingers->seq;		}	    }	    for(i = 1; i < fingers->last_plus_one; i++) {		finger = (Ev_finger_handle) FT_NEXT_ADDRESS(fingers, finger);		if (EV_MARK_ID(finger->info) == mark_id)		    return(i);	    }	}	return(fingers->last_plus_one);}ev_remove_finger(fingers, mark)	Ev_finger_table		*fingers;	Ev_mark_object		 mark;{	int			 i = ev_find_finger_internal(fingers, &mark);	ev_remove_finger_internal(fingers, i);}staticev_remove_finger_internal(fingers, i)	register Ev_finger_table	*fingers;	int				 i;{	if (i < fingers->last_plus_one) {	    (void) ft_shift_out(fingers, i, i+1);	} else LINT_IGNORE(ASSUME(0));	/* There should be an entry */}extern Op_bdry_handleev_add_op_bdry(op_bdry, pos, type, mark)	Ev_finger_table		*op_bdry;	Es_index		 pos;	unsigned		 type;	Ev_mark			 mark;{	Op_bdry_handle		 bdry;	bdry = (Op_bdry_handle)		ev_add_finger(op_bdry, pos, (opaque_t)type, mark);	bdry->more_info = (opaque_t) 0;	return(bdry);}Op_bdry_handleev_find_op_bdry(op_bdry, mark)	Ev_finger_table		op_bdry;	Ev_mark_object		mark;{	return((Op_bdry_handle) ev_find_finger(&op_bdry, mark));}/* Caller must ensure that i is the first of the entries being merged. */unsignedev_op_bdry_info_merge(op_bdry, i, next_i, prior)	Ev_finger_table		 op_bdry;	register int		 i;	int			*next_i;	unsigned		 prior;{	register Op_bdry_handle	 seq = (Op_bdry_handle) op_bdry.seq;	int			 pos = seq[i].pos;	register unsigned	 result = prior;	while (i < op_bdry.last_plus_one) {	    if (seq[i].flags & EV_BDRY_END) {		ASSUME(result & seq[i].flags);		result &= ~seq[i].flags;	    } else {		ASSUME(!(result & seq[i].flags));		result |= seq[i].flags;	    }	    if (pos != seq[++i].pos)		break;	}	if (next_i)	    *next_i = i;	return(result);}unsignedev_op_bdry_info(op_bdry, pos, next_i)	Ev_finger_table		 op_bdry;	Es_index		 pos;	int			*next_i;{	register Op_bdry_handle	 seq = (Op_bdry_handle) op_bdry.seq;	int			 i = 0;	register unsigned	 result = 0;	while ((i < op_bdry.last_plus_one) && (seq[i].pos <= pos)) {	    result = ev_op_bdry_info_merge(op_bdry, i, &i, result);	}	if (next_i)	    *next_i = i;	return(result);}ev_remove_op_bdry(op_bdry, pos, type, mask)	Ev_finger_table		*op_bdry;	register Es_index	 pos;	unsigned		 type;	register unsigned	 mask;{	register Op_bdry_handle	seq = (Op_bdry_handle) op_bdry->seq;	register int		i, last_plus_one = op_bdry->last_plus_one;	register unsigned	masked_type = type & mask;	i = ft_index_for_position(*op_bdry, pos);	if (i == last_plus_one)	    goto Return;	while (i < last_plus_one && seq[i].pos == pos) {	    if (masked_type == (seq[i].flags & mask)) {		ev_remove_finger_internal(op_bdry, i);		goto Return;	    }	    i++;	}	LINT_IGNORE(ASSUME(0));	/* There should be an entry */Return:	return;}extern Ev_mark_objectev_add_glyph(chain, line_start, pos, pr, op, offset_x, offset_y, flags)	register Ev_chain		 chain;	register Es_index		 line_start, pos;	Pixrect				*pr;	int				 op;	int				 offset_x, offset_y;	register int			 flags;{	Ev_chain_pd_handle		 private = EV_CHAIN_PRIVATE(chain);	register Op_bdry_handle		 bdry;	register Ev_overlay_handle	 glyph_info;	Ev_mark_object			 result;	(void) ev_init_mark(&result);	if ((pos < 0) || (pr == 0) || (offset_y != 0)	|| ((offset_x >= 0) && !(flags & EV_GLYPH_LINE_END))	|| ((offset_x < 0) && (flags & EV_GLYPH_LINE_END))) {	    LINT_IGNORE(ASSUME(0));	/* Let implementor look at this. */	    return(result);	}	bdry = ev_add_op_bdry(&private->op_bdry, line_start,			      EV_BDRY_OVERLAY, &result);	glyph_info = NEW(Ev_overlay_object);	bdry->more_info = (opaque_t) glyph_info;	glyph_info->pr = pr;	glyph_info->pix_op = op;	glyph_info->offset_x = offset_x;	glyph_info->offset_y = offset_y;	if (flags & EV_GLYPH_LINE_END)	    glyph_info->flags |= EV_OVERLAY_RIGHT_MARGIN;	(void) ev_init_mark(&result);	/* Get the next generated id */	if (pos == line_start) {	    /* Force pos > line_start so that ev_display_internal will have	     * an EI_OP_EV_OVERLAY show up in its range.info.	     */	    extern struct ei_process_result	ev_ei_process();	    struct ei_process_result		ei_process_result;	    pos++;	    ei_process_result =		ev_ei_process(chain->first_view, line_start, pos);	    glyph_info->offset_x -= ei_process_result.bounds.r_width;	}	bdry = ev_add_op_bdry(&private->op_bdry, pos,			      EV_BDRY_OVERLAY|EV_BDRY_END, &result);	bdry->more_info = (opaque_t) glyph_info;	/* What is painted depends on whether glyph_count is positive, so	 * increment it before painting.	 */	private->glyph_count++;	if (flags & EV_GLYPH_DISPLAY) {	    (void) ev_display_range(chain, line_start, pos);	}	return(result);}extern Ev_mark_objectev_add_glyph_on_line(chain, line, pr, op, offset_x, offset_y, flags)	register Ev_chain	 chain;	int			 line;	Pixrect			*pr;	int			 op;	int			 offset_x, offset_y;	register int		 flags;{	register Es_index	 line_start;	Es_index		 first, pos;	Ev_mark_object		 result;	ev_init_mark(&result);	if (line < 0) {	    LINT_IGNORE(ASSUME(0));	/* Let implementor look at this. */	    return(result);	}	line_start = ev_position_for_physical_line(chain, line, 0);	if (line_start == ES_CANNOT_SET) {	    LINT_IGNORE(ASSUME(0));	/* Let implementor look at this. */	    return(result);	}	if ((flags & (EV_GLYPH_LINE_START | EV_GLYPH_LINE_END))	&& !(flags & EV_GLYPH_WORD_START)) {	    pos = line_start;	} else {	    ev_span(chain, line_start, &first, &pos,		  EI_SPAN_SP_AND_TAB|EI_SPAN_RIGHT_ONLY|EI_SPAN_IN_CLASS_ONLY);	    if (first == ES_CANNOT_SET)		pos = line_start;	}	result = ev_add_glyph(chain, line_start, pos, pr, op,			      offset_x, offset_y, flags);	return(result);}extern Op_bdry_handleev_find_glyph(chain, line_start)	Ev_chain	chain;	Es_index	line_start;{	register Ev_chain_pd_handle	private = EV_CHAIN_PRIVATE(chain);	register Op_bdry_handle		bdry;	register Op_bdry_handle		seq = (Op_bdry_handle)						private->op_bdry.seq;	register int			i, last_plus_one;	i = ft_index_for_position(private->op_bdry, line_start);	last_plus_one = private->op_bdry.last_plus_one;	if (i == last_plus_one)	    goto Return;	while (i < last_plus_one && seq[i].pos == line_start) {	    if (seq[i].flags & EV_BDRY_OVERLAY	    && !(seq[i].flags & EV_BDRY_END)) {		bdry = &seq[i];		break;	    }	    i++;	}	for (i++; i < last_plus_one; i++) {	    if (((seq[i].flags & (EV_BDRY_OVERLAY|EV_BDRY_END)) ==		    (EV_BDRY_OVERLAY|EV_BDRY_END)) &&		(seq[i].more_info == bdry->more_info)) {		return(&seq[i]);	    }	}Return:	LINT_IGNORE(ASSUME(0));	/* There should be an entry */	return(0);}static voidev_clear_margins(view, pos, lt_index, rect)	register Ev_handle	 view;	register Es_index	 pos;	register int		 lt_index;	register Rect		*rect;/* * If rect is not NULL, believe it, * else if lt_index is in range, construct the rect from it, * else construct the rect for the line containing pos. */{	extern Rect		 ev_rect_for_line();	Rect			 dummy_rect;	if (rect == 0) {	    rect = &dummy_rect;	    if (lt_index < 0 || lt_index >= view->line_table.last_plus_one) {		int		 dummy_lt_index;		switch (ev_xy_in_view(view, pos, &dummy_lt_index, rect)) {		  case EV_XY_VISIBLE:		    break;		  default:		    return;		}		lt_index = dummy_lt_index;	    } else		*rect = ev_rect_for_line(view, lt_index);	}	ev_clear_from_margins(view, rect, (Rect *)0);}extern voidev_remove_glyph(chain, mark, flags)	Ev_chain		chain;	Ev_mark_object		mark;	unsigned		flags;{	register Ev_handle	view;	register Ev_chain_pd_handle				private = EV_CHAIN_PRIVATE(chain);	register int		i;	Op_bdry_handle		bdry;	Es_index		line_start, pos;	i = ev_find_finger_internal(&private->op_bdry, &mark);	if AN_ERROR((i == 0) || (i >= private->op_bdry.last_plus_one))	    return;	bdry = (Op_bdry_handle)FT_ADDRESS(&private->op_bdry, i);	pos = bdry->pos;	ev_remove_finger_internal(&private->op_bdry, i);	/* Glyph fingers come in pairs with consecutive ids.	 * The mark argument identifies the second of the pair.	 * Both fingers must be removed.	 */	mark--;	/* Usually first glyph finger is just above second, so try to	 * avoid the fully general lookup.	 */	bdry--; i--;	if (!( ((sizeof(Op_bdry_handle) % sizeof(long)) == 0) &&	       (EV_MARK_ID(bdry->info) == EV_MARK_ID(mark)) )) {	    i = ev_find_finger_internal(&private->op_bdry, &mark);	    if AN_ERROR(i >= private->op_bdry.last_plus_one)		return;	    bdry = (Op_bdry_handle)FT_ADDRESS(&private->op_bdry, i);	}	line_start = bdry->pos;	free(bdry->more_info);	ev_remove_finger_internal(&private->op_bdry, i);	/* What is painted depends on whether glyph_count is positive, so	 * decrement it after painting.	 */	if (flags) {	    /* Clear margin before paint in case glyph extended into it. */	    FORALLVIEWS(chain, view) {		ev_clear_margins(view, line_start, -1, (Rect *)0);	    }	    ev_display_range(chain, line_start, pos);	}	private->glyph_count--;}extern voidev_set_glyph_pr(chain, mark, pr)	Ev_chain		chain;	Ev_mark_object		mark;	struct pixrect		*pr;{	register Ev_handle	view;	register Ev_chain_pd_handle				private = EV_CHAIN_PRIVATE(chain);	register int		i;	register Op_bdry_handle	bdry;	Ev_overlay_handle	glyph_info;	Es_index		line_start, pos, stop_pos;	i = ev_find_finger_internal(&private->op_bdry, &mark);	if AN_ERROR((i == 0) || (i >= private->op_bdry.last_plus_one))	    return;	bdry = (Op_bdry_handle)FT_ADDRESS(&private->op_bdry, i);	glyph_info = (Ev_overlay_handle)bdry->more_info;	glyph_info->pr = pr;	stop_pos = bdry->pos;	/* Glyph fingers come in pairs with consecutive ids.	 * The mark argument identifies the second of the pair.	 * The position to start repaint from is in first finger.	 */	mark--;	/* Usually first glyph finger is just above second, so try to	 * avoid the fully general lookup.	 */	bdry--;	if (!( ((sizeof(Op_bdry_handle) % sizeof(long)) == 0) &&	       (EV_MARK_ID(bdry->info) == EV_MARK_ID(mark)) )) {	    i = ev_find_finger_internal(&private->op_bdry, &mark);	    if AN_ERROR(i >= private->op_bdry.last_plus_one)		return;	    bdry = (Op_bdry_handle)FT_ADDRESS(&private->op_bdry, i);	}	pos = bdry->pos;	line_start = ev_line_start(chain->first_view, pos);	/* Clear margin before paint in case glyph extended into it. */	FORALLVIEWS(chain, view) {	    ev_clear_margins(view, line_start, -1, (Rect *)0);	}	(void) ev_display_range(chain, line_start, stop_pos);}

⌨️ 快捷键说明

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