📄 ev_display.c
字号:
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 + -