home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
-
- #include "jwp.h"
-
-
- static BOOL HasSelection, AtStart;
- static POINT OldPoint, LeftPoint, RightPoint;
- static POSITION OldPos, LeftPos, RightPos;
- static int LastDirection;
-
-
-
- #define GETPOS(x) (&UNITOF(x,POSOF(x)) - PARAOF(x)->text)
- #define SWAPALL() { \
- POSITION TempPos; \
- POINT TempPoint; \
- TempPos = LeftPos; LeftPos = RightPos; RightPos = TempPos; \
- TempPoint = LeftPoint; LeftPoint = RightPoint; RightPoint = TempPoint; \
- }
-
-
- static void MoveLeftRight (POSITION *oldpos, int Direction, BOOL abs)
- {
- POSITION p = *oldpos;
- int len;
-
- if (abs) {
- if (Direction > 0) {
- len = unitlen(PARAOF(p)->text);
- if (POSOF(p) < len) {
- POSOF(p)++;
- } else if (PARAOF(p)->next != NULL) {
- PARAOF(p) = PARAOF(p)->next;
- POSOF(p) = 0;
- }
- } else {
- if (POSOF(p) > 0) {
- POSOF(p)--;
- } else {
- POSOF(p) = -1;
- }
- /*
- } else if (PARAOF(p)->prev != NULL) {
- PARAOF(p) = PARAOF(p)->prev;
- POSOF(p) = unitlen(PARAOF(p)->text);
- }
- */
- }
-
- *oldpos = p;
- return;
- }
-
-
- if (Direction > 0) {
- if (POSOF(p) < LINEOF(p)->length) {
- POSOF(p)++;
- } else if (LINEOF(p)->next != NULL) {
- LINEOF(p) = LINEOF(p)->next;
- POSOF(p) = 0;
- } else if (PARAOF(p)->next != NULL) {
- PARAOF(p) = PARAOF(p)->next;
- LINEOF(p) = PARAOF(p)->lines;
- POSOF(p) = 0;
- }
- } else {
- if (POSOF(p) > 0) {
- POSOF(p)--;
- } else {
- POSOF(p) = -1;
- }
- /*
- } else if (LINEOF(p)->prev != NULL) {
- LINEOF(p) = LINEOF(p)->prev;
- POSOF(p) = (LINEOF(p)->length > 0 ? LINEOF(p)->length - 1 : LINEOF(p)->length);
- } else if (PARAOF(p)->prev != NULL) {
- PARAOF(p) = PARAOF(p)->prev;
- LINEOF(p) = PARAOF(p)->lastline;
- POSOF(p) = (LINEOF(p)->length > 0 ? LINEOF(p)->length - 1 : LINEOF(p)->length);
- }
- */
- }
-
- *oldpos = p;
- }
-
-
-
- void RecordAnchor (FILEOPTIONS *f, POSITION pos, POINT xypos)
- {
- POSITION temppos;
-
- HasSelection = (SELPARA1(f) != NULL && SELPARA2(f) != NULL);
-
- if (HasSelection && SELTYPE(f) != SEL_SELECTION) {
- HasSelection = FALSE;
- TurnOffSelection(f);
- CharInput(f, '\0');
- }
-
- OldPos = pos;
- OldPoint = xypos;
-
- if (!HasSelection) return;
-
- /*
- StartGap = (ISKANJI(SELCHAR1(f).kanji) || SELPOS1(f) <= 0 ||
- ISKANJI(SELPARA1(f)->text[SELPOS1(f) - 1].kanji));
- */
- AtStart = (&SELCHAR1(f) == &UNITOF(OldPos,POSOF(OldPos)));
-
- temppos = OldPos;
- MoveLeftRight (&temppos, -1, FALSE);
-
- if (!AtStart && &SELCHAR2(f) != &UNITOF(temppos,POSOF(temppos)))
- ErrorMessage(global.hwnd, "RecordAnchor: Bad Cursor Position!");
- }
-
-
-
- void ChangeAnchor (int dx, int dy)
- {
- OldPoint.x += dx;
- OldPoint.y += dy;
- }
-
-
-
- int RelativePosition (POSITION p1, POSITION p2, BOOL abs)
- {
- PARAGRAPH far *p;
- ONELINE far *lp;
-
- if (PARAOF(p1) == PARAOF(p2)) {
- if (abs) return (POSOF(p1) - POSOF(p2));
-
- if (LINEOF(p1) == LINEOF(p2)) {
- return (POSOF(p1) - POSOF(p2));
- } else {
- for (lp = LINEOF(p1); lp != NULL; lp = lp->next) {
- if (lp == LINEOF(p2)) return (-1);
- }
- return (+1);
- }
- }
-
- for (p = PARAOF(p1); p != NULL; p = p->next) {
- if (p == PARAOF(p2)) return (-1);
- }
-
- return (+1);
- }
-
-
-
- void DropAnchor (FILEOPTIONS *f, POSITION NewPos, POINT NewPoint, int Direction)
- {
- int i;
- POSITION DummyPos1, DummyPos2;
-
-
- if (Direction == 0) {
- Direction = RelativePosition(NewPos, OldPos, FALSE);
- if (Direction == 0) return;
- }
-
- LastDirection = Direction;
-
-
- LeftPos = OldPos; LeftPoint = OldPoint;
- RightPos = NewPos; RightPoint = NewPoint;
- SELTYPE(f) = SEL_SELECTION;
- SELNOW(f) = FALSE;
-
-
- /* Now the real headache begins! */
-
- if (!HasSelection) {
- if (Direction < 0) {
- SELPARA1(f) = PARAOF(NewPos); SELPOS1(f) = GETPOS(NewPos);
- MoveLeftRight(&OldPos, -1, FALSE);
- SELPARA2(f) = PARAOF(OldPos); SELPOS2(f) = GETPOS(OldPos);
- SWAPALL();
- } else {
- SELPARA1(f) = PARAOF(OldPos); SELPOS1(f) = GETPOS(OldPos);
- MoveLeftRight(&NewPos, -1, FALSE);
- SELPARA2(f) = PARAOF(NewPos); SELPOS2(f) = GETPOS(NewPos);
- }
- } else if (AtStart) {
- if (Direction > 0) {
- /* Have we gone over the end? */
-
- PARAOF(DummyPos1) = SELPARA2(f); POSOF(DummyPos1) = SELPOS2(f);
- PARAOF(DummyPos2) = PARAOF(NewPos); POSOF(DummyPos2) = GETPOS(NewPos);
-
- i = RelativePosition(DummyPos2, DummyPos1, TRUE);
-
- if (i > 0) {
- if (PARAOF(DummyPos2) == PARAOF(DummyPos1) && POSOF(DummyPos2) == POSOF(DummyPos1) + 1) {
- /* Cancel selection */
- FlipHighlight(f);
- SELPARA1(f) = SELPARA2(f) = NULL;
- SELPOS1(f) = SELPOS2(f) = 0;
- return;
- }
-
- /* Flipped */
- MoveLeftRight(&DummyPos1, +1, TRUE);
- MoveLeftRight(&NewPos, -1, FALSE);
- SELPARA1(f) = PARAOF(DummyPos1); SELPOS1(f) = POSOF(DummyPos1);
- SELPARA2(f) = PARAOF(NewPos); SELPOS2(f) = GETPOS(NewPos);
- } else {
- SELPARA1(f) = PARAOF(NewPos); SELPOS1(f) = GETPOS(NewPos);
- }
- } else {
- SELPARA1(f) = PARAOF(NewPos);
- SELPOS1(f) = GETPOS(NewPos);
- SWAPALL();
- }
- } else {
- if (Direction > 0) {
- MoveLeftRight(&NewPos, -1, FALSE);
- SELPARA2(f) = PARAOF(NewPos);
- SELPOS2(f) = GETPOS(NewPos);
- } else {
- /* Have we gone over the end? */
-
- PARAOF(DummyPos1) = SELPARA1(f); POSOF(DummyPos1) = SELPOS1(f);
- PARAOF(DummyPos2) = PARAOF(NewPos); POSOF(DummyPos2) = GETPOS(NewPos);
-
- i = RelativePosition(DummyPos2, DummyPos1, TRUE);
-
- if (i <= 0) {
- if (PARAOF(DummyPos2) == PARAOF(DummyPos1) && POSOF(DummyPos2) == POSOF(DummyPos1)) {
- /* Cancel selection */
- FlipHighlight(f);
- SELPARA1(f) = SELPARA2(f) = NULL;
- SELPOS1(f) = SELPOS2(f) = 0;
- return;
- }
-
- /* Flipped */
- MoveLeftRight(&DummyPos1, -1, TRUE);
- SELPARA1(f) = PARAOF(NewPos); SELPOS1(f) = GETPOS(NewPos);
- SELPARA2(f) = PARAOF(DummyPos1); SELPOS2(f) = POSOF(DummyPos1);
- } else {
- MoveLeftRight(&NewPos, -1, FALSE);
- SELPARA2(f) = PARAOF(NewPos); SELPOS2(f) = GETPOS(NewPos);
- }
- SWAPALL();
- }
- }
- }
-
-
-
- void ExtendSelection (HWND hwnd, FILEOPTIONS *f)
- {
- int i;
- HDC hdc;
- RECT rect;
- POSITION p;
- BOOL StartGap = FALSE , EndGap = FALSE;
-
-
- if (SELPARA1(f) == NULL || SELPARA2(f) == NULL) return;
-
-
- HideCaret(hwnd);
- hdc = GetDC(hwnd);
-
-
- if (POSOF(LeftPos) < LINEOF(LeftPos)->length && KANJIPOS(LeftPos)) StartGap = TRUE;
- else if (POSOF(LeftPos) <= 0 || KANJIAT(LeftPos,POSOF(LeftPos)-1)) StartGap = TRUE;
-
- if (POSOF(RightPos) < LINEOF(RightPos)->length && KANJIPOS(RightPos)) EndGap = TRUE;
- else if (POSOF(RightPos) > 0 && KANJIAT(RightPos,POSOF(RightPos)-1)) EndGap = TRUE;
-
- if (POSOF(LeftPos) > 0 && CHAROF(LeftPos,POSOF(LeftPos)-1) == '\t') StartGap = FALSE;
- if (POSOF(RightPos) > 0 && CHAROF(RightPos,POSOF(RightPos)-1) == '\t') EndGap = FALSE;
-
- if (LINEOF(RightPos) == LINEOF(LeftPos)) {
- rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
- rect.top = LeftPoint.y - LINEOF(OldPos)->height - LINEGAP(f);
- rect.right = RightPoint.x - (EndGap ? (f->leading - CHARGAP(f)) : 0);
- rect.bottom = RightPoint.y + LINEGAP(f);
-
- PatBlt(hdc, rect.left, rect.top,
- rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
- } else {
- p = (LastDirection > 0) ? LeftPos : RightPos;
-
- for (;;) {
- if (LastDirection > 0) {
- if (LINEOF(RightPos) == LINEOF(p)) break;
-
- rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
- rect.top = LeftPoint.y - LINEOF(p)->height - LINEGAP(f);
- rect.right = LINEOF(p)->width - f->startx;
- rect.bottom = rect.top + LINEOF(p)->height + 2 * LINEGAP(f);
-
- if (LINEOF(p)->length > 0 && KANJIAT(p,LINEOF(p)->length-1))
- rect.right -= f->leading - CHARGAP(f);
- } else {
- if (LINEOF(LeftPos) == LINEOF(p)) break;
-
- rect.left = LEFTMARGIN(p) * BASEWIDTH(f) - f->startx - CHARGAP(f);
- rect.top = RightPoint.y - LINEOF(p)->height - LINEGAP(f);
- rect.right = RightPoint.x - (EndGap ? (f->leading - CHARGAP(f)) : 0);
- rect.bottom = rect.top + LINEOF(p)->height + 2 * LINEGAP(f);
-
- if (LINEOF(RightPos) == LINEOF(p) && POSOF(RightPos) <= 0)
- rect.right = rect.left;
- }
-
- if (rect.top > f->height) break;
-
- if (rect.bottom >= 0) {
- if (LINEOF(p)->length > 0) {
- PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
- }
- }
-
- if (LastDirection > 0) {
- i = PARAOF(p)->spacing;
- if (!NEXTLINE(p)) {
- ErrorMessage(global.hwnd, "Can't find end of block!");
- break;
- }
- StartGap = TRUE;
- LeftPoint.x = LEFTMARGIN(p) * BASEWIDTH(f) - f->startx;
- LeftPoint.y += LINEOF(p)->height + i;
- } else {
- i = LINEOF(p)->height;
- if (!PREVLINE(p)) {
- ErrorMessage(global.hwnd, "Can't find beginning of block!");
- break;
- }
- EndGap = FALSE;
- RightPoint.x = LINEOF(p)->width - f->startx;
- RightPoint.y -= i + PARAOF(p)->spacing;
-
- if (LINEOF(p)->length > 0 && KANJIAT(p,LINEOF(p)->length-1))
- RightPoint.x -= f->leading - CHARGAP(f);
- }
- }
-
- if (LeftPoint.y == RightPoint.y) {
- rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
- rect.top = LeftPoint.y - LINEOF(p)->height - LINEGAP(f);
- rect.right = LINEOF(p)->width - f->startx;
- rect.bottom = rect.top + LINEOF(p)->height + 2 * LINEGAP(f);
-
- if (LINEOF(p)->length > 0 && KANJIAT(p,LINEOF(p)->length - 1))
- rect.right -= f->leading - CHARGAP(f);
-
- if (LastDirection > 0 && LINEOF(RightPos) == LINEOF(p)) {
- if (POSOF(RightPos) > 0) {
- rect.right = RightPoint.x - (EndGap ? (f->leading - CHARGAP(f)) : 0);
-
- PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
- }
- } else if (LastDirection < 0 && LINEOF(LeftPos) == LINEOF(p)) {
- if (LINEOF(p)->length > 0) {
- rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
-
- PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
- }
- } else {
- ErrorMessage(global.hwnd, "Can't match end of block line!");
- }
- } else {
- ErrorMessage(global.hwnd, "RightPos mismatch: (%d != %d)", LeftPoint.y, RightPoint.y);
- }
- }
-
- ReleaseDC(hwnd, hdc);
- ShowCaret(hwnd);
- }
-
-
- BOOL InSelection (FILEOPTIONS *f, POSITION pos)
- {
- PARAGRAPH far *p;
- ONELINE far *lp;
- BOOL insel = FALSE;
-
- for (p = f->paragraph; p != NULL; p = p->next) {
- if (p == SELPARA1(f) || p == SELPARA2(f)) {
- for (lp = p->lines; lp != NULL; lp = lp->next) {
- if (lp == LINEOF(pos)) break;
- if (p == SELPARA1(f) && lp->position <= SELPOS1(f)) {
- if (lp->next == NULL) {
- if (lp->position + lp->length >= SELPOS1(f)) insel = TRUE;
- } else {
- if (lp->position + lp->length > SELPOS1(f)) insel = TRUE;
- }
- }
- if (p == SELPARA2(f)) {
- if (lp->next == NULL) {
- if (lp->position + lp->length >= SELPOS2(f)) insel = FALSE;
- } else {
- if (lp->position + lp->length > SELPOS2(f)) insel = FALSE;
- }
- break;
- }
- }
- }
- if (p == PARAOF(pos)) break;
- }
-
- return (insel);
- }
-
-
- void AbsoluteToPosition (POSITION abs, POSITION *pos)
- {
- int offset;
- POSITION p;
- ONELINE far *lp;
-
- if (POSOF(abs) < 0) { /* Negative position, use at own risk! */
- *pos = abs;
- LINEOF(*pos) = PARAOF(abs)->lines;
- return;
- }
-
- PARAOF(p) = PARAOF(abs);
- POSOF(p) = 0;
-
- for (lp = PARAOF(p)->lines; ; lp = lp->next) {
- if (lp != NULL) {
- LINEOF(p) = lp;
- offset = POS2ABS(p);
- }
-
- if (lp == NULL || offset > POSOF(abs)) {
- if (lp == NULL) {
- LINEOF(p) = PARAOF(abs)->lastline;
- } else {
- LINEOF(p) = LINEOF(p)->prev;
- }
- offset = POS2ABS(p);
- POSOF(p) = POSOF(abs) - offset;
- break;
- }
- }
-
- *pos = p;
- }
-