📄 ev_update.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)ev_update.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986, 1988 by Sun Microsystems, Inc. *//* * Initialization and finalization of entity views. */#include <suntool/primal.h>#include <suntool/ev_impl.h>#include <stdio.h>#include <sys/time.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <pixrect/pixfont.h>#include "sunwindow/sv_malloc.h"/* for ev_lt_format ... */static struct ev_impl_line_data line_data = {-1, -1, -1, -1};/* * - Invariant on input: * those lines in the line table that have not been damaged or deleted * still correspond to what is on the screen. * damaged lines have a damaged index > -1. * deleted lines have line table entries that are repeated. * an entirely deleted line is not marked damaged: repetition suffices. * this routine is called whenever a simple insert or delete has occurred. * all operations are on old line table. * - Invariant on output: * the delta due to the insert or delete has been propagated. * the line table may be passed to this function again, * or to the format routine. * * find line table entry for start of change * if insertion * set damaged index to min of unsigned damaged index and * 1st damaged entity relative to line start * propagate delta but not damaged index through rest of line table * else * if deleting partial line at start of span * set damaged index to min of unsigned damaged index and * 1st damaged entity relative to line start * for lt = first completely deleted line * until lt = first line not completely deleted * *lt = start of deleted span * damaged index = -1 * if deleting partial line at end of span * set damaged index to min of unsigned damaged index and * 1st damaged entity relative to line start * propagate delta but not damaged index through rest of line table * * If the table needs any repainting, return 1; otherwise return 0. */intev_lt_delta(view, before_edit, delta) Ev_handle view; Es_index before_edit; int delta;{ int result = 0; int lt_index; Es_index range_min = before_edit; Ev_impl_line_seq seq = (Ev_impl_line_seq) view->line_table.seq; /* If edit is not before beginning of table ... */ if (before_edit >= seq[0].pos) { if (delta < 0) range_min += delta; lt_index = ft_bounding_index(&view->line_table, range_min); /* We know end of edit is not before beginning of table. * If it starts before beginning of table, start it at * beginning of table. */ if (lt_index == view->line_table.last_plus_one) { Es_index pos; lt_index = 0; pos = ev_line_start(view, range_min); seq[lt_index].considered += seq[lt_index].pos - pos; seq[lt_index].damaged = 0; seq[lt_index].pos = pos; } /* If edit is not after end of visible lines in table ... */ if (lt_index+1 < view->line_table.last_plus_one) { result = 1; range_min -= seq[lt_index].pos; seq[lt_index].damaged = seq[lt_index].damaged >= 0 ? min(seq[lt_index].damaged, range_min) : range_min; if (delta < 0) { int max_lt_index; max_lt_index = ft_bounding_index(&view->line_table, before_edit); if (max_lt_index+1 < view->line_table.last_plus_one && seq[max_lt_index].pos < before_edit && seq[max_lt_index].pos >= (before_edit+delta)) { seq[max_lt_index].damaged = 0; } for (--max_lt_index; max_lt_index > lt_index; --max_lt_index) { seq[max_lt_index].damaged = -1; } } } } ev_update_lt_after_edit(&view->line_table, before_edit, delta); return result;}#define ev_lt_fmt_find_damage(new, old, new_ix, old_ix, lpo) \ save_old_ix = old_ix; \ for (tmp = old; old_ix+1 < lpo; ++old_ix, ++new_ix, ++tmp) { \ if (tmp->damaged > -1 || (tmp+1)->damaged > -1 \ || tmp->pos == ES_INFINITY) \ break; \ } \ if (tmp > old) { \ bcopy(old, new, \ (old_ix-save_old_ix) * sizeof(struct ev_impl_line_seq)); \ old = tmp; \ new += (old_ix-save_old_ix); \ } \ new->pos = old->pos;/* * To format: * - Invariant on input: * deltas have been propagated and damage marked as per the input invariant * on insert/delete. * - Invariant on output: * a trial line table has been constructed, with correct line breaks. * lines in the new line table that should be blitted down are * flagged for blit down. * lines in the new line table that should be repainted have a * damage index > -1. * lines that should be blitted up or left alone are unmarked. * (that is, damage index = -1.) * the old and new line tables may be passed to the paint routine. */voidev_lt_format(view, new_lt, old_lt) Ev_handle view; Ev_line_table *new_lt; Ev_line_table *old_lt;{ register Ev_impl_line_seq new = (Ev_impl_line_seq) new_lt->seq; register Ev_impl_line_seq old = (Ev_impl_line_seq) old_lt->seq; register Ev_impl_line_seq tmp; register int new_ix = 0; register int old_ix = 0; register int lpo = old_lt->last_plus_one; register Es_index length = es_get_length(view->view_chain->esh); int save_old_ix; struct ei_process_result line_lpo, ev_line_lpo(); ev_lt_fmt_find_damage(new, old, new_ix, old_ix, lpo); /* * Invariant: we know new->pos is correct; * This while loop computes * new->damaged, new->blit_down, and (new+1)->pos. */ while (new_ix+1 < lpo) { new->blit_down = -1; new->blit_up = -1; if (new->pos == ES_INFINITY) { ft_set(*new_lt, new_ix, lpo, ES_INFINITY, &line_data); old = &((Ev_impl_line_seq) old_lt->seq)[new_ix]; if (old->pos < ES_INFINITY && old->pos + old->considered > length) new->damaged = 0; break; } if (old_ix+1 < lpo && new->pos == old->pos) { /* * Skip deleted lines. If there is a deletion, * blit from the bottom of the deletion. */ while (old_ix+1 < lpo && (old+1)->pos == old->pos) { ++old; ++old_ix; } /* undamaged old lines either get blitted or left alone */ if (new_ix > old_ix && old->pos < length) { new->blit_down = old_ix; } if (new_ix < old_ix) { if (old_ix+1 < lpo) { new->blit_up = old_ix; } else { old->damaged = 0; } } if (old->damaged == -1) { /* * If there is damage on the next line, we may have to * suck up characters from it. */ if ((old+1)->damaged > -1 && (old+1)->damaged + (old+1)->pos <= old->considered + old->pos) { line_lpo = ev_line_lpo(view, new->pos); ++old; /* If we are sucking chars from the next line ... */ if (line_lpo.last_plus_one > old->pos) { new->damaged = old->pos - new->pos; } new->considered = line_lpo.considered - new->pos; ++new; if (line_lpo.last_plus_one == length && line_lpo.considered == length) { new->pos = ES_INFINITY; } else { new->pos = line_lpo.last_plus_one; } } else { new->considered = old->considered; (++new)->pos = (++old)->pos; } ++new_ix; ++old_ix; continue; } } /* * Invariant: old is damaged or rewrapped and old_ix+1 < lpo * Reaching here repetitively indicates massive rewrap. * * BUG ALERT on "old->damaged = -1;": * if we ever want to delay between format and paint, * such that formatting may need to be done again, * move this reset of old->damaged to the paint code. */ new->damaged = (old_ix+1 >= lpo || new->pos != old->pos) ? 0 : old->damaged; if (old_ix < lpo) old->damaged = -1; line_lpo = ev_line_lpo(view, new->pos); if (line_lpo.last_plus_one < new->pos + new->damaged) new->damaged = line_lpo.last_plus_one - new->pos; new->considered = line_lpo.considered - new->pos; ++new; ++new_ix; if (line_lpo.last_plus_one == length && line_lpo.considered == length) { new->pos = ES_INFINITY; } else { new->pos = line_lpo.last_plus_one; } /* * If we didn't insert >= 1 line of text at this point, * catch old up with new, skipping deleted lines */ while (old_ix+1 < lpo && (old+1)->pos <= line_lpo.last_plus_one) { ++old; ++old_ix; } if (old_ix == new_ix && old->pos == new->pos) { ev_lt_fmt_find_damage(new, old, new_ix, old_ix, lpo); } } /* while (new_ix+1 < lpo) */}/* * Set up a pair of rects for blitting. * Note that old_rect->r_height is not used and therefore * is not precisely set. */static voidev_set_up_rect(view, new_rect, old_rect, new_top, old_top, new_bot) Ev_handle view; Rect *new_rect; Rect *old_rect; int new_top; int old_top; int new_bot;{ Rect tmp_rect; Rect ev_rect_for_line(); tmp_rect = ev_rect_for_line(view, new_top); new_rect->r_top = tmp_rect.r_top; tmp_rect = ev_rect_for_line(view, new_bot); new_rect->r_height = (tmp_rect.r_top - new_rect->r_top) + tmp_rect.r_height; tmp_rect = ev_rect_for_line(view, old_top); old_rect->r_top = tmp_rect.r_top;#ifdef notdef ev_add_margins(view, new_rect); ev_add_margins(view, old_rect);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -