/* putchr.c */ /***************************************************************************** Text Processor XTR [ラインバッファ作成] *****************************************************************************/ #include "xtr.h" /****************************************************************************/ /* ラインバッファへの書き込み */ /****************************** PutChr **************************************/ static int kanjiflag; static int kikocnt; static int kksize; void PutChr(unsigned c) { int x0 = x; switch (c) { case '\f': case '\r': case '\v': if (mada_start_of_line) { if (c == '\f') WritePage(); else Write1(c); } else { nonewlineflag = ON; WriteLine(); if (c == '\f') WritePage(); else Write1(c); } InitParag(); break; case '\n': WriteLine(); InitParag(); break; case '\t': if (tabtospmode) { /* タブ間隔で割り切れないインデントが付けられても表などが 変形しないように bindent を基準にしていることに注意 */ PutChrN(skmode ? alttabsp : SP, /* sk+ なら特別なスペースに変換 */ itabstop - ((x< bindent? x : x - bindent) % itabstop)); } else if (x >= MAXWIDTH) { /* タブを変換しないモードで、ラインバッファがもういっぱいなら */ PutChr1('\t'); } else { /* タブを変換しないモードなら,タブ間隔で割り切れないインデントが 付けられると表などが変形するのは仕方がない */ *lbv[x] = '\t'; for (x++; x % itabstop; x++) lbv[x] = lbv[x0]; lbv[x] = lbv[x0] + 1; } break; default: PutChr1(c); break; } } void PutChr1(unsigned c) { register int x0 = x; register int w; static int burasageflag = OFF; if (anktohwmode && !nocntrlmode && Is1B(c)) c = ANKtoHW(c); if (Is1B(c)) { if (kanjiflag) { kikocnt++; kanjiflag = OFF; } w = 1; } else { if (!kanjiflag) { kikocnt++; kanjiflag = ON; } w = (IsHW(c) ? 1 : 2); } if (wexpmodeno != 0) { if ((c_wide || c_qexpand) && !madaindentflag) /* 倍角指定中で,インデント部分でないなら */ w *= 2; /* 2倍の幅にする */ if (c_half && !madaindentflag && w >= 2) /* 半角指定中で,インデント部分でないなら */ w /= 2; /* 1/2の幅にする */ } while (++x < x0 + w) lbv[x] = lbv[x0]; lbv[x] = lbv[x0] + SetMoji(c, lbv[x0]); if (wexpmodeno == 1 || wexpmodeno == 2) { /* ダミースペースで横拡大もどきとするモードの場合 */ if (w == 4) { *lbv[x]++ = SP; *lbv[x]++ = SP; } else if (w == 2 && IsHan(c)) { *lbv[x]++ = SP; } } if (wlmode && ((wlrem = wlimit - (lbv[x] - lbuf + kikocnt * kksize)) < 0)) { Wrap(x0); burasageflag = OFF; } else if (wrapmode) { if (x > width) { if (!oidasimode && !kxmode && !burasageflag && x0 <= width && (IsHSpace(c) || Member(c, gtkinsoku) && !Member(c, gtkinsoku2))) { /* この場合 width を越えてもすぐに行を折らない */ burasageflag = ON; } else { Wrap(x0); burasageflag = OFF; } } else { burasageflag = OFF; } } else if (x > MAXWIDTH) { nonewlineflag = ON; WriteLine(); lineoverflag = ON; } } void InitLine(void) { lbv[x = 0] = lbuf; kanjiflag = OFF; kikocnt = 0; kksize = wkmode ? kikosize : c_kicode ? c_kicode->rpllen : 0; wlrem = wlimit; } void AdjKIKO(const uchar *s, int n) /* Wrap で追い出した文字列のKI/KO を数えてカウンタを補正する */ { if (nokanjimode) return; while (n > 0) { if (iskanji(*s)) { if (!kanjiflag) { kanjiflag = ON; kikocnt++; } s += 2; n -= 2; } else { if (kanjiflag) { kanjiflag = OFF; kikocnt++; } s++; n--; } } } void PutChrN(unsigned c, int n) { if (szmode && IsHanSp(c)) { PutChrN(ZENSP, n / 2); /* 全角スペースに変換 */ n %= 2; /* 奇数桁ならあまり1 */ } while (--n >= 0) PutChr(c); } void DelSpaces(void) { int i; unsigned c; for ( ; x > 0 && (i = PrevCol(x), c = Moji(lbv[i]), IsHSpace(c)) /* 制御コードが埋め込まれていないか */ && !IsAttribCol(i); x = i); } void PutStr(const uchar *str) { unsigned c; while ((c = RdMoji(str)) != '\0') { PutChr(c); } } void PutStrN(const uchar *str, int n) { const uchar *p = str; while (p - str < n) { PutChr(RdMoji(p)); } } void PutCntrl(def_t *cntrl) { if (nocntrlmode) return; if (cntrl && ExtractCntrl(cntrl, 0)) { memcpy(lbv[x], cbuf, clength); lbv[x] += clength; } } void PutCntrl1(const uchar *p, int len) { if (nocntrlmode) return; memcpy(lbv[x], p, len); lbv[x] += len; } void ReputCntrl(def_t *cntrl) /* cntrl を出力したことで一緒に解除されてしまった文字修飾を復元 */ { if (nocntrlmode) return; if (cntrl && ExtractReputCntrl(cntrl)) { memcpy(lbv[x], cbuf, clength); lbv[x] += clength; } } void PutResetCntrl(def_t *cntrl, def_t *rescntrl) { if (nocntrlmode) return; ExtractResetCntrl(cntrl, rescntrl); memcpy(lbv[x], cbuf, clength); lbv[x] += clength; } int PrevCol(int col) /* 前の文字の桁位置を返す */ { for (--col; col > 0 && lbv[col] == lbv[col - 1]; --col); return col; } int NextCol(int col) /* 次の文字の桁位置を返す */ { for (col++; col < x && lbv[col] == lbv[col - 1]; col++); return col; } int IsAttribCol(int col) /* 文字修飾付きの桁か調べる */ { uchar *p = lbv[col]; assert(col >= 0 && col < x); return SkipMoji(p) < lbv[NextCol(col)]; } /* * Local variables: * mode: c * c-indent-level: 4 * c-continued-statement-offset: 4 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * tab-width: 4 * tab-stop-list: (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80) * End: */