📄 ev_update.c
字号:
#endif notdef}static intev_get_width(view, first, last_plus_one, lt_index) register Ev_handle view; Es_index first, last_plus_one; int lt_index;{ struct ei_process_result ei_measure; struct ei_process_result ev_ei_process(); Ev_pos_info *cache; Ev_chain chain = view->view_chain; Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(chain); Ev_pd_handle view_private = EV_PRIVATE(view); Rect new_rect; if (first == last_plus_one) return 0; /* Try using (barely(?) invalid) cached insert info. * This may fall apart when multiple edits are involved. */ new_rect = ev_rect_for_line(view, lt_index); cache = &view_private->cached_insert_info; if ((cache->edit_number > 0) && (cache->pos == last_plus_one) && (ft_bounding_index(&view->tmp_line_table, last_plus_one) == lt_index) && (cache->edit_number == private->edit_number-1) && (cache->index_of_first == EV_VIEW_FIRST(view)) ) { return cache->pr_pos.x - new_rect.r_left; } ei_measure = ev_ei_process(view, first, last_plus_one); return ei_measure.pos.x - new_rect.r_left;}static voidev_display_line(view, width_before, lt_index, first, last_plus_one) register Ev_handle view; int width_before; int lt_index; Es_index first, last_plus_one;{#ifndef BUFSIZE#define BUFSIZE 2048#endif BUFSIZE static char *buf; /* Avoids constant malloc/free */ char *bp; Ev_chain chain = view->view_chain; Ev_chain_pd_handle chain_private = EV_CHAIN_PRIVATE(chain); Ei_handle eih = chain->eih; struct ei_process_result result; struct ei_process_result ev_ei_process(); Rect rect; Rect ev_rect_for_line(); Es_buf_object esbuf; struct range range; int rc = -1; Ev_overlay_handle glyph; Es_index glyph_pos = ES_INFINITY; register Ev_impl_line_seq line_seq =(Ev_impl_line_seq) view->line_table.seq; #define ESBUF_SET_POSITION(pos) \ es_set_position(esbuf.esh, \ (last_plus_one = esbuf.last_plus_one = (pos))) /* Don't statically allocate buf to avoid blowing up bss */ if (buf == (char *)0) { buf = sv_malloc(BUFSIZE+1); } if (first == ES_INFINITY) first = es_get_length(chain->esh); if (last_plus_one == ES_INFINITY) last_plus_one = es_get_length(chain->esh); rect = ev_rect_for_line(view, lt_index); rect.r_width -= width_before; if (rect.r_width == 0) return; rect.r_left += width_before; /* * at the end of the last line, just clear to end of line. */ if (first == es_get_length(chain->esh) || first == last_plus_one) { ev_clear_rect(view, &rect); return; } result.pos.x = rect.r_left; result.pos.y = rect.r_top; ev_range_info(chain_private->op_bdry, first, &range); range.last_plus_one = min(range.last_plus_one, last_plus_one); esbuf.esh = chain->esh; es_set_position(esbuf.esh, first); esbuf.sizeof_buf = last_plus_one - first; bp = (esbuf.sizeof_buf >= BUFSIZE) ? malloc(esbuf.sizeof_buf+1) : buf; if (!bp) { fprintf(stderr, "ev_display_line: out of memory\n"); return; } esbuf.buf = bp; esbuf.buf[esbuf.sizeof_buf] = '\0'; if (esbuf.sizeof_buf > 0) { rc = ev_fill_esbuf(&esbuf, &first); ASSERT (rc == 0); } ev_clear_from_margins(view, &rect, NULL); if (rc == 0) { do { esbuf.last_plus_one = range.last_plus_one; esbuf.sizeof_buf = esbuf.last_plus_one - esbuf.first; result.bounds = rect; 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[lt_index].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); } } } result = ei_process( eih, range.ei_op|EI_OP_CLEAR_INTERIOR|EI_OP_CLEAR_BACK, &esbuf, result.pos.x, result.pos.y, PIX_SRC|PIX_DST, view->pw, &rect, /* tab_origin */ view->rect.r_left); if (esbuf.last_plus_one == glyph_pos) { extern void ev_do_glyph(); ev_do_glyph(view, &glyph_pos, &glyph, &result); } if (esbuf.last_plus_one < last_plus_one) { esbuf.buf += esbuf.sizeof_buf; esbuf.first = esbuf.last_plus_one; ev_range_info(chain_private->op_bdry, esbuf.first, &range); range.last_plus_one = min(range.last_plus_one, last_plus_one); } } while (esbuf.last_plus_one < last_plus_one); } if (bp != buf) free(bp);}static voidev_copy_and_fix(view, new_rect, old_rect) Ev_handle view; Rect *new_rect, *old_rect;{ Pixwin *pw = view->pw; Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(view->view_chain); pw_copy(pw, new_rect->r_left, new_rect->r_top, new_rect->r_width, new_rect->r_height, PIX_SRC, pw, old_rect->r_left, old_rect->r_top); if (! rl_empty(&pw->pw_fixup)) { ev_display_fixup(view); } /* ev_clear_from_margins(view, old_rect, new_rect); */ if (private->notify_level & EV_NOTIFY_SCROLL) ev_notify(view, EV_ACTION_SCROLL, old_rect, new_rect, 0);}/* * To paint: * - Invariant on input: * the new line table contains correct line breaks. * its damaged indices indicate where on a line to start painting. * lines to be blitted down are flagged for blit down. * - Invariant on output: * the new line table corresponds to what is on the screen. */voidev_lt_paint(view, new_lt, old_lt, clear_to_bottom) Ev_handle view; Ev_line_table *new_lt; Ev_line_table *old_lt; int clear_to_bottom; /* This is a kludge */{ register Ev_impl_line_seq new = & ((Ev_impl_line_seq) new_lt->seq)[new_lt->last_plus_one-2]; register Ev_impl_line_seq old = & ((Ev_impl_line_seq) old_lt->seq)[0]; register Ev_impl_line_seq new_eob; Rect new_rect; Rect old_rect; int new_lim; int new_end_of_block; register int new_ix = new_lt->last_plus_one-2; int lpo = old_lt->last_plus_one; Es_index length = es_get_length(view->view_chain->esh); Es_index next_pos; if (ev_get(view, EV_NO_REPAINT_TIL_EVENT)) return; new_rect = view->rect; ev_add_margins(view, &new_rect); old_rect = new_rect; /* Blit down all blocks of lines flagged for blit_down. */ new_lim = 0; while (new > (Ev_impl_line_seq) new_lt->seq) { if (new->blit_down > -1) { /* find top of blit block. */ for (new_end_of_block = new_ix, new_eob = new; new_end_of_block > new_lim && (new_eob-1)->blit_down > -1 && (new_eob-1)->blit_down + 1 == new_eob->blit_down; --new_end_of_block, --new_eob) { new_eob->blit_down = -1; } /* set up the rect to slide */ ev_set_up_rect(view, &new_rect, &old_rect, new_end_of_block, new_eob->blit_down, new_ix); new_eob->blit_down = -1; ev_copy_and_fix(view, &new_rect, &old_rect); /* decrement past the blit block we just processed */ new = new_eob-1; new_ix = new_end_of_block-1; } else { --new; --new_ix; } } /* Step forward, blitting up and repairing damage */ new = (Ev_impl_line_seq) new_lt->seq; new_ix = 0; new_lim = lpo-2; while (new_ix + 1 < lpo && new->pos < length) { /* Blit up */ new_eob = new; if (new->blit_up > -1) { /* find bottom of blit block. */ new_end_of_block = new_ix; for (; new_end_of_block < new_lim && (new_eob+1)->blit_up > -1 && (new_eob+1)->blit_up - 1 == new_eob->blit_up; ++new_end_of_block, ++new_eob) ; /* set up the rect to slide */ ev_set_up_rect(view, &new_rect, &old_rect, new_ix, new->blit_up, new_end_of_block); ev_copy_and_fix(view, &new_rect, &old_rect); } /* Repair damage */ while (new <= new_eob) { if (new->damaged > -1) { next_pos = (new+1)->pos == ES_INFINITY ? length : (new+1)->pos; old = & ((Ev_impl_line_seq) old_lt->seq)[new_ix]; if (old->pos != ES_INFINITY && (new+1)->pos == ES_INFINITY && old->pos + old->considered > next_pos) next_pos = old->pos + old->considered; if (new->pos + new->damaged <= next_pos) { /* measure to new->damaged and paint from there. */ next_pos = (new+1)->pos == ES_INFINITY ? length : (new+1)->pos; ev_display_line(view, ev_get_width(view, new->pos, new->pos + new->damaged, new_ix), new_ix, new->pos + new->damaged, next_pos); } new->damaged = -1; } new->blit_up = -1; ++new; ++new_ix; } } /* * Performance enhancement: Added more constraints * && (new->damaged > -1 || new->blit_up > -1 * || ((Ev_impl_line_seq) old_lt->seq)[new_ix].considered > -1) */ if (new_ix + 1 < lpo && new->pos >= length && (new->blit_up > -1 || new->damaged > -1 || old->damaged > -1 || ((Ev_impl_line_seq) old_lt->seq)[new_ix].considered > -1) || clear_to_bottom) { new->damaged = -1; new->blit_up = -1; new_rect = ev_rect_for_line(view, new_ix); ev_clear_to_bottom(view, &new_rect, new_rect.r_top, 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -