📄 ev_display.c
字号:
/* Cases to consider for arbitrary old(o) and new(n) ranges: * ooooo nnnnn * ooooonnnnn * ooobbnnn * bbbbb (or obbbbbo or nbbbbbn) * nnnbbooo * nnnnnooooo * nnnnn ooooo */ev_set_selection(chain, first, last_plus_one, type) Ev_chain chain; register Es_index first, last_plus_one; unsigned type;{ register Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(chain); register Es_index repaint_first = first, repaint_last_plus_one = last_plus_one; Ev_mark to_use; ASSUME(0 < type && type < 0x34); to_use = SELECTION_FOR_TYPE(private, type); if (!NO_SELECTION(to_use)) { Ev_range selection; int was_pending_delete; selection = ev_get_selection_range(private, type, &was_pending_delete); ev_remove_op_bdry( &private->op_bdry, selection.first, type, EV_BDRY_TYPE_ONLY); ev_remove_op_bdry( &private->op_bdry, selection.last_plus_one, type|EV_BDRY_END, EV_BDRY_TYPE_ONLY); if (selection.last_plus_one > first && last_plus_one > selection.first) { /* * Old and new selection overlap: we will repaint the affected * enclosing range once. */ if (first == selection.first && (was_pending_delete == (type & EV_SEL_PENDING_DELETE)) ) { /* * Old and new selection have same head: only repaint * the altered tail. */ if (last_plus_one < selection.last_plus_one) { repaint_first = last_plus_one; repaint_last_plus_one = selection.last_plus_one; } else { repaint_first = selection.last_plus_one; } } else if (last_plus_one == selection.last_plus_one && (was_pending_delete == (type & EV_SEL_PENDING_DELETE)) ) { /* * Old and new selection have same tail: only repaint * the altered head. */ if (first < selection.first) { repaint_last_plus_one = selection.first; } else { repaint_first = selection.first; repaint_last_plus_one = first; } } else { /* * Repaint the entire enclosing range. */ if (first > selection.first) repaint_first = selection.first; if (last_plus_one < selection.last_plus_one) repaint_last_plus_one = selection.last_plus_one; } } else { ev_display_range(chain, selection.first, selection.last_plus_one); } } ev_add_op_bdry(&private->op_bdry, first, type, &to_use[0]); ev_add_op_bdry(&private->op_bdry, last_plus_one, type|EV_BDRY_END, &to_use[1]); ev_display_range(chain, repaint_first, repaint_last_plus_one);}intev_get_selection(chain, first, last_plus_one, type) Ev_chain chain; Es_index *first, *last_plus_one; unsigned type;{ Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(chain); Ev_range selection; int result; selection = ev_get_selection_range(private, type, &result); *first = selection.first; *last_plus_one = selection.last_plus_one; return(result);}ev_display_view(view) Ev_handle view;{ ev_display_in_rect(view, (Rect *)0);}ev_display_views(chain) Ev_chain chain;{ Ev_handle view; FORALLVIEWS(chain, view) { ev_display_view(view); }}pkg_private voidev_clear_from_margins(view, from_rect, to_rect) register Ev_handle view; register Rect *from_rect, *to_rect;/* * If to_rect is NULL, just clear margins around from_rect. */{ Rect r_temp; Ev_pd_handle private = EV_PRIVATE(view); if (to_rect == (Rect *)0) { r_temp.r_top = from_rect->r_top; r_temp.r_height = from_rect->r_height; } else if (to_rect->r_top < from_rect->r_top) { r_temp.r_top = rect_bottom(to_rect); r_temp.r_height = view->rect.r_height - r_temp.r_top; } else { r_temp.r_top = from_rect->r_top; r_temp.r_height = to_rect->r_top - r_temp.r_top; } if (private->left_margin > 0) { r_temp.r_width = private->left_margin; r_temp.r_left = view->rect.r_left - r_temp.r_width; ev_clear_rect(view, &r_temp); } if (private->right_margin > 0) { r_temp.r_width = private->right_margin; r_temp.r_left = rect_right(&view->rect) + 1; ev_clear_rect(view, &r_temp); }}static struct ev_impl_line_data valid_line_data = {-1, -1, -1, -1};static struct ev_impl_line_data invalid_line_data = {-1, 0, -1, -1};ev_set_start(view, start) Ev_handle view; Es_index start;{ int lt_index, slide_rc; Rect from_rect; Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(view->view_chain); Ev_impl_line_seq seq = (Ev_impl_line_seq) view->line_table.seq; switch (ev_xy_in_view(view, start, <_index, &from_rect)) { case EV_XY_VISIBLE: if ((seq[lt_index].damaged == -1) || (lt_index != 0)) { if (lt_index == 0) { /* Nothing to do */ return; } if (lt_index > 1) ft_set(view->line_table, 1, lt_index, ev_index_for_line(view, lt_index), &valid_line_data); ft_set(view->line_table, 0, 1, ev_index_for_line(view, lt_index), &invalid_line_data); ev_update_view_display(view, TRUE); break; } /* else fall thru */ default: view->line_table.seq[0] = start; ev_display_view(view); break; }}pkg_private voidev_add_margins(view, rect) Ev_handle view; register Rect *rect;{ Ev_pd_handle private = EV_PRIVATE(view); rect->r_left -= private->left_margin; rect->r_width += private->left_margin + private->right_margin;}ev_display_fixup(view) register Ev_handle view;{ struct ei_process_result result; Ev_impl_line_seq line_seq = (Ev_impl_line_seq) view->line_table.seq; int start, /* indices into line_table to */ stop; /* start & stop painting */ Rect fixup_rect; Rect fixup_bound; Es_index current_pos = es_get_position(view->view_chain->esh); fixup_bound = view->pw->pw_fixup.rl_bound; /* Note: following call frees view->pw->pw_fixup! */ pw_restrict_clipping(view->pw, &view->pw->pw_fixup); ev_clear_rect(view, &fixup_bound); start = ev_line_for_y(view, fixup_bound.r_top); fixup_rect = ev_rect_for_line(view, start); stop = ev_line_for_y(view, rect_bottom(&fixup_bound)); if (stop+1 < view->line_table.last_plus_one) stop++; fixup_rect.r_height += fixup_bound.r_height; es_set_position(view->view_chain->esh, line_seq[start].pos); result = ev_display_internal( view, &fixup_rect, start, line_seq[stop].pos, 0, 0); es_set_position(view->view_chain->esh, current_pos); pw_exposed(view->pw);}static voidev_swap_line_table(table1, table2) Ev_line_table *table1; Ev_line_table *table2;{ ft_object temp_table; temp_table.last_plus_one = table1->last_plus_one; temp_table.sizeof_element = table1->sizeof_element; temp_table.last_bounding_index = table1->last_bounding_index; temp_table.first_infinity = table1->first_infinity; temp_table.seq = table1->seq; table1->last_plus_one = table2->last_plus_one; table1->sizeof_element = table2->sizeof_element; table1->last_bounding_index = table2->last_bounding_index; table1->first_infinity = table2->first_infinity; table1->seq = table2->seq; table2->last_plus_one = temp_table.last_plus_one; table2->sizeof_element = temp_table.sizeof_element; table2->last_bounding_index = temp_table.last_bounding_index; table2->first_infinity = temp_table.first_infinity; table2->seq = temp_table.seq;}extern Es_indexev_scroll_lines(view, line_count, scroll_by_display_lines) register Ev_handle view; int line_count; int scroll_by_display_lines;{ Ev_impl_line_seq line_seq = (Ev_impl_line_seq) view->line_table.seq; if (line_count >= 0 && line_count < view->line_table.last_plus_one) { ev_set_start(view, line_seq[line_count].pos); } else { register Ev_chain chain = view->view_chain; register Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(chain); struct ei_span_result span_result; char buf[EV_BUFSIZE]; struct es_buf_object esbuf; register int i; Es_index pos, pos_to_remember; Rect from_rect, to_rect; extern void ev_lt_format(); static void ev_swap_line_table(); esbuf.esh = chain->esh; esbuf.buf = buf; esbuf.sizeof_buf = sizeof(buf); esbuf.first = esbuf.last_plus_one = 0; if (line_count < 0) { i = -line_count; if ((pos = line_seq[0].pos) == ES_INFINITY) pos = es_get_length(esbuf.esh); pos_to_remember = pos; while (i-- && pos > 0) { span_result = ei_span_of_group( chain->eih, &esbuf, EI_SPAN_LINE|EI_SPAN_LEFT_ONLY, pos-1); if (span_result.first == ES_CANNOT_SET) { if (pos > 1) { /* Must have hit a gap in stream */ span_result.first = es_bounds_of_gap(esbuf.esh, pos-1, 0, 0x1); i++; } else span_result.first = 0; /* Must be line */ } pos = span_result.first; } } else { i = line_count - view->line_table.last_plus_one + 1; pos = line_seq[view->line_table.last_plus_one-1].pos; pos_to_remember = pos; while (i--) { span_result = ei_span_of_group( chain->eih, &esbuf, EI_SPAN_LINE|EI_SPAN_RIGHT_ONLY, pos); if (span_result.first == ES_CANNOT_SET) break; pos = span_result.last_plus_one; } } /* Try to preserve any available bits. */ if (span_result.first != ES_CANNOT_SET && line_count < 0 && -line_count < view->line_table.last_plus_one-1) { if (scroll_by_display_lines) { while (line_seq[-line_count].pos != pos_to_remember) { ft_set(view->line_table, 0, 1, pos, &invalid_line_data); ev_lt_format(view, &view->tmp_line_table, &view->line_table); line_seq = (Ev_impl_line_seq)view->tmp_line_table.seq; pos = line_seq[1].pos; } (void)ev_swap_line_table(&view->line_table, &view->tmp_line_table); ev_lt_paint(view, &view->line_table, &view->tmp_line_table, FALSE); } else { ft_set(view->line_table, 0, 1, pos, &invalid_line_data); ev_update_view_display(view, FALSE); } } else { ev_set_start(view, pos); } } ASSERT(allock()); return(line_seq[0].pos);}ev_display_in_rect(view, rect) register Ev_handle view; register Rect *rect;{ register Es_handle esh = view->view_chain->esh; struct rect rect_intersect_view; struct ei_process_result evdi_result; Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(view->view_chain); register Es_index length = es_get_length(esh); register Es_index pos; if (rect) { rect_intersection(rect, &view->rect, &rect_intersect_view); rect = &rect_intersect_view; ev_clear_rect(view, rect); } else { if ((private->notify_level & EV_NOTIFY_SCROLL) || (private->glyph_count)) { rect = &rect_intersect_view; *rect = view->rect; ev_add_margins(view, rect); } else { rect = &view->rect; } ev_clear_rect(view, rect); rect = &view->rect; } pos = ev_index_for_line(view, 0); /* Make sure something will be displayed */ if (pos >= length && length > 0) { ((Ev_impl_line_seq) view->line_table.seq)[0].pos = length+1; /* Above defeats the optimization in ev_line_start */ pos = ev_line_start(view, length); } ft_set(view->line_table, 0, view->line_table.last_plus_one, pos, &invalid_line_data); ev_update_view_display(view, FALSE); /* Notify the client of the painting. */ if (private->notify_level & EV_NOTIFY_PAINT) { ev_notify(view, EV_ACTION_PAINT, rect, 0); }}ev_fill_esbuf(esbuf, ptr_to_last_plus_one) Es_buf_handle esbuf; Es_index *ptr_to_last_plus_one;{ register Es_index next, last_plus_one = *ptr_to_last_plus_one; int read, result;TryRead: next = es_read(esbuf->esh, esbuf->sizeof_buf, esbuf->buf, &read); if (result = READ_AT_EOF(last_plus_one, next, read)) { } else if (read == 0) { last_plus_one = next; goto TryRead; } else { esbuf->first = last_plus_one; esbuf->last_plus_one = last_plus_one + read; *ptr_to_last_plus_one = next; } return(result);}/* * ev_range_info was originally only called by ev_display_internal, * which only uses ei_op and last_plus_one, and ignores op_bdry_state * and next_i completely. on first call to ev_op_bdry_info_merge, * range->next_i isn't even set. */ev_range_info(op_bdry, pos, range) Ev_line_table op_bdry; Es_index pos; register struct range *range;{ register unsigned op_bdry_state; /* Optimization */ register int ei_op; /* temporaries */ if (pos == ES_INFINITY) { op_bdry_state = ev_op_bdry_info_merge( op_bdry, range->next_i, &range->next_i, range->op_bdry_state); } else op_bdry_state = ev_op_bdry_info(op_bdry, pos, &range->next_i); ei_op = 0; if (op_bdry_state & EV_SEL_PRIMARY) ei_op |= EI_OP_INVERT; if (op_bdry_state & EV_SEL_SECONDARY) ei_op |= EI_OP_STRIKE_UNDER; if (op_bdry_state & EV_SEL_PENDING_DELETE) ei_op |= EI_OP_LIGHT_GRAY; if (op_bdry_state & EV_BDRY_OVERLAY) ei_op |= EI_OP_EV_OVERLAY; range->op_bdry_state = op_bdry_state; range->ei_op = ei_op; if (range->next_i < op_bdry.last_plus_one) range->last_plus_one = ft_position_for_index(op_bdry, range->next_i); else range->last_plus_one = ES_INFINITY;}/* * ev_process and friends were intended to be used to * clean up ev_display_internal(). * No one has had time yet to convert ev_display_internal(). * "first" should always be at the start of a display line, or measuring * may be inaccurate due to tabs or word-wrap. */Ev_process_handleev_process_init(ph, view, first, stop_plus_one, rect, buf, sizeof_buf) register Ev_process_handle ph; Ev_handle view; Es_index first; Es_index stop_plus_one; /* ES_INFINITY ==> max buf size */ Rect *rect; char *buf; int sizeof_buf;{ if (!ph) return (ph); ph->view = view; ph->rect = *rect; ph->whole_buf.buf = ph->esbuf.buf = buf; ph->whole_buf.sizeof_buf = ph->esbuf.sizeof_buf = sizeof_buf; ph->whole_buf.esh = ph->esbuf.esh = view->view_chain->esh; ph->whole_buf.first = ph->esbuf.first = first; ph->whole_buf.last_plus_one = stop_plus_one;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -