home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
-
- #include "jwp.h"
-
- BOOL NullParaFormatProc(FILEOPTIONS *f, PARAGRAPH far *pp, int n);
-
- static UNIT far *CurrentPosition, far *TopPosition;
- static POSITION StopPos;
- static long int OldBottom;
-
- static BOOL TopChanged;
- static BOOL (* NewParaFormatProc)(FILEOPTIONS *, PARAGRAPH far *, int) = NullParaFormatProc;
- static int nr_para = 0;
-
-
-
- static BOOL NullParaFormatProc(FILEOPTIONS *f, PARAGRAPH far *pp, int n)
- {
- return (TRUE);
- }
-
-
-
- void SetReformatProc (BOOL (*f_pf)(FILEOPTIONS *, PARAGRAPH far *, int))
- {
- if (f_pf == NULL) NewParaFormatProc = NullParaFormatProc;
- else NewParaFormatProc = f_pf;
- }
-
-
-
- static void SplitLine (FILEOPTIONS *f, POSITION p, int Options)
- {
- int i, j, len;
- unsigned int n;
- PARAGRAPH far *pp;
- ONELINE far *lp;
-
-
- /* How many blocks needed? */
-
- len = unitlen(&UNITOF(p, POSOF(p)+1)) + 1;
- n = len / TEXTBLOCKSIZE;
- n = (n + 1) * TEXTBLOCKSIZE;
-
- pp = StructAlloc(PARAGRAPH);
-
- pp->leftindent = PARAOF(p)->leftindent;
- pp->rightindent = PARAOF(p)->rightindent;
- pp->firstindent = PARAOF(p)->firstindent;
- pp->spacing = PARAOF(p)->spacing;
- pp->spacemulti = PARAOF(p)->spacemulti;
-
- pp->prev = PARAOF(p);
- pp->next = PARAOF(p)->next;
- PARAOF(p)->next = pp;
-
- if (pp->next != NULL) pp->next->prev = pp;
- else f->eof = pp;
-
-
- pp->textsize = n;
-
- lp = pp->lines = pp->lastline = StructAlloc(ONELINE);
- f->nr_lines++;
-
- lp->prev = lp->next = NULL;
-
- lp->position = 0;
- pp->text = (UNIT far *) BlockAlloc(n * sizeof(UNIT));
-
- lp->length = len;
- lp->height = lp->width = 0;
-
-
- /* Copy the text */
-
- for (i = 0, j = POSOF(p) + 1; ; i++, j++) {
- if (Options & OP_MOVESEL) {
- if (SELPARA1(f) == PARAOF(p) && &UNITOF(p, j) == &SELCHAR1(f)) {
- SELPARA1(f) = pp;
- SELPOS1(f) = i;
- }
- if (SELPARA2(f) == PARAOF(p) && &UNITOF(p, j) == &SELCHAR2(f)) {
- SELPARA2(f) = pp;
- SELPOS2(f) = i;
- }
- }
-
- if (&UNITOF(f->current,CURCHAR(f)) == &UNITOF(p, j)) {
- CURPARA(f) = pp;
- CURLINE(f) = lp;
- CURCHAR(f) = i;
- }
- if (CurrentPosition == &UNITOF(p, j)) CurrentPosition = &(pp->text[i]);
- if (TopPosition == &UNITOF(p, j)) {
- TopPosition = &(pp->text[i]);
- TopChanged = (j != 0);
- }
-
- pp->text[i] = UNITOF(p,j);
- if (!CHAROF(p, j)) break;
- }
-
-
- PARAOF(p)->lastline = LINEOF(p);
- LINEOF(p)->length = POSOF(p);
- CHAROF(p, POSOF(p)) = 0;
-
- f->nr_bytes--;
-
- ReallocateText(p, unitlen(PARAOF(p)->text));
-
- /* Special format? */
-
- NewParaFormatProc(f, pp, nr_para + 1);
- }
-
-
-
- static void JoinLine (FILEOPTIONS *f, POSITION p, int Options)
- {
- int i, j;
- PARAGRAPH far *pp;
- ONELINE far *tp1, far *tp2;
-
-
- /* Join with the next paragraph */
-
- pp = PARAOF(p)->next;
- if (pp->next == NULL && pp == f->eof) f->eof = PARAOF(p);
-
-
- /* Do we need to shift the next paragraph's margins up? */
-
- if (POSOF(p) <= 0) {
- PARAOF(p)->firstindent = pp->firstindent;
- PARAOF(p)->leftindent = pp->leftindent;
- PARAOF(p)->rightindent = pp->rightindent;
- }
-
-
- /* How many blocks needed? */
-
- ReallocateText (p, unitlen(pp->text) + unitlen(PARAOF(p)->text) + 1);
-
- CurrentPosition = &UNITOF(f->current,CURCHAR(f));
- TopPosition = TOPPARA(f)->text + TOPLINE(f)->position;
-
-
- /* Is the cursor on the remaining text? */
-
- for (i = POSOF(p) + 1; ; i++) {
- if (CurrentPosition == &UNITOF(p,i)) {
- CurrentPosition = &UNITOF(p,POSOF(p));
- break;
- } else if (!CHAROF(p,i)) break;
- }
-
-
- /* Copy the text */
-
- for (i = 0, j = POSOF(p); ; i++, j++) {
- if (Options & OP_MOVESEL) {
- if (SELPARA1(f) == pp && &(pp->text[i]) == &SELCHAR1(f)) {
- SELPARA1(f) = PARAOF(p);
- SELPOS1(f) = LINEOF(p)->position + j;
- }
- if (SELPARA2(f) == pp && &(pp->text[i]) == &SELCHAR2(f)) {
- SELPARA2(f) = PARAOF(p);
- SELPOS2(f) = LINEOF(p)->position + j;
- }
- }
-
- if (CurrentPosition == pp->text + i) CurrentPosition = &UNITOF(p, j);
- if (TopPosition == pp->text + i) {
- TopPosition = &UNITOF(p, j);
- TopChanged = (j != 0);
- }
-
- UNITOF(p,j) = pp->text[i];
- if (!CHAROF(p, j)) break;
- }
-
-
- PARAOF(p)->lastline = LINEOF(p);
- LINEOF(p)->length = j;
-
-
- /* Re-link */
-
- PARAOF(p)->next = pp->next;
- if (pp->next != NULL) pp->next->prev = PARAOF(p);
-
- PARAOF(StopPos) = pp->next;
- LINEOF(StopPos) = (pp->next != NULL) ? pp->next->lines : NULL;
- POSOF(StopPos) = 0;
-
-
- /* Gets rid of the next paragraph */
-
- for (tp1 = pp->lines; tp1 != NULL; ) {
- tp2 = tp1;
- tp1 = tp1->next;
- OldBottom += tp2->height + pp->spacing;
- FreeStruct(tp2);
- f->nr_lines--;
- }
-
- if (pp->text != NULL) FreeBlock(pp->text);
- FreeStruct(pp);
-
- f->nr_bytes--;
- }
-
-
-
- static BOOL IsWhiteSpace (KANJI ch)
- {
- if (ch <= ' ') return (TRUE);
- return (FALSE);
- }
-
-
-
- static BOOL IsWordWrap (POSITION *p)
- {
- int i;
- KANJI ch;
- UNIT far *cp = &UNITOF(*p, POSOF(*p));
-
- ch = cp->kanji;
-
- if (ISKANJI(ch)) return (FALSE);
- if (IsWhiteSpace(ch)) return (FALSE);
-
- /* Back-seek */
-
- for (i = POSOF(*p); i >= 0; i--, cp--) {
- ch = cp->kanji;
- if (ISKANJI(ch) || IsWhiteSpace(ch) || ch == '-') break;
- }
-
- if (i < 0) return (FALSE); /* Word longer than one line! */
-
- POSOF(*p) = i + 1;
- return (TRUE);
- }
-
-
-
- static BOOL PotentialWordWrap (POSITION p)
- {
- int i;
- KANJI ch;
- UNIT far *cp = &UNITOF(p, POSOF(p));
-
- if (ISKANJI(cp->kanji)) {
- if (POSOF(p) == 0) return (TRUE);
- return (FALSE);
- }
-
- /* Skip white spaces */
-
- for (i = POSOF(p); i > 0; i--, POSOF(p)--, cp--) {
- ch = cp->kanji;
- if (ISKANJI(ch)) return (FALSE);
- if (!IsWhiteSpace(ch)) break;
- }
-
- if (i < 0) return (FALSE);
-
- /* Now, is this word alone? */
-
- return (!IsWordWrap(&p));
- }
-
-
-
- static BOOL OpenNewLine (FILEOPTIONS *f, POSITION p, int width, int height, int length)
- {
- UNIT far *cp = &UNITOF(p,POSOF(p));
- BOOL CanStop = FALSE;
-
- if (LINEOF(p)->next == NULL) {
- LINEOF(p)->next = StructAlloc(ONELINE);
- LINEOF(p)->next->prev = LINEOF(p);
- LINEOF(p)->next->next = NULL;
- LINEOF(p)->next->position = 0;
- f->nr_lines++;
- } else {
- if (POS2ABS(p) == LINEOF(p)->next->position) CanStop = TRUE;
- }
-
- LINEOF(p)->height = height;
- LINEOF(p)->width = width;
- LINEOF(p)->length = length;
-
- LINEOF(p) = LINEOF(p)->next;
- LINEOF(p)->position = cp - PARAOF(p)->text;
- if (!CanStop) LINEOF(p)->length = unitlen(cp);
-
- return (CanStop);
- }
-
-
-
- void ReformatParagraph (FILEOPTIONS *f, POSITION start, PARAGRAPH far *stop, int options)
- {
- int i, j, r, w;
- long int OldTop, NewBottom;
- int BlockHeight = LINEGAP(f);
- int MaxHeight, LineLength;
- long int dimension;
- UNIT far *cp;
- POSITION p;
- RECT rect;
- BOOL GoneBack = FALSE, CanStop;
- BOOL relaxed, SoftReturn;
- HDC hdc, hdcmem;
- HBRUSH hbrush;
- HBITMAP hbitmap;
-
-
- TopChanged = FALSE;
-
- /* Word wrap situation? */
-
- if (PotentialWordWrap(start) && LINEOF(start)->prev != NULL) {
- p = start;
- LINEOF(start) = LINEOF(start)->prev;
- POSOF(start) = LINEOF(start)->length - 1;
-
- GoneBack = TRUE;
- }
-
-
- /* Now take care of some accounting */
-
- CurrentPosition = &UNITOF(f->current,CURCHAR(f));
- TopPosition = &(TOPPARA(f)->text[TOPLINE(f)->position]);
-
- if (stop != NULL) {
- PARAOF(StopPos) = stop;
- LINEOF(StopPos) = stop->lines;
- POSOF(StopPos) = 0;
- } else {
- PARAOF(StopPos) = NULL;
- LINEOF(StopPos) = NULL;
- POSOF(StopPos) = 0;
- }
-
-
- /* Find the region top/bottom */
-
- if (options & OP_UPDATE) {
- if (LINEOF(start) == TOPLINE(f)->prev) {
- p = start;
- j = -(LINEOF(p)->height + PARAOF(p)->spacing);
- } else if (TOPLINE(f)->prev == NULL && TOPPARA(f)->prev != NULL &&
- LINEOF(start) == TOPPARA(f)->prev->lastline) {
- p = start;
- j = -(LINEOF(p)->height + PARAOF(p)->spacing);
- } else {
- p = f->top;
- j = LINEGAP(f);
- }
-
- do {
- if (j >= f->height) {
- ErrorMessage(global.hwnd, "ReformatParagraph: Top of block not found!");
- break;
- }
- if (LINEOF(p) == LINEOF(start)) break;
- j += LINEOF(p)->height + PARAOF(p)->spacing;
- } while (NEXTLINE(p));
-
- NewBottom = j;
- OldTop = j - LINEGAP(f);
-
- do {
- if (LINEOF(p) == LINEOF(StopPos)) break;
- j += LINEOF(p)->height + PARAOF(p)->spacing;
- } while (NEXTLINE(p));
-
- OldBottom = j - LINEGAP(f);
- } else {
- NewBottom = OldBottom = OldTop = 0L;
- }
-
-
- /* Now reformat the paragraph! */
-
- p = start;
- nr_para = 0;
-
- Loop:
-
- NewParaFormatProc(f, PARAOF(p), nr_para);
-
-
- MaxHeight = f->basefont->height;
-
- if (f->linelen > PARAOF(p)->rightindent) {
- LineLength = (f->linelen - PARAOF(p)->rightindent) * BASEWIDTH(f);
- } else {
- LineLength = BASEWIDTH(f);
- }
-
- relaxed = SoftReturn = FALSE;
-
-
- i = POSOF(p);
- j = CalcLength(f, &p);
- cp = &UNITOF(p,POSOF(p));
-
- LINEOF(p)->length = unitlen(cp);
-
- for (; ; POSOF(p)++, i++, cp++) {
- if (cp->kanji == '\r') { /* ^M = hard return */
- //nr_para++;
- SplitLine(f, p, options);
- cp = &UNITOF(p,POSOF(p));
- } else if (cp->kanji == '\b') { /* ^H = join lines */
- while (cp->kanji == '\b') {
- JoinLine(f, p, options);
- cp = &UNITOF(p,POSOF(p));
- LineLength = (f->linelen - PARAOF(p)->rightindent) * BASEWIDTH(f);
- }
- }
-
-
- if (cp->kanji == '\n') { /* ^J = soft return */
- SoftReturn = TRUE;
- w = 0;
- } else {
- SoftReturn = FALSE;
- if (cp->kanji) {
- dimension = GetDimension(f, p, j);
- w = LOWORD(dimension);
- if (POSOF(p) > 0 && cp[-1].kanji != '\t' && !ISKANJI(cp[-1].kanji) && ISKANJI(cp->kanji))
- w += f->leading;
- } else {
- w = 0;
- }
- }
-
-
- /* Line break? */
-
- if ((f->type & FN_NORMAL) && (j + w > LineLength || SoftReturn)) {
- if (SoftReturn) {
- relaxed = FALSE;
- POSOF(p)++;
- } else {
- relaxed = global.relaxmargin && IsSmallKana(cp->kanji);
- relaxed |= IsWhiteSpace(cp->kanji);
- }
-
- if (!relaxed) {
- /* Word wrap? */
-
- if (!SoftReturn && !ISKANJI(cp->kanji) && IsWordWrap(&p)) {
- i = POSOF(p);
- cp = &UNITOF(p, POSOF(p));
-
- j = CalcLength(f, &p);
- }
-
- /* Open new line */
-
- NewBottom += MaxHeight + PARAOF(p)->spacing;
- BlockHeight += MaxHeight + PARAOF(p)->spacing;
-
- r = OpenNewLine(f, p, j, MaxHeight, SoftReturn ? POSOF(p) - 1 : POSOF(p));
-
- LINEOF(p) = LINEOF(p)->next;
- POSOF(p) = -1;
- if (!SoftReturn) cp--;
-
- MaxHeight = f->basefont->height;
- j = PARAOF(p)->leftindent * BASEWIDTH(f);
-
- /* Can we stop? */
-
- if ((options & OP_MINIMAL) && r) {
- if (GoneBack && LINEOF(p) == LINEOF(start)->next) {
- CanStop = GoneBack = FALSE;
- } else {
- CanStop = TRUE;
- }
- } else {
- CanStop = FALSE;
- }
-
- if (CanStop) {
- POSITION pp;
-
- if (LINEOF(StopPos) == NULL) { /* StopLine can be NULL */
- PARAOF(pp) = f->eof;
- LINEOF(pp) = f->eof->lastline;
- POSOF(pp) = 0;
- } else {
- pp = StopPos;
- PREVLINE(pp);
- }
-
- do {
- OldBottom -= LINEOF(pp)->height + PARAOF(pp)->spacing;
- if (!PREVLINE(pp)) break;
- } while (LINEOF(pp) != LINEOF(p)->prev);
-
- StopPos = p;
-
- goto Update;
- }
- } else {
- j += w;
- if (ISKANJI(cp->kanji)) j += f->leading;
- }
- } else {
- //if (HIWORD(dimension) > MaxHeight) MaxHeight = HIWORD(dimension);
- j += w;
- if (ISKANJI(cp->kanji)) j += f->leading;
- }
-
- if (POSOF(p) >= 0 && cp == CurrentPosition) f->current = p;
- if (POSOF(p) >= 0 && cp == TopPosition) {
- f->top = p;
- TopChanged = (POSOF(p) != 0);
- }
-
- if (!cp->kanji) break;
- }
-
- NewBottom += MaxHeight + PARAOF(p)->spacing;
- BlockHeight += MaxHeight + PARAOF(p)->spacing;
-
- LINEOF(p)->height = MaxHeight;
- LINEOF(p)->length = unitlen(PARAOF(p)->text + LINEOF(p)->position);
- LINEOF(p)->width = j;
- PARAOF(p)->lastline = LINEOF(p);
-
-
- /* Now, if it is at the beginning of a line, move it to the end */
- /* of the previous line. */
-
- if ((options & OP_MOVETOEND) && CURPARA(f) == PARAOF(p) &&
- CURCHAR(f) <= 0 && CURLINE(f)->prev != NULL) {
-
- CURLINE(f) = CURLINE(f)->prev;
- CURCHAR(f) = CURLINE(f)->length;
- }
-
- /* If the last line is blank, get rid of it */
-
- if ((options & OP_MOVETOEND) &&
- !CHAROF(p,0) && LINEOF(p)->prev != NULL &&
- PARAOF(p)->text[LINEOF(p)->position - 1].kanji != '\n') {
-
- NewBottom -= LINEOF(p)->height + PARAOF(p)->spacing;
- BlockHeight -= LINEOF(p)->height + PARAOF(p)->spacing;
- PARAOF(p)->lastline = LINEOF(p) = LINEOF(p)->prev;
- }
-
-
- {
- ONELINE far *tp1, far *tp2;
-
- for (tp1 = LINEOF(p)->next; tp1 != NULL; ) {
- tp2 = tp1;
- tp1 = tp1->next;
- FreeStruct(tp2);
- f->nr_lines--;
- }
-
- LINEOF(p)->next = NULL;
- }
-
- /* Reformat the next paragraph? */
-
- if (!NEXTLINE(p)) LINEOF(p) = NULL;
-
- if (LINEOF(p) != LINEOF(StopPos)) {
- POSOF(p) = 0;
- nr_para++;
- goto Loop;
- }
-
-
- Update:
-
- if (!(options & OP_UPDATE)) return;
-
- NewBottom -= LINEGAP(f);
- BlockHeight -= LINEGAP(f);
-
- if (!FindCaret(f, TRUE) || TopChanged) {
- if (TopChanged) {
- /* Make sure MoveIntoWindow doesn't find the top */
- /* Move it to the last line */
- TOPPARA(f) = f->eof;
- TOPLINE(f) = f->eof->lastline;
- }
-
- MoveIntoWindow(f);
- InvalidateRect(f->hwnd, NULL, TRUE);
- UpdateWindow(f->hwnd);
- return;
- }
-
- /* Now redraw the update portion! */
-
- hdc = GetDC(f->hwnd);
- hdcmem = CreateCompatibleDC(hdc);
- SetTextColor(hdcmem, GetSysColor(COLOR_WINDOWTEXT));
- SetBkColor(hdcmem, GetSysColor(COLOR_WINDOW));
-
- if (BlockHeight + OldTop >= f->height) BlockHeight = f->height - OldTop;
-
- hbitmap = CreateCompatibleBitmap (hdc, f->width, BlockHeight);
- if (hbitmap != NULL) {
- SelectObject(hdcmem, hbitmap);
-
- rect.left = 0;
- rect.right = f->width;
- rect.top = 0;
- rect.bottom = NewBottom - OldTop;
-
- hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
- FillRect(hdcmem, &rect, hbrush);
- DeleteObject(hbrush);
-
- rect.top = OldTop;
- rect.bottom = NewBottom;
-
- RedrawFile(f, hdcmem, 0, OldTop, &rect, global.showspecial); /* Draw on the hdc! */
- } else {
- w = f->basefont->height + f->spacing;
-
- hbitmap = CreateCompatibleBitmap (hdc, f->width, w);
- if (hbitmap != NULL) {
- SelectObject(hdcmem, hbitmap);
-
- rect.left = 0;
- rect.right = f->width;
- rect.top = 0;
- rect.bottom = NewBottom - OldTop;
-
- hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
- FillRect(hdcmem, &rect, hbrush);
- DeleteObject(hbrush);
-
- for (i = 0; i < BlockHeight; i += w) {
- rect.top = OldTop + i;
- rect.bottom = OldTop + i + w;
-
- RedrawFile(f, hdcmem, 0, OldTop, &rect, global.showspecial); /* Draw on the hdc! */
- }
- } else {
- rect.left = OldTop;
- rect.right = f->width;
- rect.top = 0;
- rect.bottom = NewBottom;
- InvalidateRect(f->hwnd, &rect, TRUE);
- UpdateWindow(f->hwnd);
- }
- }
-
-
- /* Shift the under-part up/down */
-
- HideCaret(f->hwnd);
-
- rect.left = 0;
- rect.right = f->width;
-
- if (NewBottom < OldBottom) {
- if (OldBottom < f->height) {
- rect.top = NewBottom;
- rect.bottom = f->height;
- ScrollWindow(f->hwnd, 0, NewBottom - OldBottom, NULL, &rect);
- } else if (NewBottom < f->height) {
- rect.top = NewBottom;
- rect.bottom = f->height;
- InvalidateRect(f->hwnd, &rect, TRUE);
- }
- } else if (NewBottom > OldBottom) {
- if (NewBottom < f->height) {
- rect.top = OldBottom;
- rect.bottom = f->height;
- ScrollWindow(f->hwnd, 0, NewBottom - OldBottom, NULL, &rect);
- }
- }
-
-
- /* Redraw the screen */
-
- if (hbitmap != NULL) {
- BitBlt(hdc, 0, OldTop, f->width, BlockHeight, hdcmem, 0, OldTop, SRCCOPY);
- }
- //ShowCaret(f->hwnd);
-
- ReleaseDC(f->hwnd, hdc);
- DeleteDC(hdcmem);
- if (hbitmap != NULL) DeleteObject(hbitmap);
-
- /*if (CURPARA(f) != global.cpospara)*/ FillCPos(f, CURPARA(f), 0, -1);
-
- //i = POS2ABS(f->current);
- //CURX(f) = global.cpos[i].x;
- //CURY(f) = global.cpos[i].y;
- f->pseudo = f->cursor;
- DoCaret(f, CURX(f), CURY(f) - CURLINE(f)->height, TRUE);
- Triangles(f);
- ShowCaret(f->hwnd);
- }
-
-
- void ReformatFile (FILEOPTIONS *f)
- {
- POSITION p;
-
- for (PARAOF(p) = f->paragraph; PARAOF(p) != NULL; PARAOF(p) = PARAOF(p)->next) {
- LINEOF(p) = PARAOF(p)->lines;
- POSOF(p) = 0;
-
- ReformatParagraph(f, p, NULL, 0);
- }
- }
-