📄 ev_display.c
字号:
ph->esbuf.last_plus_one = first; ph->last_plus_one = first; ph->pos_for_line = first; ph->esbuf_status = 0; ph->result.last_plus_one = first; ph->result.considered = first; ph->result.break_reason = EI_PR_BUF_EMPTIED; ph->result.pos.x = ph->ei_xy.x = rect->r_left; ph->result.pos.y = ph->ei_xy.y = rect->r_top; ph->flags = 0; /* what about result.bounds? */ es_set_position(ph->whole_buf.esh, first); return (ph);}intev_process_update_buf(ph) register Ev_process_handle ph; /* Non-zero return says we're done */{ int result = 0; Es_index length = es_get_length(ph->esbuf.esh); /* Increment past already processed entities. */ if (ph->result.break_reason != EI_PR_BUF_EMPTIED) { /* ei_process leaves result.last_plus_one * at the newline, but the next character to be * positioned in the line table is one past the newline. */ if (ph->result.break_reason == EI_PR_NEWLINE) { ph->result.last_plus_one++; } ph->pos_for_line = ph->result.last_plus_one; ph->esbuf.buf += ph->result.last_plus_one - ph->esbuf.first; ph->esbuf.sizeof_buf -= ph->result.last_plus_one - ph->esbuf.first; ph->esbuf.first = ph->result.last_plus_one; } if (ph->flags & EV_PROCESS_PROCESSED_BUF && (ph->result.break_reason == EI_PR_BUF_EMPTIED || ph->esbuf.last_plus_one >= ph->whole_buf.last_plus_one)) { if (ph->result.last_plus_one == length) ph->result.last_plus_one = ES_INFINITY; return (1); } else { ph->flags |= EV_PROCESS_PROCESSED_BUF; } /* Make sure esbuf is full. */ if (ph->esbuf.first >= ph->esbuf.last_plus_one || ph->result.break_reason == EI_PR_BUF_EMPTIED) { ph->esbuf.buf = ph->whole_buf.buf; if ((ph->whole_buf.last_plus_one < ES_INFINITY) && (ph->whole_buf.last_plus_one > ph->last_plus_one) && (ph->whole_buf.last_plus_one - ph->last_plus_one < EV_BUFSIZE)) { ph->esbuf.sizeof_buf = ph->whole_buf.last_plus_one - ph->last_plus_one; } else { ph->esbuf.sizeof_buf = EV_BUFSIZE; } ph->last_plus_one = ph->esbuf.last_plus_one = ph->esbuf.first; es_set_position(ph->esbuf.esh, ph->last_plus_one); if (result = ev_fill_esbuf(&ph->esbuf, &ph->last_plus_one)) { if (ph->result.last_plus_one == length) ph->result.last_plus_one = ES_INFINITY; if (ph->result.break_reason != EI_PR_OUT_OF_RANGE) ph->result.break_reason |= EI_PR_END_OF_STREAM; } else if (ph->esbuf.last_plus_one > ph->whole_buf.last_plus_one) { ph->esbuf.sizeof_buf = ph->whole_buf.last_plus_one - ph->esbuf.first; es_set_position(ph->esbuf.esh, (ph->last_plus_one = ph->esbuf.last_plus_one = ph->whole_buf.last_plus_one)); } } return (result);}/* Flags for ev_process() */#define EV_PROCESS_NEXT_LINE 0x0000001unsigned long /* break_reason */ev_process(ph, flags, op, rop, pw) register Ev_process_handle ph; long unsigned flags; int op; int rop; struct pixwin *pw;{ Ei_handle eih = ph->view->view_chain->eih; if (flags & EV_PROCESS_NEXT_LINE) { ph->result.pos.y += ei_line_height(eih); } ph->result = ei_process( eih, op, &ph->esbuf, ph->ei_xy.x, ph->ei_xy.y, rop, pw, &ph->rect, ph->rect.r_left); switch (ph->result.break_reason) { case EI_PR_HIT_RIGHT: switch ((EV_PRIVATE(ph->view))->right_break) { case EV_CLIP: { Es_index span_first, span_lpo; (void) ev_span(ph->view->view_chain, ph->result.last_plus_one, &span_first, &span_lpo, EI_SPAN_RIGHT_ONLY|EI_SPAN_LINE); if (span_first != ES_CANNOT_SET) { ph->result.last_plus_one = span_lpo; ph->last_plus_one = ph->result.last_plus_one; ph->esbuf.last_plus_one = ph->result.last_plus_one; es_set_position(ph->esbuf.esh, ph->result.last_plus_one); } break; } case EV_WRAP_AT_WORD: { Es_index span_first, span_lpo; unsigned span_flags; Rect tmp_rect; struct ei_process_result ei_measure, ev_ei_process(); span_flags = ev_span(ph->view->view_chain, ph->result.last_plus_one, &span_first, &span_lpo, EI_SPAN_SP_AND_TAB); if (span_first != ES_CANNOT_SET) { /* if white space, break after, * else if word and not first word, break before, * else revert to character wrap. */ if ((span_flags & EI_SPAN_NOT_IN_CLASS) == 0) { if (span_flags & EI_SPAN_RIGHT_HIT_NEXT_LEVEL) ++span_lpo; ph->result.last_plus_one = span_lpo; /* because we clip white space */ ph->result.considered = span_lpo; } else if (span_first > ph->pos_for_line) { ph->result.last_plus_one = span_first; ei_measure = ev_ei_process(ph->view, ph->pos_for_line, span_first); ph->result.bounds.r_width = ei_measure.bounds.r_width - (ph->result.bounds.r_left - ei_measure.bounds.r_left); if (ph->result.bounds.r_width < 0) { ph->result.bounds.r_left -= ph->result.bounds.r_width; ph->result.bounds.r_width = 0; } if (span_first < ph->esbuf.first) { ph->last_plus_one = span_first-1; break; /* goto NextBuffer; */ } } else break; ph->last_plus_one = ph->result.last_plus_one; ph->esbuf.last_plus_one = ph->result.last_plus_one; es_set_position(ph->esbuf.esh, ph->result.last_plus_one); } break; } default: break; } /* switch right_break */ break; default: break; } /* switch break_reason */ ph->ei_xy.x = ph->view->rect.r_left; return (ph->result.break_reason);}struct ei_process_resultev_ei_process(view, start, stop_plus_one) register Ev_handle view; Es_index start; /* Entity to start measuring at */ Es_index stop_plus_one; /* 1st entity not measured *//* This routine mirrors ev_display_internal for those cases where the * view->line_table should not be disturbed. * "start" should always be at the start of a display line, or measuring * may be inaccurate due to tabs or word-wrap. */{ char buf[EV_BUFSIZE]; Rect rect; Ev_process_object process_object; register Ev_process_handle ph; rect.r_left = view->rect.r_left; rect.r_top = 0; rect.r_width = view->rect.r_width; rect.r_height = 32000; /* Close enough to Infinity */ ph = ev_process_init(&process_object, view, start, stop_plus_one, &rect, buf, EV_BUFSIZE); while (!ev_process_update_buf(ph)) { (void) ev_process(ph, EV_PROCESS_NEXT_LINE, EI_OP_MEASURE, PIX_SRC, 0); } return(ph->result);}/* * Find the index of the last character on a line started by line_start, * plus one. */struct ei_process_resultev_line_lpo(view, line_start) Ev_handle view; Es_index line_start;{ char buf[EV_BUFSIZE]; Rect rect; Ev_process_object process_object; register Ev_process_handle ph; Ev_process_handle ev_process_init(); rect.r_left = view->rect.r_left; rect.r_top = 0; rect.r_width = view->rect.r_width; rect.r_height = 32000; /* Close enough to Infinity */ ph = ev_process_init(&process_object, view, line_start, ES_INFINITY, &rect, buf, EV_BUFSIZE); while (!ev_process_update_buf(ph)) { (void) ev_process(ph, 0, EI_OP_MEASURE, PIX_SRC, 0); if (ph->result.break_reason != EI_PR_BUF_EMPTIED) break; } if (ph->result.break_reason == EI_PR_NEWLINE) ph->result.last_plus_one++; return (ph->result);}Es_indexev_display_line_start(view, pos) register Ev_handle view; Es_index pos;/* Return the index of the entity at the start of the display line * containing pos. */{ char buf[EV_BUFSIZE]; Rect rect; Ev_process_object process_object; register Ev_process_handle ph; register Es_index line_start; register Es_index line_start_next; int line_index; switch (ev_xy_in_view(view, pos, &line_index, &rect)) { case EV_XY_RIGHT: case EV_XY_VISIBLE: return (ev_index_for_line(view, line_index)); default: rect.r_left = view->rect.r_left; rect.r_top = 0; rect.r_width = view->rect.r_width; rect.r_height = 32000; /* Close enough to Infinity */ line_start = ev_line_start(view, pos); if (line_start == pos) return(line_start); ph = ev_process_init(&process_object, view, line_start, pos, &rect, buf, EV_BUFSIZE); while (!ev_process_update_buf(ph)) { line_start = ph->result.last_plus_one; (void) ev_process(ph, EV_PROCESS_NEXT_LINE, EI_OP_MEASURE, PIX_SRC, 0); } if (pos == es_get_length(view->view_chain->esh)) return(line_start); /* BUG ALERT: if pos-line_start == EV_BUFSIZE, * ei_process will return BUF_EMPTIED instead of HIT_RIGHT. */ ASSERT(pos-line_start < EV_BUFSIZE); ph = ev_process_init(&process_object, view, line_start, pos+1, &rect, buf, EV_BUFSIZE); while (!ev_process_update_buf(ph)) { (void) ev_process(ph, EV_PROCESS_NEXT_LINE, EI_OP_MEASURE, PIX_SRC, 0); if (ph->result.break_reason == EI_PR_HIT_RIGHT) { line_start = ph->result.last_plus_one; break; } } return(line_start); }}voidev_do_glyph(view, glyph_pos_ptr, glyph_ptr, result) register Ev_handle view; Es_index *glyph_pos_ptr; Ev_overlay_handle *glyph_ptr; struct ei_process_result *result;{ Ev_overlay_handle glyph = *glyph_ptr; Ev_chain chain = view->view_chain; Ei_handle eih = chain->eih; Ev_pd_handle private = EV_PRIVATE(view); int height = ei_line_height(eih); int width = -glyph->offset_x; int left; Rect margin_rect; if (glyph->flags & EV_OVERLAY_RIGHT_MARGIN) { left = rect_right(&(view->rect))+1; width = glyph->pr->pr_width; if (width > private->right_margin) width = private->right_margin; margin_rect.r_left = left; margin_rect.r_top = result->bounds.r_top; margin_rect.r_width = private->right_margin; margin_rect.r_height = height; ev_clear_rect(view, &margin_rect); } else { left = rect_right(&(result->bounds))+1+glyph->offset_x; if (height > glyph->pr->pr_height) height = glyph->pr->pr_height; if (width > glyph->pr->pr_width) width = glyph->pr->pr_width; if (left < view->rect.r_left) { margin_rect.r_left = view->rect.r_left - private->left_margin; margin_rect.r_top = result->bounds.r_top; margin_rect.r_width = private->left_margin; margin_rect.r_height = height; ev_clear_rect(view, &margin_rect); } } pw_write(view->pw, left, result->bounds.r_top, width, height, glyph->pix_op, glyph->pr, 0, 0); *glyph_ptr = (Ev_overlay_handle) 0; *glyph_pos_ptr = ES_INFINITY;}/* * As of 2/23/87, ev_display_internal may assume that the line table * is correct. If the line table is not correct, the caller should * be going through ev_update_view_display(); */struct ei_process_resultev_display_internal(view, rect, line, stop_plus_one, ei_op, break_action) register Ev_handle view; register Rect *rect; /* r_left, r_top are where to start * r_width = view->rect.r_width-r_left * r_height is how far to paint. */ register int line; /* starting index into line_table. */ register Es_index stop_plus_one; /* 1st entity not displayed */ int ei_op, /* EI_OP_* in entity_interpreter.h */ break_action; /* OR of any of * EV_QUIT, EV_Q_DORBREAK */{ /* before calling this function, be sure to * es_set_position(view->view_chain->esh, * the 1st char to be displayed); */ Ev_chain chain = view->view_chain; Ei_handle eih = chain->eih; char buf[EV_BUFSIZE]; register Ev_impl_line_seq line_seq = (Ev_impl_line_seq) view->line_table.seq; Es_index last_plus_one; int save_left = rect->r_left; int save_width = rect->r_width; struct range range; Ev_pd_handle private = EV_PRIVATE(view); Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(chain); Es_buf_object esbuf; Ev_overlay_handle glyph; Es_index glyph_pos; struct ei_process_result glyph_save_result, result; int rop_to_use; Es_index esbuf_last_plus_one; Es_index esbuf_sizeof_buf;#define INCREMENT_LINE line++; ASSERT(line < view->line_table.last_plus_one)#define ADVANCE_TO_NEW_LINE \ result.pos.x = view->rect.r_left; \ result.pos.y += ei_line_height(eih); \ INCREMENT_LINE; \ if (line+1 == view->line_table.last_plus_one) \ goto Done#define ESBUF_SET_POSITION(pos) \ es_set_position(esbuf.esh, \ (last_plus_one = esbuf.last_plus_one = (pos))) result.break_reason = EI_PR_OUT_OF_RANGE; glyph_save_result.break_reason = EI_PR_OUT_OF_RANGE; glyph_pos = ES_INFINITY;Glyph_restart: result.pos.x = rect->r_left; result.pos.y = rect->r_top; /* WARNING: Anytime that result.last_plus_one is modified it may * be necessary to call ev_range_info(). */ result.last_plus_one = last_plus_one = es_get_position(chain->esh); if AN_ERROR(line+1 >= view->line_table.last_plus_one) { result.break_reason = EI_PR_HIT_BOTTOM; goto Done; } if ((ei_op & EI_OP_MEASURE) == 0) { ev_range_info(chain_private->op_bdry, last_plus_one, &range); range.ei_op |= ei_op; if (range.ei_op & EI_OP_EV_OVERLAY) { if (last_plus_one != line_seq[line].pos) { /* Start is part way into the glyph region. * Pretend the call really started at line's start. */ es_set_position(chain->esh, line_seq[line].pos); rect->r_width += (rect->r_left - view->rect.r_left); rect->r_left = view->rect.r_left; goto Glyph_restart; } } glyph = (Ev_overlay_handle) 0; } else { range.last_plus_one = ES_INFINITY; range.ei_op = ei_op; } esbuf.esh = chain->esh; FOREVER { esbuf.buf = buf; if ((stop_plus_one < ES_INFINITY) && (stop_plus_one > last_plus_one) && (stop_plus_one-last_plus_one < EV_BUFSIZE)) { esbuf.sizeof_buf = stop_plus_one-last_plus_one; } else esbuf.sizeof_buf = EV_BUFSIZE; if (ev_fill_esbuf(&esbuf, &last_plus_one)) { if (result.break_reason == EI_PR_OUT_OF_RANGE) { if (line+1 < view->line_table.last_plus_one && line_seq[line+1].pos < ES_INFINITY) { break; } else goto Done; } result.break_reason |= EI_PR_END_OF_STREAM; break; } if (esbuf.last_plus_one > range.last_plus_one) { ESBUF_SET_POSITION(range.last_plus_one); } if (esbuf.last_plus_one > stop_plus_one) { ESBUF_SET_POSITION(stop_plus_one); } /* Invariant at this point: * esbuf.last_plus_one <= MIN[stop_plus_one, range.last_plus_one] */ while (esbuf.first < esbuf.last_plus_one) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -