📄 scrn.c
字号:
t->x = x; break; case 10: texec(t->cap, t->ll, 1, 0, 0, 0, 0); t->x = 0; t->y = hl; goto docv; case 12: texec(t->cap, t->ho, 1, 0, 0, 0, 0); t->x = 0; t->y = hy; goto docv; case 8: texec(t->cap, t->cr, 1, 0, 0, 0, 0); t->x = 0;docv: case 5: texec(t->cap, t->cv, 1, y, 0, 0, 0); t->y = y; break; case 6: texec(t->cap, t->cm, 1, y, x, 0, 0); t->y = y; t->x = x; break; case 7: texec(t->cap, t->cv, 1, y, 0, 0, 0); t->y = y; texec(t->cap, t->ch, 1, x, 0, 0, 0); t->x = x; break; case 13: texec(t->cap, t->cV, 1, y, 0, 0, 0); t->y = y; t->x = 0; break; }/* Use relative cursor position functions if we're not there yet *//* First adjust row */ if (y > t->y) { /* Have to go down */ if (!t->lf || t->cDO < (y - t->y) * t->clf) { texec(t->cap, t->DO, 1, y - t->y, 0, 0, 0); t->y = y; } else while (y > t->y) { texec(t->cap, t->lf, 1, 0, 0, 0, 0); ++t->y; } } else if (y < t->y) { /* Have to go up */ if (!t->up || t->cUP < (t->y - y) * t->cup) { texec(t->cap, t->UP, 1, t->y - y, 0, 0, 0); t->y = y; } else while (y < t->y) { texec(t->cap, t->up, 1, 0, 0, 0, 0); --t->y; } }/* Use tabs */ if (x > t->x && t->ta) { int ntabs = (x - t->x + t->x % t->tw) / t->tw; int cstunder = x % t->tw + t->cta * ntabs; int cstover; if (x + t->tw < t->co && t->bs) cstover = t->cbs * (t->tw - x % t->tw) + t->cta * (ntabs + 1); else cstover = 10000; if (cstunder < t->cRI && cstunder < x - t->x && cstover > cstunder) { if (ntabs) { t->x = x - x % t->tw; do { texec(t->cap, t->ta, 1, 0, 0, 0, 0); } while (--ntabs); } } else if (cstover < t->cRI && cstover < x - t->x) { t->x = t->tw + x - x % t->tw; ++ntabs; do { texec(t->cap, t->ta, 1, 0, 0, 0, 0); } while (--ntabs); } } else if (x < t->x && t->bt) { int ntabs = ((t->x + t->tw - 1) - (t->x + t->tw - 1) % t->tw - ((x + t->tw - 1) - (x + t->tw - 1) % t->tw)) / t->tw; int cstunder, cstover; if (t->bs) cstunder = t->cbt * ntabs + t->cbs * (t->tw - x % t->tw); else cstunder = 10000; if (x - t->tw >= 0) cstover = t->cbt * (ntabs + 1) + x % t->tw; else cstover = 10000; if (cstunder < t->cLE && (t->bs ? cstunder < (t->x - x) * t->cbs : 1) && cstover > cstunder) { if (ntabs) { do { texec(t->cap, t->bt, 1, 0, 0, 0, 0); } while (--ntabs); t->x = x + t->tw - x % t->tw; } } else if (cstover < t->cRI && (t->bs ? cstover < (t->x - x) * t->cbs : 1)) { t->x = x - x % t->tw; ++ntabs; do { texec(t->cap, t->bt, 1, 0, 0, 0, 0); } while (--ntabs); } }/* Now adjust column */ if (x < t->x) { /* Have to go left */ if (!t->bs || t->cLE < (t->x - x) * t->cbs) { texec(t->cap, t->LE, 1, t->x - x, 0, 0, 0); t->x = x; } else while (x < t->x) { texec(t->cap, t->bs, 1, 0, 0, 0, 0); --t->x; } } else if (x > t->x) { /* Have to go right */ /* Hmm.. this should take into account possible attribute changes */ if (x-t->x>1 && t->RI) { texec(t->cap, t->RI, 1, x - t->x, 0, 0, 0); t->x = x; } else { while(x>t->x) { texec(t->cap, t->nd, 1, 0, 0, 0, 0); ++t->x; } } /* if (t->cRI < x - t->x) { *//* } else { int *s = t->scrn + t->x + t->y * t->co; int *a = t->attr + t->x + t->y * t->co; if (t->ins) clrins(t); while (x > t->x) { int atr, c; if(*s==-1) c=' ', atr=0; else c= *s, atr= *a; if (atr != t->attrib) set_attr(t, atr); utf8_putc(c); ++s; ++a; ++t->x; } }*/ }}int cpos(register SCRN *t, register int x, register int y){ /* Move cursor quickly if we can */ if (y == t->y) { if (x > t->x && x - t->x < 4 && !t->ins) { int *cs = t->scrn + t->x + t->co * t->y; int *as = t->attr + t->x + t->co * t->y; do { /* We used to space over unknown chars, but they now could be the right half of a UTF-8 two column character, so we can't. Also do not try to emit utf-8 sequences here. */ if(*cs<32 || *cs>=127) break; if (*as != t->attrib) set_attr(t, *as); ttputc(*cs); ++cs; ++as; ++t->x; } while (x != t->x); } if (x == t->x) return 0; } if ((!t->ms && t->attrib & (INVERSE | UNDERLINE | BG_NOT_DEFAULT)) || (t->ut && (t->attrib & BG_NOT_DEFAULT))) set_attr(t, t->attrib & ~(INVERSE | UNDERLINE | BG_MASK)); /* Should be in cposs */ if (y < t->top || y >= t->bot) setregn(t, 0, t->li); cposs(t, x, y); return 0;}static void doinschr(SCRN *t, int x, int y, int *s, int *as, int n){ int a; if (x < 0) { s -= x; as -= x; x = 0; } if (x >= t->co - 1 || n <= 0) return; if (t->im || t->ic || t->IC) { cpos(t, x, y); if ((n == 1 && t->ic) || !t->IC) { if (!t->ic) setins(t, x); for (a = 0; a != n; ++a) { texec(t->cap, t->ic, 1, x, 0, 0, 0); outatri(t, x + a, y, s[a], as[a]); texec(t->cap, t->ip, 1, x, 0, 0, 0); } if (!t->mi) clrins(t); } else { texec(t->cap, t->IC, 1, n, 0, 0, 0); for (a = 0; a != n; ++a) outatri(t, x + a, y, s[a], as[a]); } } mmove(t->scrn + x + t->co * y + n, t->scrn + x + t->co * y, (t->co - (x + n)) * sizeof(int)); mmove(t->attr + x + t->co * y + n, t->attr + x + t->co * y, (t->co - (x + n)) * sizeof(int)); mmove(t->scrn + x + t->co * y, s, n * sizeof(int)); mmove(t->attr + x + t->co * y, s, n * sizeof(int));}static void dodelchr(SCRN *t, int x, int y, int n){ int a; if (x < 0) x = 0; if (!n || x >= t->co - 1) return; if (t->dc || t->DC) { cpos(t, x, y); texec(t->cap, t->dm, 1, x, 0, 0, 0); /* Enter delete mode */ if ((n == 1 && t->dc) || !t->DC) for (a = n; a; --a) texec(t->cap, t->dc, 1, x, 0, 0, 0); else texec(t->cap, t->DC, 1, n, 0, 0, 0); texec(t->cap, t->ed, 1, x, 0, 0, 0); /* Exit delete mode */ } mmove(t->scrn + t->co * y + x, t->scrn + t->co * y + x + n, (t->co - (x + n)) * sizeof(int)); mmove(t->attr + t->co * y + x, t->attr + t->co * y + x + n, (t->co - (x + n)) * sizeof(int)); msetI(t->scrn + t->co * y + t->co - n, ' ', n); msetI(t->attr + t->co * y + t->co - n, (t->attrib & FG_MASK), n);}/* Insert/Delete within line *//* FIXME: doesn't know about attr */void magic(SCRN *t, int y, int *cs, int *ca,int *s, int *a, int placex){ struct hentry *htab = t->htab; int *ofst = t->ofst; int aryx = 1; int x; if (!(t->im || t->ic || t->IC) || !(t->dc || t->DC)) return; mset(htab, 0, 256 * sizeof(struct hentry)); msetI(ofst, 0, t->co);/* Build hash table */ for (x = 0; x != t->co - 1; ++x) { t->ary[aryx].next = htab[cs[x] & 255].next; t->ary[aryx].loc = x; ++htab[cs[x] & 255].loc; htab[cs[x] & 255].next = aryx++; }/* Build offset table */ for (x = 0; x < t->co - 1;) if (htab[s[x] & 255].loc >= 15) ofst[x++] = t->co - 1; else { int aryy; int maxaryy = 0; int maxlen = 0; int best = 0; int bestback = 0; int z; for (aryy = htab[s[x] & 255].next; aryy; aryy = t->ary[aryy].next) { int amnt, back; int tsfo = t->ary[aryy].loc - x; int cst = -abs(tsfo); int pre = 32; for (amnt = 0; x + amnt < t->co - 1 && x + tsfo + amnt < t->co - 1; ++amnt) { if (cs[x + tsfo + amnt] != s[x + amnt]) break; else if ((s[x + amnt] & 255) != 32 || pre != 32) ++cst; pre = s[x + amnt] & 255; } pre = 32; for (back = 0; back + x > 0 && back + tsfo + x > 0; --back) { if (cs[x + tsfo + back - 1] != s[x + back - 1]) break; else if ((s[x + back - 1] & 255) != 32 || pre != 32) ++cst; pre = s[x + back - 1] & 255; } if (cst > best) { maxaryy = aryy; maxlen = amnt; best = cst; bestback = back; } } if (!maxlen) { ofst[x] = t->co - 1; maxlen = 1; } else if (best < 2) for (z = 0; z != maxlen; ++z) ofst[x + z] = t->co - 1; else for (z = 0; z != maxlen - bestback; ++z) ofst[x + z + bestback] = t->ary[maxaryy].loc - x; x += maxlen; }/* Apply scrolling commands */ for (x = 0; x != t->co - 1; ++x) { int q = ofst[x]; if (q && q != t->co - 1) { if (q > 0) { int z, fu; for (z = x; z != t->co - 1 && ofst[z] == q; ++z) ; while (s[x] == cs[x] && x < placex) ++x; dodelchr(t, x, y, q); for (fu = x; fu != t->co - 1; ++fu) if (ofst[fu] != t->co - 1) ofst[fu] -= q; x = z - 1; } else { int z, fu; for (z = x; z != t->co - 1 && ofst[z] == q; ++z) ; while (s[x + q] == cs[x + q] && x - q < placex) ++x; doinschr(t, x + q, y, s + x + q, a + x + q, -q); for (fu = x; fu != t->co - 1; ++fu) if (ofst[fu] != t->co - 1) ofst[fu] -= q; x = z - 1; } } }}static void doupscrl(SCRN *t, int top, int bot, int amnt, int atr){ int a = amnt; if (!amnt) return; set_attr(t, atr); if (top == 0 && bot == t->li && (t->sf || t->SF)) { setregn(t, 0, t->li); cpos(t, 0, t->li - 1); if ((amnt == 1 && t->sf) || !t->SF) while (a--) texec(t->cap, t->sf, 1, t->li - 1, 0, 0, 0); else texec(t->cap, t->SF, a, a, 0, 0, 0); goto done; } if (bot == t->li && (t->dl || t->DL)) { setregn(t, 0, t->li); cpos(t, 0, top); if ((amnt == 1 && t->dl) || !t->DL) while (a--) texec(t->cap, t->dl, 1, top, 0, 0, 0); else texec(t->cap, t->DL, a, a, 0, 0, 0); goto done; } if (t->cs && (t->sf || t->SF)) { setregn(t, top, bot); cpos(t, 0, bot - 1); if ((amnt == 1 && t->sf) || !t->SF) while (a--) texec(t->cap, t->sf, 1, bot - 1, 0, 0, 0); else texec(t->cap, t->SF, a, a, 0, 0, 0); goto done; } if ((t->dl || t->DL) && (t->al || t->AL)) { cpos(t, 0, top); if ((amnt == 1 && t->dl) || !t->DL) while (a--) texec(t->cap, t->dl, 1, top, 0, 0, 0); else texec(t->cap, t->DL, a, a, 0, 0, 0); a = amnt; cpos(t, 0, bot - amnt); if ((amnt == 1 && t->al) || !t->AL) while (a--) texec(t->cap, t->al, 1, bot - amnt, 0, 0, 0); else texec(t->cap, t->AL, a, a, 0, 0, 0); goto done; } msetI(t->updtab + top, 1, bot - top); return; done: mmove(t->scrn + top * t->co, t->scrn + (top + amnt) * t->co, (bot - top - amnt) * t->co * sizeof(int)); mmove(t->attr + top * t->co, t->attr + (top + amnt) * t->co, (bot - top - amnt) * t->co * sizeof(int)); if (bot == t->li && t->db) { msetI(t->scrn + (t->li - amnt) * t->co, -1, amnt * t->co); msetI(t->attr + (t->li - amnt) * t->co, 0, amnt * t->co); msetI(t->updtab + t->li - amnt, 1, amnt); } else { msetI(t->scrn + (bot - amnt) * t->co, ' ', amnt * t->co); msetI(t->attr + (bot - amnt) * t->co, 0, amnt * t->co); }}static void dodnscrl(SCRN *t, int top, int bot, int amnt, int atr){ int a = amnt; if (!amnt) return; set_attr(t, atr); if (top == 0 && bot == t->li && (t->sr || t->SR)) { setregn(t, 0, t->li); cpos(t, 0, 0); if ((amnt == 1 && t->sr) || !t->SR) while (a--) texec(t->cap, t->sr, 1, 0, 0, 0, 0); else texec(t->cap, t->SR, a, a, 0, 0, 0); goto done; } if (bot == t->li && (t->al || t->AL)) { setregn(t, 0, t->li); cpos(t, 0, top); if ((amnt == 1 && t->al) || !t->AL) while (a--) texec(t->cap, t->al, 1, top, 0, 0, 0); else texec(t->cap, t->AL, a, a, 0, 0, 0); goto done; } if (t->cs && (t->sr || t->SR)) { setregn(t, top, bot); cpos(t, 0, top); if ((amnt == 1 && t->sr) || !t->SR) while (a--) texec(t->cap, t->sr, 1, top, 0, 0, 0); else texec(t->cap, t->SR, a, a, 0, 0, 0); goto done; } if ((t->dl || t->DL) && (t->al || t->AL)) { cpos(t, 0, bot - amnt); if ((amnt == 1 && t->dl) || !t->DL) while (a--) texec(t->cap, t->dl, 1, bot - amnt, 0, 0, 0); else texec(t->cap, t->DL, a, a, 0, 0, 0); a = amnt; cpos(t, 0, top); if ((amnt == 1 && t->al) || !t->AL) while (a--) texec(t->cap, t->al, 1, top, 0, 0, 0); else texec(t->cap, t->AL, a, a, 0, 0, 0); goto done; } msetI(t->updtab + top, 1, bot - top); return; done: mmove(t->scrn + (top + amnt) * t->co, t->scrn + top * t->co, (bot - top - amnt) * t->co * sizeof(int)); mmove(t->attr + (top + amnt) * t->co, t->attr + top * t->co, (bot - top - amnt) * t->co * sizeof(int)); if (!top && t->da) { msetI(t->scrn, -1, amnt * t->co); msetI(t->attr, 0, amnt * t->co); msetI(t->updtab, 1, amnt); } else { msetI(t->scrn + t->co * top, ' ', amnt * t->co); msetI(t->attr + t->co * top, 0, amnt * t->co); }}void nscroll(SCRN *t,int atr){ int y, z, q, r, p; for (y = 0; y != t->li; ++y) { q = t->sary[y]; if (ifhave) return; if (q && q != t->li) { if (q > 0) { for (z = y; z != t->li && t->sary[z] == q; ++z) t->sary[z] = 0; doupscrl(t, y, z + q, q, atr); y = z - 1; } else { for (r = y; r != t->li && (t->sary[r] < 0 || t->sary[r] == t->li); ++r) ; p = r - 1; do { q = t->sary[p]; if (q && q != t->li) { for (z = p; t->sary[z] = 0, (z && t->sary[z - 1] == q); --z) ; dodnscrl(t, z + q, p + 1, -q, atr); p = z + 1; } } while (p-- != y); y = r - 1; } } } msetI(t->sary, 0, t->li);}void npartial(SCRN *t){ set_attr(t, BG_COLOR(bg_text)); clrins(t); setregn(t, 0, t->li);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -