📄 ei_plain_text.c
字号:
rect->r_left, bounds->r_top, bounds_right - rect->r_left, bounds->r_height, PIX_SRC, (Pixrect *)0, 0, 0); if (op & EI_OP_CLEAR_INTERIOR) (void) pw_write(pw, bounds->r_left, bounds->r_top, bounds->r_width, bounds->r_height, PIX_SRC, (Pixrect *)0, 0, 0); if (op & EI_OP_CLEAR_BACK) (void) pw_write(pw, bounds_right, bounds->r_top, rect->r_left + rect->r_width - bounds_right, bounds->r_height, PIX_SRC, (Pixrect *)0, 0, 0);#undef bounds_right } else { (void) pw_lock(pw, bounds); } if (pw->pw_prretained) { if (batch_length > 0) (void) pw_batchrop(pw, x, y, rop|PIX_DONTCLIP, batch, batch_length); } else if (rop & PIX_DONTCLIP) { prpos.pr = pw->pw_clipdata->pwcd_prmulti; prpos.pos.x = x; prpos.pos.y = y; if (batch_length > 0) prs_batchrop(prpos, rop, batch, batch_length); } else { register struct pixwin_prlist *prl; for (prl = pw->pw_clipdata->pwcd_prl; prl; prl = prl->prl_next) { struct rect rclip; prpos.pr = prl->prl_pixrect; prpos.pos.x = x-prl->prl_x; prpos.pos.y = y-prl->prl_y; rect_construct(&rclip, prl->prl_x, prl->prl_y, prl->prl_pixrect->pr_width, prl->prl_pixrect->pr_height); if (batch_length > 0) { if (rect_includesrect(&rclip, bounds)) { prs_batchrop(prpos, rop|PIX_DONTCLIP, batch, batch_length); break; } else prs_batchrop(prpos, rop&(~PIX_DONTCLIP), batch, batch_length); } } } if (op & EI_OP_LIGHT_GRAY) (void) pw_replrop(pw, bounds->r_left, bounds->r_top, bounds->r_width, bounds->r_height, PIX_SRC | PIX_DST, &gray17_pr, 0, 0); if (op & EI_OP_STRIKE_UNDER) {#define bottom temp bottom = rect_bottom(bounds); (void) pw_vector(pw, bounds->r_left, bottom, rect_right(bounds)-1, bottom, PIX_NOT(PIX_SRC), 0);#undef bottom } if (op & EI_OP_INVERT) (void) pw_write(pw, bounds->r_left, bounds->r_top, bounds->r_width, bounds->r_height, PIX_NOT(PIX_SRC) ^ PIX_DST, (Pixrect *)0, 0, 0); (void) pw_unlock(pw); /* Refresh changed portion of screen from memory image, if retained */ pw_batch_off(pw);}static caddr_tei_plain_text_get(eih, attribute) Ei_handle eih; Ei_attribute attribute;{ register Eipt_handle private = ABS_TO_REP(eih); switch (attribute) { case EI_CONTROL_CHARS_USE_FONT: return((caddr_t)(private->state & CONTROL_CHARS_USE_FONT)); case EI_FONT: return((caddr_t)private->font); case EI_TAB_WIDTH: return((caddr_t)(private->tab_width)); default: return(0); }}static intei_plain_text_set(eih, attributes) Ei_handle eih; caddr_t *attributes;{ register Eipt_handle private = ABS_TO_REP(eih); while (*attributes) { switch ((Ei_attribute)*attributes) { case EI_CONTROL_CHARS_USE_FONT: if (attributes[1]) { private->state |= CONTROL_CHARS_USE_FONT; } else { private->state &= ~CONTROL_CHARS_USE_FONT; } break; case EI_FONT: if (attributes[1]) { ei_plain_text_set_font(eih, (struct pixfont *)LINT_CAST(attributes[1])); } else { return(1); } break; case EI_TAB_WIDTH: ei_plain_text_set_tab_width(eih, (int)attributes[1]); break; default: break; } attributes = attr_next(attributes); } return(0);}#define EI_IS_LINE_CHAR(char) \ ((char) == '\n')#define EI_WORD_CLASS 0#define EI_PATH_NAME_CLASS 1#define EI_SP_AND_TAB_CLASS 2#define EI_CLIENT1_CLASS 3#define EI_CLIENT2_CLASS 4#define EI_NUM_CLASSES 5 /* number of character classes */static SET ei_classes[EI_NUM_CLASSES]; /* character classes */static short ei_classes_initialized; /* = 0 (implicit init for cc -A-R) */static voidei_classes_initialize(){ register SET *setp; /* character class of interest */ register int ch; /* counter */ /* WORD is alpha-numeric characters only */ setp = &ei_classes[EI_WORD_CLASS]; CLEAR_SET(setp); for (ch = 0; ch <= 255; ch++) { if (isalnum(ch)) ADD_ELEMENT(setp, ch); } ADD_ELEMENT(setp, '_'); /* PATH_NAME is non-white & non-null chars */ setp = &ei_classes[EI_PATH_NAME_CLASS]; FILL_SET(setp); REMOVE_ELEMENT(setp, ' '); REMOVE_ELEMENT(setp, '\t'); REMOVE_ELEMENT(setp, '\n'); REMOVE_ELEMENT(setp, '\0'); /* SP_AND_TAB is exactly that */ setp = &ei_classes[EI_SP_AND_TAB_CLASS]; CLEAR_SET(setp); ADD_ELEMENT(setp, ' '); ADD_ELEMENT(setp, '\t'); /* CLIENT1/2 are initially empty */ setp = &ei_classes[EI_CLIENT1_CLASS]; CLEAR_SET(setp); setp = &ei_classes[EI_CLIENT2_CLASS]; CLEAR_SET(setp); ei_classes_initialized = 1;}/* ARGSUSED */static struct ei_span_resultei_plain_text_span_of_group(eih, esbuf, group_spec, index) Ei_handle eih; /* Currently unused */ register Es_buf_handle esbuf; register int group_spec; Es_index index;{ register Es_index esi = index; register int i, in_class; struct ei_span_result result;/* WARNING: the code below that uses the SET macros, must not have characters * with the 8-th bit on be sign extended when converted to larger storage * classes. Thus, buf_rep[i] and c must both be variables of type * unsigned char. */ register unsigned char *buf_rep = (unsigned char *)esbuf->buf; register unsigned char c; /* Invariants of this routine: * i == esi - esbuf->first * during left scan, c == esbuf->buf[(--i)], (i++) during right */#define ESTABLISH_I_INVARIANT i = esi - esbuf->first#define ESTABLISH_C_INVARIANT_LEFT c = buf_rep[(--esi, --i)]#define ESTABLISH_C_INVARIANT_RIGHT c = buf_rep[(esi++, i++)] if (group_spec & EI_SPAN_LEFT_ONLY) { /* For a LEFT_ONLY span, the entity after esi should not be * considered, requiring us to backup esi before starting. */ if (esi <= 0) { goto ErrorReturn; } else esi--; } if (esi < esbuf->first || esi >= esbuf->last_plus_one) { if (es_make_buf_include_index(esbuf, esi, esbuf->sizeof_buf/4)) { goto ErrorReturn; /* BUG ALERT: this always fails at the end of the stream * unless EI_SPAN_LEFT_ONLY has already backed up esi. */ } } result.first = esi; result.last_plus_one = esi+1; result.flags = 0; if ((group_spec & EI_SPAN_CLASS_MASK) == EI_SPAN_CHAR) goto Return; if ((group_spec & EI_SPAN_CLASS_MASK) == EI_SPAN_DOCUMENT) { result.first = 0; result.last_plus_one = es_get_length(esbuf->esh); goto Return; }; ESTABLISH_I_INVARIANT; c = buf_rep[i]; /* treat LINE class special */ if ((group_spec & EI_SPAN_CLASS_MASK) == EI_SPAN_LINE) { if ((in_class = EI_IS_LINE_CHAR(c)) == 0) { result.flags |= EI_SPAN_NOT_IN_CLASS; if (group_spec & EI_SPAN_IN_CLASS_ONLY) goto ErrorReturn; } else { if (group_spec & EI_SPAN_NOT_CLASS_ONLY) goto ErrorReturn; if (group_spec & EI_SPAN_LEFT_ONLY) { result.first++; goto DoneLineScanLeft; } } if ((group_spec & EI_SPAN_RIGHT_ONLY) == 0) { while (esi > 0) { /* Scan left. */ if (i == 0) { esi = es_backup_buf(esbuf); if (esi == ES_CANNOT_SET) { goto DoneLineScanLeft; } esi++; /* ... because i is pre-decremented */ ESTABLISH_I_INVARIANT; } ESTABLISH_C_INVARIANT_LEFT; if (EI_IS_LINE_CHAR(c)) { break; } else result.first = esi; }DoneLineScanLeft: /* Fix the buffer up for the scan right */ esi = index; if (esi < esbuf->last_plus_one) { ESTABLISH_I_INVARIANT; } } esi++; i++; if ((group_spec & EI_SPAN_LEFT_ONLY) == 0) for (;!in_class;) { if (esi >= esbuf->last_plus_one) { esbuf->last_plus_one = esi; es_set_position(esbuf->esh, esbuf->last_plus_one); if (es_advance_buf(esbuf)) goto Return; ESTABLISH_I_INVARIANT; } ESTABLISH_C_INVARIANT_RIGHT; in_class = EI_IS_LINE_CHAR(c); result.last_plus_one = esi; } } else { /* Handle other classes uniformly */ SET *setp; /* character class of interest */ if (!ei_classes_initialized) ei_classes_initialize(); switch (group_spec & EI_SPAN_CLASS_MASK) { case EI_SPAN_WORD: setp = &ei_classes[EI_WORD_CLASS]; break; case EI_SPAN_PATH_NAME: setp = &ei_classes[EI_PATH_NAME_CLASS]; break; case EI_SPAN_SP_AND_TAB: setp = &ei_classes[EI_SP_AND_TAB_CLASS]; break; case EI_SPAN_CLIENT1: setp = &ei_classes[EI_CLIENT1_CLASS]; break; case EI_SPAN_CLIENT2: setp = &ei_classes[EI_CLIENT2_CLASS]; break; default: goto ErrorReturn; } if ((in_class = IN(setp, c)) == 0) { result.flags |= EI_SPAN_NOT_IN_CLASS; if (group_spec & EI_SPAN_IN_CLASS_ONLY) goto ErrorReturn; } else { if (group_spec & EI_SPAN_NOT_CLASS_ONLY) goto ErrorReturn; } if ((group_spec & EI_SPAN_RIGHT_ONLY) == 0) { while (esi > 0) { /* Scan left. */ if (i == 0) { esi = es_backup_buf(esbuf); if (esi == ES_CANNOT_SET) { goto DoneClassScanLeft; } esi++; /* ... because i is pre-decremented */ ESTABLISH_I_INVARIANT; } ESTABLISH_C_INVARIANT_LEFT; if (in_class != IN(setp, c)) { break; /* Here we assume LINE is the next level for this class */ } else if (EI_IS_LINE_CHAR(c)) { result.flags |= EI_SPAN_LEFT_HIT_NEXT_LEVEL; break; } else result.first = esi; }DoneClassScanLeft: /* Fix the buffer up for the scan right */ esi = index; if (esi < esbuf->last_plus_one) { ESTABLISH_I_INVARIANT; } } esi++; i++; if ((group_spec & EI_SPAN_LEFT_ONLY) == 0) for (;;) { if (esi >= esbuf->last_plus_one) { esbuf->last_plus_one = esi; es_set_position(esbuf->esh, esbuf->last_plus_one); if (es_advance_buf(esbuf)) goto Return; ESTABLISH_I_INVARIANT; } ESTABLISH_C_INVARIANT_RIGHT; if (in_class != IN(setp, c)) { break; /* Here we assume LINE is the next level for this class */ } else if (EI_IS_LINE_CHAR(c)) { result.flags |= EI_SPAN_RIGHT_HIT_NEXT_LEVEL; break; } else result.last_plus_one = esi; } } goto Return;ErrorReturn: result.first = result.last_plus_one = ES_CANNOT_SET;Return: return(result);}static struct ei_process_resultei_plain_text_expand(eih, esbuf, rect, x, out_buf, out_buf_len, tab_origin) Ei_handle eih; register Es_buf_handle esbuf; Rect *rect; int x; char *out_buf; int out_buf_len; int tab_origin;/* Returns number of expanded chars in result.last_plus_one. * Result.break_reason = * EI_PR_END_OF_STREAM if exhausted the entity stream. * EI_PR_BUF_EMPTIED if exhausted out_buf_len or esbuf. * EI_PR_NEWLINE if a character in the newline class was encountered. * EI_PR_HIT_RIGHT if scan reached right edge of rect. */{ Eipt_handle private = ABS_TO_REP(eih); struct ei_process_result result; struct ei_process_result process_result; Es_buf_object process_esbuf; char *in_buf = esbuf->buf; char *cp; char *op; result.last_plus_one = 0; result.break_reason = EI_PR_BUF_EMPTIED; if (!in_buf || !out_buf) return(result); process_esbuf = *esbuf; for (cp = in_buf, op = out_buf; esbuf->first < esbuf->last_plus_one && cp < in_buf + esbuf->sizeof_buf && result.last_plus_one < out_buf_len; cp++, esbuf->first++) { if (*cp == TAB) { /* * Measure to just after the tab. (x corresponds to start) * If HIT_RIGHT or NEWLINE, return only enough chars * in result.last_plus_one to get to right edge. * If BUF_EMPTIED, then tab must be on the same line as * esbuf->first, and process_result.pos.x tells where * it ends. * Save process_result.pos.x. * Then measure to just before the tab. * Now, old process_result.pos.x - process_result.pos.x * is the width of the tab in pixels. * Divide by the width of the space to get number of * spaces, and, if there is enough room, copy them * into out_buf. */ int tmp_x, spaces_in_tab, i; process_esbuf.last_plus_one = esbuf->first + 1; process_result = ei_plain_text_process( eih, EI_OP_MEASURE, &process_esbuf, x, rect->r_top, PIX_SRC, (struct pixwin *)0, rect, tab_origin); switch (process_result.break_reason) { case EI_PR_HIT_RIGHT: case EI_PR_NEWLINE: /* * Following is a cop-out instead of * returning only enough chars * in result.last_plus_one to get to right edge. */ *op++ = SPACE; result.last_plus_one++; break; default: tmp_x = process_result.pos.x; process_esbuf.last_plus_one--; process_result = ei_plain_text_process( eih, EI_OP_MEASURE, &process_esbuf, x, rect->r_top, PIX_SRC, (struct pixwin *)0, rect, tab_origin); spaces_in_tab = (tmp_x - process_result.pos.x) / private->font->pf_char['m'].pc_adv.x; if (result.last_plus_one >= (out_buf_len - spaces_in_tab)) { result.break_reason = EI_PR_BUF_FULL; break; } for (i = 0; i < spaces_in_tab; i++) { *op++ = ' '; result.last_plus_one++; } } if (result.break_reason == EI_PR_BUF_FULL) break; } else if (*cp == NEWLINE) { *op++ = SPACE; result.last_plus_one++; } else if (!iscntrl(*cp) || private->state & CONTROL_CHARS_USE_FONT) { *op++ = *cp; result.last_plus_one++; } else { if (result.last_plus_one < (out_buf_len - 2)) { *op++ = '^'; *op++ = (*cp < ' ') ? *cp+64 : '?'; result.last_plus_one += 2; } else { result.break_reason = EI_PR_BUF_FULL; break; } } } return(result);}struct pr_posfonthome(font) PIXFONT *font;{ struct pr_pos result; result.x = 0; result.y = font->pf_char['A'].pc_home.y; return(result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -