home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-02 | 41.4 KB | 1,609 lines | [TEXT/MPCC] |
- // { WASTE PROJECT }
- // { Drawing Selections, Activating, Updating, Scrolling, etc. }
-
- // { Copyright © 1993-1994 Marco Piovanelli }
- // { All Rights Reserved }
-
- // conversion to C by Dan Crevier
-
- #include "WASTEIntf.h"
- #include <QDOffscreen.h>
-
- // { values for _WEArrowOffset action parameter: }
- // { plain arrow keys }
- #define kGoLeft 0
- #define kGoRight 1
- #define kGoUp 2
- #define kGoDown 3
-
- // { modifiers }
- #define kOption 4
- #define kCommand 8
-
- // { option + arrow combos }
- #define kGoWordStart kGoLeft + kOption
- #define kGoWordEnd kGoRight + kOption
- #define kGoTextStart kGoUp + kOption
- #define kGoTextEnd kGoDown + kOption
-
- // { command + arrow combos }
- #define kGoLineStart kGoLeft + kCommand
- #define kGoLineEnd kGoRight + kCommand
- #define kGoPageStart kGoUp + kCommand
- #define kGoPageEnd kGoDown + kCommand
-
-
- pascal void ClearHiliteBit(void)
- {
- LMSetHiliteMode(LMGetHiliteMode() & 0x7f);
- }
-
- Boolean SLPixelToChar(LinePtr pLine, WERunAttributesPtr pAttrs, Ptr pSegment,
- long segmentStart, long segmentLength, JustStyleCode styleRunPosition,
- void *callbackData);
-
- Boolean SLPixelToChar(LinePtr pLine, WERunAttributesPtr pAttrs, Ptr pSegment,
- long segmentStart, long segmentLength, JustStyleCode styleRunPosition,
- void *callbackData)
- {
- struct SLPixelToCharData *p = (struct SLPixelToCharData *) callbackData;
- WEPtr pWE = p->pWE;
- Fixed slop;
- Fixed width;
- short cType;
-
- // { if this is the first style run on the line, subtract pen indent from pixelWidth }
- if (styleRunPosition <= smLeftStyleRun)
- {
- p->pixelWidth = p->pixelWidth - BSL(_WECalcPenIndent(pLine->lineSlop, pWE->alignment), 16);
- }
-
- if (pAttrs->runStyle.tsObject != nil)
- {
-
- // { EMBEDDED OBJECT }
- // { calculate object width as Fixed }
- width = BSL((*(WEObjectDescHandle)pAttrs->runStyle.tsObject)->objectSize.h, 16);
-
- // { subtract object width from pixelWidth }
- p->pixelWidth = p->pixelWidth - width;
-
- // { if pixelWidth has gone negative, the point is within the object: }
- // { find out whether it's closer to the left edge or to the right edge }
- if ((p->pixelWidth < 0) && (p->pixelWidth + BSR(width, 1) < 0))
- {
- *p->edge = kLeadingEdge;
- p->offset = segmentStart;
- }
- else
- {
- *p->edge = kTrailingEdge;
- p->offset= segmentStart + 1;
- }
- }
- else
- {
-
- // { REGULAR TEXT }
-
- // { if this is the last segment on the line, strip the last blank character (if any), }
- // { unless it is the last non-CR character in the whole text stream }
- if (!(styleRunPosition & 1))
- {
- if ((segmentStart + segmentLength < pWE->textLength) ||
- pSegment[segmentLength - 1] == kEOL)
- {
- cType = CharType(pSegment, segmentLength - 1);
- if (cType & (smcTypeMask + smcClassMask) == smCharPunct + smPunctBlank)
- {
- if ((cType & smcDoubleMask) == 0)
- segmentLength = segmentLength - 1;
- else
- segmentLength = segmentLength - 2;
- }
- }
- }
-
- // { calculate slop for this text segment (justified text only) }
- if (pWE->alignment == weJustify)
- {
- slop = FixMul(PortionLine(pSegment, segmentLength, styleRunPosition,
- *(Point *)(&kOneToOneScaling), *(Point *)(&kOneToOneScaling)),
- pLine->lineJustAmount);
- }
- else
- {
- slop = 0;
- }
-
- // { call PixelToChar for this segment }
- #ifdef WASTE_TABS
- {
- long ii,
- beginChar,
- offset;
- Fixed lastWidth,
- tabWidth;
-
- width = p->pixelWidth;
- beginChar = 0;
- offset = 0;
- for (ii = 0; ii < segmentLength && width > 0; ii++)
- if (pSegment[ii] == '\t')
- {
- /* Measure this sub-segment */
-
- lastWidth = width;
- offset += NPixel2Char(pSegment + beginChar, ii - beginChar,
- slop, lastWidth,
- (Boolean *)p->edge, &width,
- styleRunPosition,
- *(Point *)(&kOneToOneScaling),
- *(Point *)(&kOneToOneScaling));
- if (width >= 0)
- {
- p->hPos += lastWidth - width;
-
- tabWidth = (p->hPos / (WASTE_TAB_SIZE << 16) + 1) * (WASTE_TAB_SIZE << 16)
- - p->hPos;
- p->hPos += tabWidth;
- if (width - tabWidth < 0)
- {
- if (width - (tabWidth + (1 << 16))/2 > 0)
- {
- *p->edge = -1;
- offset++;
- }
- else
- *p->edge = 0;
- width = -1 << 16;
- }
- else
- {
- offset++;
- width -= tabWidth;
- }
-
- beginChar = ii + 1;
- }
- }
- if (width > 0)
- {
- lastWidth = width;
- offset += NPixel2Char(pSegment + beginChar, segmentLength - beginChar,
- slop, lastWidth,
- (Boolean *)p->edge, &width,
- styleRunPosition,
- *(Point *)(&kOneToOneScaling),
- *(Point *)(&kOneToOneScaling));
- p->hPos += lastWidth - width;
- }
-
- p->offset = segmentStart + offset;
- }
- #else
- p->offset = segmentStart + NPixel2Char(pSegment, segmentLength, slop, p->pixelWidth,
- (Boolean *)p->edge, &width, styleRunPosition, *(Point *)(&kOneToOneScaling),
- *(Point *)(&kOneToOneScaling));
- #endif
-
- // { update pixelWidth for next iteration }
- p->pixelWidth = width;
- }
-
- // { if pixelWidth has gone negative, we're finished; otherwise go to next run }
- return (p->pixelWidth < 0);
- }
-
- pascal long WEGetOffset(const LongPt *thePoint, char *edge, WEHandle hWE)
- {
- // { given a long point in local coordinates, }
- // { find the text offset corresponding to the nearest glyph }
-
- WEPtr pWE;
- long lineIndex;
- Fixed pixelWidth;
- Boolean saveWELock;
- long retval;
- struct SLPixelToCharData callbackData;
- LongPt tempPoint = *thePoint; // so we don't change original point
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { offset thePoint so that it is relative to the top left corner of the destination rectangle }
- tempPoint.v = tempPoint.v - pWE->destRect.top;
- tempPoint.h = tempPoint.h - pWE->destRect.left;
-
- // { if the point is above the destination rect, return zero }
- if (tempPoint.v < 0)
- {
- retval = 0;
- *edge = kTrailingEdge;
- }
- else
- {
- // { if the point is below the last line, return last char offset }
- if (tempPoint.v >= WEGetHeight(0, LONG_MAX, hWE))
- {
- retval = pWE->textLength;
- *edge = kLeadingEdge;
- }
- else
- {
- // { find the line index corresponding to the vertical pixel offset }
- lineIndex = _WEPixelToLine(tempPoint.v, hWE);
-
- // { express the horizontal pixel offset as a Fixed value }
- pixelWidth = BSL(tempPoint.h, 16);
-
- // { walk through the segments on this line calling PixelToChar }
- callbackData.pWE = pWE;
- #ifdef WASTE_TABS
- callbackData.hPos = 0;
- #endif
- callbackData.pixelWidth = pixelWidth;
- callbackData.edge = edge;
- callbackData.offset = 0;
- _WESegmentLoop(lineIndex, lineIndex, SLPixelToChar, (void *)&callbackData, hWE);
- retval = callbackData.offset;
- }
- }
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
-
- return retval;
- }
-
- Boolean SLCharToPixel(LinePtr pLine, WERunAttributesPtr pAttrs, Ptr pSegment,
- long segmentStart, long segmentLength, JustStyleCode styleRunPosition,
- void *callbackData);
-
- Boolean SLCharToPixel(LinePtr pLine, WERunAttributesPtr pAttrs, Ptr pSegment,
- long segmentStart, long segmentLength, JustStyleCode styleRunPosition,
- void *callbackData)
- {
- struct SLCharToPixelData *p = (struct SLCharToPixelData *) callbackData;
- WEPtr pWE = p->pWE;
- Fixed slop;
- short width;
- Boolean isInSegment;
-
- // { is offset within this segment? }
- isInSegment = (p->offset < segmentStart + segmentLength);
-
- // { if this is the first style run on the line, add pen indent to thePoint.h }
- if (styleRunPosition <= smLeftStyleRun)
- {
- p->thePoint->h = p->thePoint->h + _WECalcPenIndent(pLine->lineSlop, pWE->alignment);
- }
-
- if (pAttrs->runStyle.tsObject != nil)
- {
-
- // { EMBEDDED OBJECT }
- if (isInSegment)
- width = 0;
- else
- width = (*(WEObjectDescHandle)pAttrs->runStyle.tsObject)->objectSize.h;
- }
- else
- {
- //{ REGULAR TEXT }
- // { calculate slop for this text segment (justified text only) }
- if (pWE->alignment == weJustify)
- {
- slop = FixMul(PortionLine(pSegment, segmentLength, styleRunPosition,
- *(Point *)(&kOneToOneScaling), *(Point *)(&kOneToOneScaling)),
- pLine->lineJustAmount);
- }
- else
- {
- slop = 0;
- }
-
- // { call CharToPixel to get width of segment up to specified offset }
- #ifdef WASTE_TABS
- {
- long ii,
- beginChar;
-
- beginChar = 0;
- width = 0;
- for (ii = 0; ii < segmentLength && p->offset > segmentStart + ii; ii++)
- if (pSegment[ii] == '\t')
- {
- p->thePoint->h += NChar2Pixel(pSegment + beginChar, ii - beginChar, slop,
- p->offset - segmentStart - beginChar,
- smHilite, styleRunPosition,
- *(Point *)(&kOneToOneScaling),
- *(Point *)(&kOneToOneScaling));
- beginChar = ii + 1;
- p->thePoint->h = (p->thePoint->h / WASTE_TAB_SIZE + 1) * WASTE_TAB_SIZE;
- }
- p->thePoint->h += NChar2Pixel(pSegment + beginChar, segmentLength - beginChar, slop,
- p->offset - segmentStart - beginChar,
- smHilite, styleRunPosition,
- *(Point *)(&kOneToOneScaling),
- *(Point *)(&kOneToOneScaling));
- }
- #else
- width = NChar2Pixel(pSegment, segmentLength, slop,
- p->offset - segmentStart, smHilite, styleRunPosition,
- *(Point *)(&kOneToOneScaling), *(Point *)(&kOneToOneScaling));
- #endif
- }
-
- // { advance thePoint.h by the width of this segment }
- p->thePoint->h = p->thePoint->h + width;
-
- // { drop out of loop when we reach offset }
- return isInSegment;
- }
-
- pascal void WEGetPoint(long offset, LongPt *thePoint, short *lineHeight, WEHandle hWE)
- {
- // { given a byte offset into the text, find the corresponding glyph position }
- // { this routine is useful for highlighting the text and for positioning the caret }
-
- WEPtr pWE;
- LinePeek pLine;
- long lineIndex;
- Boolean saveWELock;
- struct SLCharToPixelData callbackData;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle) hWE, true);
- pWE = *hWE;
-
- // { the base point is the top left corner of the destination rectangle }
- *thePoint = *(LongPt *)&pWE->destRect.top;
-
- // { first of all find the line on which the glyph lies }
- lineIndex = WEOffsetToLine(offset, hWE);
-
- // { calculate the vertical coordinate and the line height }
- pLine = (LinePeek)&((*pWE->hLines)[lineIndex]);
- thePoint->v = thePoint->v + pLine->first.lineOrigin;
- *lineHeight = pLine->second.lineOrigin - pLine->first.lineOrigin;
-
- if ((offset == pWE->textLength) && (WEGetChar(offset - 1, hWE) == 0xd /* '\r' */))
- {
- // { SPECIAL CASE: if offset is past the last character and }
- // { the last character is a carriage return, return a point below the last line }
-
- thePoint->v = thePoint->v + *lineHeight;
- thePoint->h = thePoint->h + _WECalcPenIndent(pWE->destRect.right - pWE->destRect.left, pWE->alignment);
- }
- else
- {
- callbackData.pWE = pWE;
- callbackData.offset = offset;
- callbackData.thePoint = thePoint;
- // { to get the horizontal coordinate, walk through the style runs on this line }
- _WESegmentLoop(lineIndex, lineIndex, SLCharToPixel, (void *)&callbackData, hWE);
- }
-
- // { pin the horizontal coordinate to the destination rectangle }
- thePoint->h = _WEPinInRange(thePoint->h, pWE->destRect.left, pWE->destRect.right);
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal void WEFindLine(long offset, char edge, long *lineStart, long *lineEnd, WEHandle hWE)
- {
- WEPtr pWE;
- LineArrayPtr pLine;
-
- pWE = *hWE;
- pLine = &(*pWE->hLines)[WEOffsetToLine(offset, hWE)];
- *lineStart = pLine[0].lineStart;
- *lineEnd = pLine[1].lineStart;
- }
-
-
- pascal long _WEGetLineStart(long lineNo, WEHandle hWE)
- {
- WEPtr pWE;
-
- pWE = *hWE;
- if (lineNo >= pWE->nLines)
- lineNo = pWE->nLines - 1;
- return ((*pWE->hLines)[lineNo].lineStart);
- }
-
-
- pascal short _WEGetContext(long offset, long *contextStart, long *contextEnd,
- WEHandle hWE)
- {
- // { This function finds a range of characters ("context"), all belonging to the same script }
- // { and centered around the specified offset. }
- // { The function result is the ID of a font belonging to this script. }
- // { Ideally, the context should consist of a whole script run, but in practice the returned }
- // { context can be narrower, for performance and other reasons (see below) }
-
- long index, saveIndex, saveRunEnd;
- WERunInfo runInfo;
- ScriptCode script1, script2;
- short retval;
-
- if (BTST((*hWE)->flags, weFNonRoman))
- {
- // { if more than one script is installed, limit the search of script run boundaries }
- // { to a single line, for speed's sake }
- WEFindLine(offset, kLeadingEdge, contextStart, contextEnd, hWE);
-
- // { find the style run the specified offset is in }
- index = _WEOffsetToRun(offset, hWE);
- _WEGetIndStyle(index, &runInfo, hWE);
-
- // { return the style run font as function result }
- retval = runInfo.runAttrs.runStyle.tsFont;
-
- // { find the script code associated with this style run }
- script1 = Font2Script(runInfo.runAttrs.runStyle.tsFont);
-
- // { save index and runInfo.runEnd for the second while loop }
- saveIndex = index;
- saveRunEnd = runInfo.runEnd;
-
- // { walk backwards across style runs preceding offset, looking for a script run boundary }
- while (runInfo.runStart > *contextStart)
- {
- index = index - 1;
- _WEGetIndStyle(index, &runInfo, hWE);
- script2 = Font2Script(runInfo.runAttrs.runStyle.tsFont);
- if (script1 != script2)
- {
- *contextStart = runInfo.runEnd;
- break;
- }
- }
-
- // { restore index and runInfo.runEnd }
- index = saveIndex;
- runInfo.runEnd = saveRunEnd;
-
- // { walk forward across style runs following offset, looking for a script run boundary }
- while (runInfo.runEnd < *contextEnd)
- {
- index = index + 1;
- _WEGetIndStyle(index, &runInfo, hWE);
- script2 = Font2Script(runInfo.runAttrs.runStyle.tsFont);
- if (script1 != script2)
- {
- *contextEnd = runInfo.runStart;
- break;
- }
- }
- }
- else
- {
- // { only the Roman script is enabled: the whole text constitutes one script run }
- retval = systemFont;
- *contextStart = 0;
- *contextEnd = (*hWE)->textLength;
- }
-
- // { make sure the range identified by contextStart/contextEnd is contained within }
- // { the 32K byte range centered around the specified offset }
- // { the reason for this is that many Script Manager routines (e.g. FindWord and CharByte) }
- // { only accept 16-bit offsets, rather than 32-bit offsets }
-
- *contextStart = _WEPinInRange(*contextStart, offset - (SHRT_MAX / 2), offset);
- *contextEnd = _WEPinInRange(*contextEnd, offset, offset + (SHRT_MAX / 2));
-
- return retval;
- }
-
- pascal short _WEGetRestrictedContext(long offset, long *contextStart, long *contextEnd,
- WEHandle hWE)
- {
- // { This function finds a range of characters ("context"), all belonging to the same script }
- // { and centered around the specified offset. }
- // { This function returns a script run subrange and is more efficient than }
- // { _WEGetContext because it doesn't try to find the script boundaries accurately. }
-
- WERunInfo runInfo;
-
- // { just find the style run the specified offset is in }
- WEGetRunInfo(offset, &runInfo, hWE);
- *contextStart = runInfo.runStart;
- *contextEnd = runInfo.runEnd;
-
- // { make sure the range identified by contextStart/contextEnd is contained within }
- // { the 32K byte range centered around the specified offset }
- // { the reason for this is that many Script Manager routines (e.g. FindWord and CharByte) }
- // { only accept 16-bit offsets, rather than 32-bit offsets }
-
- *contextStart = _WEPinInRange(*contextStart, offset - (SHRT_MAX / 2), offset);
- *contextEnd = _WEPinInRange(*contextEnd, offset, offset + (SHRT_MAX / 2));
-
- return runInfo.runAttrs.runStyle.tsFont;
- } // { _WEGetRestrictedContext }
-
- pascal void WEFindWord(long offset, char edge, long *wordStart, long *wordEnd, WEHandle hWE)
- {
- WEPtr pWE;
- long contextStart, contextEnd;
- Handle hText;
- OffsetTable wordBreaks;
- short saveFont;
- GrafPtr savePort;
- Boolean saveTextLock;
-
- pWE = *hWE;
- hText = pWE->hText;
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { find a script context containing the specified offset }
- // { (words cannot straddle script boundaries) }
- // { and set the port font to the corresponding script font }
-
- saveFont = pWE->port->txFont;
- TextFont(_WEGetContext(offset, &contextStart, &contextEnd, hWE));
-
- // { lock the text }
- saveTextLock = _WESetHandleLock(hText, true);
-
- // { find word breaks }
- FindWord(*hText + contextStart, contextEnd - contextStart, offset - contextStart,
- (Boolean)edge, nil, wordBreaks);
-
- // { unlock the text }
- _WESetHandleLock(hText, saveTextLock);
-
- // { restore font and port }
- TextFont(saveFont);
- SetPort(savePort);
-
- // { calculate wordStart and wordEnd relative to the beginning of the text }
- *wordStart = contextStart + wordBreaks[0].offFirst;
- *wordEnd = contextStart + wordBreaks[0].offSecond;
- }
-
- pascal short WECharByte(long offset, WEHandle hWE)
- {
- WEPtr pWE;
- long contextStart, contextEnd;
- short saveFont;
- GrafPtr savePort;
- short retval;
-
- retval = smSingleByte;
- pWE = *hWE;
-
- // { exit now if there is no double-byte script system installed }
- if (!BTST(pWE->flags, weFDoubleByte))
- return retval;
-
- // { sanity check: make sure offset is within allowed bounds }
- if ((offset < 0) || (offset >= pWE->textLength))
- return retval;
-
- // { save the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { find a script context containing the specified offset }
- // { and set the port font to the corresponding script font }
- saveFont = pWE->port->txFont;
- TextFont(_WEGetRestrictedContext(offset, &contextStart, &contextEnd, hWE));
-
- // { pass CharByte a pointer to the beginning of the style run }
- // { CharByte is guaranteed not to move memory, so the text needn't be locked }
- retval = CharByte(*pWE->hText + contextStart, offset - contextStart);
-
- // { restore the port font }
- TextFont(saveFont);
-
- // { restore the port }
- SetPort(savePort);
-
- return retval;
- } // { WECharByte }
-
- pascal short WECharType(long offset, WEHandle hWE)
- {
- WEPtr pWE;
- long contextStart, contextEnd;
- Handle hText;
- short saveFont;
- GrafPtr savePort;
- Boolean saveTextLock;
- short retval;
-
- retval = 0;
- pWE = *hWE;
- hText = pWE->hText;
-
- // { sanity check: make sure offset is within allowed bounds }
- if ((offset < 0) || (offset >= pWE->textLength))
- return retval;
-
- // { save the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { find a script context containing the specified offset }
- // { and set the port font to the corresponding script font }
- saveFont = pWE->port->txFont;
- TextFont(_WEGetRestrictedContext(offset, &contextStart, &contextEnd, hWE));
-
- // { lock the text (CharType may move memory) }
- saveTextLock = _WESetHandleLock(hText, true);
-
- // { pass CharType a pointer to the beginning of the style run }
- retval = CharType(*hText + contextStart, offset - contextStart);
-
- // { unlock the text }
- _WESetHandleLock(hText, saveTextLock);
-
- // { restore the port font }
- TextFont(saveFont);
-
- // { restore the port }
- SetPort(savePort);
-
- return retval;
- } // { WECharType }
-
-
- pascal void _WEDrawCaret(long offset, WEHandle hWE)
- {
- WEPtr pWE;
- LongPt thePoint;
- Rect caretRect;
- short caretHeight;
- GrafPtr savePort;
- RgnHandle saveClip;
-
- // { the WE record must be already locked }
- pWE = *hWE;
-
- // { find the caret position using WEGetPoint }
- WEGetPoint(offset, &thePoint, &caretHeight, hWE);
- WELongPointToPoint(&thePoint, (Point *)&caretRect.top);
- if (caretRect.left > pWE->destRect.left)
- {
- caretRect.left = caretRect.left - 1;
- }
-
- // { calculate caret rectangle }
- caretRect.bottom = caretRect.top + caretHeight;
- caretRect.right = caretRect.left + kCaretWidth;
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { clip to the view region }
- saveClip = NewRgn();
- GetClip(saveClip);
- SetClip(pWE->viewRgn);
-
- // { draw the caret }
- InvertRect(&caretRect);
-
- // { restore the clip region }
- SetClip(saveClip);
- DisposeRgn(saveClip);
-
- // { restore the port }
- SetPort(savePort);
- }
-
- pascal void _WEBlinkCaret(WEHandle hWE)
- {
- WEPtr pWE;
-
- // { the WE record must be already locked }
- pWE = *hWE;
-
- // { do nothing if we're not active }
- if (!BTST(pWE->flags, weFActive))
- return;
-
- // { redraw the caret, in XOR mode }
- _WEDrawCaret(pWE->selStart, hWE);
-
- // { keep track of the current caret visibility status }
- pWE->flags = pWE->flags ^ BSL(1, weFCaretVisible);
-
- // { update caretTime }
- pWE->caretTime = TickCount();
-
- } // { _WEBlinkCaret }
-
- pascal RgnHandle WEGetHiliteRgn(long rangeStart, long rangeEnd, WEHandle hWE)
- {
- // { returns the hilite region corresponding to the specified range }
- // { the caller is responsible for disposing of the returned region }
- // { when it's finished with it }
-
- WEPtr pWE;
- RgnHandle hiliteRgn;
- LongRect selRect;
- LongPt firstPoint, lastPoint;
- short firstLineHeight, lastLineHeight;
- Rect r;
- GrafPtr savePort;
- Boolean saveWELock;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { make sure rangeStart comes before rangeEnd }
- _WEReorder(&rangeStart, &rangeEnd);
-
- // { calculate pixel location corresponding to rangeStart }
- WEGetPoint(rangeStart, &firstPoint, &firstLineHeight, hWE);
-
- // { calculate pixel location corresponding to rangeEnd }
- WEGetPoint(rangeEnd, &lastPoint, &lastLineHeight, hWE);
-
- // { open a region: rects to be hilited will be accumulated in this }
- OpenRgn();
-
- if (firstPoint.v == lastPoint.v)
- {
- // { selection range encompasses only one line }
- WESetLongRect(&selRect, firstPoint.h, firstPoint.v, lastPoint.h, lastPoint.v + lastLineHeight);
- WELongRectToRect(&selRect, &r);
- FrameRect(&r);
- }
- else
- {
- // { selection range encompasses more than one line }
- // { hilite the first line }
- WESetLongRect(&selRect, firstPoint.h, firstPoint.v, pWE->destRect.right, firstPoint.v + firstLineHeight);
- WELongRectToRect(&selRect, &r);
- FrameRect(&r);
-
- // { any lines between the first and the last one? }
- if (firstPoint.v + firstLineHeight < lastPoint.v)
- {
- // { hilite all the lines in-between }
- WESetLongRect(&selRect, pWE->destRect.left, firstPoint.v + firstLineHeight, pWE->destRect.right, lastPoint.v);
- WELongRectToRect(&selRect, &r);
- FrameRect(&r);
- }
-
- // { hilite the last line }
- WESetLongRect(&selRect, pWE->destRect.left, lastPoint.v, lastPoint.h, lastPoint.v + lastLineHeight);
- WELongRectToRect(&selRect, &r);
- FrameRect(&r);
- }
-
- // { copy the accumulated region into a new region }
- hiliteRgn = NewRgn();
- CloseRgn(hiliteRgn);
-
- // { restrict this region to the view region }
- SectRgn(hiliteRgn, pWE->viewRgn, hiliteRgn);
-
- // { restore the port }
- SetPort(savePort);
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
-
- // { return the hilite region }
- return hiliteRgn;
- }
-
- pascal void _WEHiliteRange(long rangeStart, long rangeEnd, WEHandle hWE)
- {
- WEPtr pWE;
- RgnHandle saveClip, auxRgn, hiliteRgn;
- PenState savePen;
- GrafPtr savePort;
-
- // { the WE record must be already locked }
- pWE = *hWE;
-
- // { do nothing if the specified range is empty }
- if (rangeStart == rangeEnd)
- {
- return;
- }
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { create auxiliary regions }
- saveClip = NewRgn();
- auxRgn = NewRgn();
-
- // { restrict the clip region to the view rectangle }
- GetClip(saveClip);
- SectRgn(saveClip, pWE->viewRgn, auxRgn);
- SetClip(auxRgn);
-
- // { get the hilite region corresponding to the specified range }
- hiliteRgn = WEGetHiliteRgn(rangeStart, rangeEnd, hWE);
-
- // { hilite the region or frame it, depending on the setting of the active flag }
- if (BTST(pWE->flags, weFActive))
- {
- ClearHiliteBit();
- InvertRgn(hiliteRgn);
- }
- else if (BTST(pWE->flags, weFOutlineHilite))
- {
- GetPenState(&savePen);
- PenNormal();
- PenMode(patXor);
- ClearHiliteBit();
- FrameRgn(hiliteRgn);
- SetPenState(&savePen);
- }
-
- // { restore the clip region }
- SetClip(saveClip);
-
- // { dispose of all regions }
- DisposeRgn(saveClip);
- DisposeRgn(auxRgn);
- DisposeRgn(hiliteRgn);
-
- // { restore the port }
- SetPort(savePort);
- }
-
- pascal void WESetSelection(long selStart, long selEnd, WEHandle hWE)
- {
- WEPtr pWE;
- long oldSelStart, oldSelEnd;
- Boolean saveWELock;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { invalid the null style }
- BCLR(pWE->flags, weFUseNullStyle);
-
- // { hide the caret if it's showing }
- if (BTST(pWE->flags, weFCaretVisible))
- {
- _WEBlinkCaret(hWE);
- }
-
- // { range-check parameters }
- selStart = _WEPinInRange(selStart, 0, pWE->textLength);
- selEnd = _WEPinInRange(selEnd, 0, pWE->textLength);
-
- // { set the weFAnchorIsEnd bit if selStart > selEnd, reorder the endpoints }
- if (selStart > selEnd)
- {
- BSET(pWE->flags, weFAnchorIsEnd);
- }
- else
- {
- BCLR(pWE->flags, weFAnchorIsEnd);
- }
- _WEReorder(&selStart, &selEnd);
-
- // { get old selection range }
- oldSelStart = pWE->selStart;
- oldSelEnd = pWE->selEnd;
-
- // { set new selection range }
- pWE->selStart = selStart;
- pWE->selEnd = selEnd;
-
- // { REDRAW THE SELECTION }
- // { skip this section if redrawing has been inhibited }
- if (!BTST(pWE->flags, weFInhibitRecal))
- {
- // { if we're active, invert the exclusive-OR between the old range and the new range. }
- // { if we're inactive, this optimization can't be used because of outline highlighting. }
- if (BTST(pWE->flags, weFActive))
- {
- _WEReorder(&oldSelStart, &selStart);
- _WEReorder(&oldSelEnd, &selEnd);
- _WEReorder(&oldSelEnd, &selStart);
- }
-
- _WEHiliteRange(oldSelStart, oldSelEnd, hWE);
- _WEHiliteRange(selStart, selEnd, hWE);
-
- if (!BTST(pWE->flags, weFMouseTracking))
- {
- // { redraw the caret immediately, if the selection range is empty }
- if (pWE->selStart == pWE->selEnd)
- {
- _WEBlinkCaret(hWE);
- }
- // { clear clickCount, unless we're tracking the mouse }
- pWE->clickCount = 0;
-
- // { scroll the selection into view, unless we're tracking the mouse }
- WESelView(hWE);
-
- }
- } // { if redrawing not inhibited }
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal void WESetAlignment(char alignment, WEHandle hWE)
- {
- if ((alignment >= weFlushLeft) && (alignment <= weJustify))
- {
- if (alignment != (*hWE)->alignment)
- {
- (*hWE)->alignment = alignment;
- WEUpdate(nil, hWE);
- }
- }
- }
-
- pascal long _WEArrowOffset(short action, long offset, WEHandle hWE)
- {
- // { given an action code (corresponding to a modifiers + arrow key combo) }
- // { and an offset into the text, find the offset of the new caret position }
-
- LongPt thePoint;
- long textLength, rangeStart, rangeEnd;
- short lineHeight;
- char edge;
-
- textLength = (*hWE)->textLength;
- switch (action)
- {
- case kGoLeft:
- if (offset > 0)
- {
- offset = offset - 1;
- if (WECharByte(offset, hWE) != smSingleByte)
- {
- offset = offset - 1;
- }
- }
- break;
-
- case kGoRight:
- if (offset < textLength)
- {
- if (WECharByte(offset, hWE) != smSingleByte)
- {
- offset = offset + 1;
- }
- offset = offset + 1;
- }
- break;
-
- case kGoUp:
- WEGetPoint(offset, &thePoint, &lineHeight, hWE);
- thePoint.v = thePoint.v - 1;
- offset = WEGetOffset(&thePoint, &edge, hWE);
- break;
-
- case kGoDown:
- WEGetPoint(offset, &thePoint, &lineHeight, hWE);
- thePoint.v = thePoint.v + lineHeight;
- offset = WEGetOffset(&thePoint, &edge, hWE);
- break;
-
- case kGoWordStart:
- WEFindWord(offset, kTrailingEdge, &rangeStart, &rangeEnd, hWE);
- offset = rangeStart;
- break;
-
- case kGoWordEnd:
- WEFindWord(offset, kLeadingEdge, &rangeStart, &rangeEnd, hWE);
- offset = rangeEnd;
- break;
-
- case kGoTextStart:
- offset = 0;
- break;
-
- case kGoTextEnd:
- offset = textLength;
- break;
-
- case kGoLineStart:
- WEFindLine(offset, kLeadingEdge, &rangeStart, &rangeEnd, hWE);
- offset = rangeStart;
- break;
-
- case kGoLineEnd:
- WEFindLine(offset, kTrailingEdge, &rangeStart, &rangeEnd, hWE);
- offset = rangeEnd;
- if (offset < textLength)
- {
- offset = offset - 1;
- if (WECharByte(offset, hWE) != smSingleByte)
- {
- offset = offset - 1;
- }
- }
- break;
-
- default:
- break;
- }
-
- return offset;
- }
-
- pascal void _WEDoArrowKey (short arrow, short modifiers, WEHandle hWE)
- {
- // { this routine is called by WEKey to handle arrow keys }
- // { the WE record is guaranteed to be already locked }
-
- WEPtr pWE;
- short action;
- long selStart, selEnd;
- long caretLoc, anchor;
-
- pWE = *hWE;
-
- // { calculate the "action" parameter for _WEArrowOffset from arrow and modifiers }
- action = arrow - kArrowLeft; // { possible range: 0..3 }
- if (modifiers & optionKey)
- {
- action = action + kOption;
- }
- if (modifiers & cmdKey)
- {
- action = action + kCommand;
- }
-
- // { get selection range }
- selStart = pWE->selStart;
- selEnd = pWE->selEnd;
-
- if ((modifiers & shiftKey) == 0)
- {
- // { if selection range isn't empty, collapse it to one of the endpoints }
- if (selStart < selEnd)
- {
- if ((arrow == kArrowLeft) || (arrow == kArrowUp))
- {
- caretLoc = selStart;
- }
- else
- {
- caretLoc = selEnd;
- }
- }
- else
- {
- // { otherwise move the insertion point }
- caretLoc = _WEArrowOffset(action, selStart, hWE);
- }
-
- // { set anchor to caretLoc, so new selection will be empty }
- anchor = caretLoc;
- }
- else
- {
- // { shift key was held down: extend the selection rather than replacing it }
- // { find out which selection boundary is the anchor and which is the free endpoint }
- if (BTST(pWE->flags, weFAnchorIsEnd))
- {
- anchor = selEnd;
- caretLoc = selStart;
- }
- else
- {
- anchor = selStart;
- caretLoc = selEnd;
- }
-
- // { move the free endpoint }
- caretLoc = _WEArrowOffset(action, caretLoc, hWE);
- }
-
- // { select the new selection }
- WESetSelection(anchor, caretLoc, hWE);
- }
-
- pascal Boolean WEAdjustCursor(Point mouseLoc, RgnHandle mouseRgn, WEHandle hWE)
- {
- // { Call WEAdjustCursor to set the cursor shape when the mouse is in the view rectangle. }
- // { MouseRgn should be either a valid region handle or NIL. }
- // { If mouseRgn is supplied (i.e., if it's not NIL), it is intersected with a region }
- // { in global coordinates within which the cursor is to retain its shape. }
- // { WEAdjustCursor returns TRUE if the cursor has been set. }
- // { Your application should set the cursor only if WEAdjustCursor returns FALSE. }
-
- WEPtr pWE;
- RgnHandle auxRgn, hiliteRgn;
- enum { kIBeam, kArrow} cursorType;
- Point portDelta;
- GrafPtr savePort;
- Boolean saveWELock;
- Boolean adjustCursor;
- Point zeroPoint = {0, 0};
-
- adjustCursor = false;
- cursorType = kIBeam;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { calculate delta between the local coordinate system and the global one }
- portDelta = zeroPoint;
- LocalToGlobal(&portDelta);
-
- // { calculate the visible portion of the view rectangle, in global coordinates }
- auxRgn = NewRgn();
- CopyRgn(pWE->viewRgn, auxRgn);
- SectRgn(auxRgn, pWE->port->visRgn, auxRgn);
- OffsetRgn(auxRgn, portDelta.h, portDelta.v);
-
- if (PtInRgn(mouseLoc, auxRgn))
- {
- // { mouse is within view rectangle: it's up to us to set the cursor }
- adjustCursor = true;
-
- // { if drag-and-drop is enabled, see if the mouse is within current selection }
- if (BTST(pWE->flags, weFDragAndDrop))
- {
- if (pWE->selStart < pWE->selEnd)
- {
-
- // { get current hilite region in global coordinates }
- hiliteRgn = WEGetHiliteRgn(pWE->selStart, pWE->selEnd, hWE);
- OffsetRgn(hiliteRgn, portDelta.h, portDelta.v);
-
- // { if mouse is within selection, set cursor to an arrow, else to an I-beam }
- // { (actually, we still use an I-beam if less than DoubleTime ticks have elapsed }
- // { since the last mouse click, so that the cursor doesn't turn into an arrow while }
- // { triple-clicking + dragging a range of lines) }
-
- if (PtInRgn(mouseLoc, hiliteRgn) && (TickCount() > pWE->clickTime + GetDblTime()))
- {
- cursorType = kArrow; // { use arrow cursor }
- CopyRgn(hiliteRgn, auxRgn);
- }
- else
- {
- DiffRgn(auxRgn, hiliteRgn, auxRgn);
- }
-
- // { dispose of the hilite region }
- DisposeRgn(hiliteRgn);
-
- } // { if drag-and-drop is enabled }
- }
-
- // { set the cursor }
- if (cursorType == kIBeam)
- SetCursor(*GetCursor(iBeamCursor));
- else
- SetCursor(&qd.arrow);
-
- // { set mouseRgn, if provided }
- if (mouseRgn != nil)
- {
- SectRgn(mouseRgn, auxRgn, mouseRgn);
- }
- }
- else
- {
- // { mouse is outside view rectangle: don't set the cursor; subtract viewRgn from mouseRgn }
- if (mouseRgn != nil)
- {
- DiffRgn(mouseRgn, auxRgn, mouseRgn);
- }
- }
- // { dispose of the temporary region }
- DisposeRgn(auxRgn);
-
- // { restore the port }
- SetPort(savePort);
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
-
- return adjustCursor;
- }
-
- pascal void WEIdle(long *maxSleep, WEHandle hWE)
- {
- WEPtr pWE;
- long caretInterval, sleepTime;
- Boolean saveWELock;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { the caret blinks only if we're active and the selection point is empty }
- if (BTST(pWE->flags, weFActive) && (pWE->selStart == pWE->selEnd))
- {
- // { the low-memory global variable CaretTime contains the preferred interval }
- // { between successive inversions of the caret }
- caretInterval = GetCaretTime();
-
- // { calculate how many ticks we can sleep before we need to invert the caret }
- // { the caretTime field of the WE record contains the time of the last inversion }
- sleepTime = caretInterval - (TickCount() - pWE->caretTime);
-
- // { if sleepTime has gone negative, invert the caret }
- if (sleepTime <= 0)
- {
- _WEBlinkCaret(hWE);
- sleepTime = caretInterval;
- }
- }
- else
- {
- // { if we don't need to blink the caret, we can sleep forever }
- sleepTime = LONG_MAX;
- }
-
- // { return sleepTime to the caller if maxSleep isn't NIL }
- if (maxSleep != nil)
- {
- *maxSleep = sleepTime;
- }
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal void WEUpdate(RgnHandle updateRgn, WEHandle hWE)
- {
- WEPtr pWE;
- long firstLine, lastLine;
- Rect auxRect;
- RgnHandle saveClip, auxRgn;
- GrafPtr savePort;
- Boolean saveWELock;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { save the clip region }
- saveClip = NewRgn();
- GetClip(saveClip);
-
- // { clip to the insersection between updateRgn and the view rectangle }
- // { (updateRgn may be NIL; in this case, just clip to the view rectangle) }
- auxRgn = NewRgn();
- if (updateRgn != nil)
- {
- SectRgn(updateRgn, pWE->viewRgn, auxRgn);
- }
- else
- {
- CopyRgn(pWE->viewRgn, auxRgn);
- }
- SetClip(auxRgn);
-
- if (EmptyRgn(auxRgn) == false)
- {
- // { set auxRect to the bounding box of the update region (clipped to the view rectangle) }
- auxRect = (*auxRgn)->rgnBBox;
-
- // { find out which lines need to be redrawn }
- firstLine = _WEPixelToLine(auxRect.top - pWE->destRect.top, hWE);
- lastLine = _WEPixelToLine((auxRect.bottom - 1) - pWE->destRect.top, hWE);
-
- // { draw them (if updateRgn is NIL, erase each line rectangle before redrawing) }
- _WEDrawLines(firstLine, lastLine, (updateRgn == nil), hWE);
-
- // { hilite the selection range or draw the caret (only if active) }
- if (pWE->selStart < pWE->selEnd)
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
- else if (BTST(pWE->flags, weFCaretVisible))
- {
- _WEBlinkCaret(hWE);
- BSET(pWE->flags, weFCaretVisible);
- }
- }
-
- DisposeRgn(auxRgn);
-
- // { restore the clip region }
- SetClip(saveClip);
- DisposeRgn(saveClip);
-
- // { restore the port }
- SetPort(savePort);
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal void WEDeactivate(WEHandle hWE)
- {
- WEPtr pWE;
- Boolean saveWELock;
-
- if (!WEIsActive(hWE)) return;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { hide the selection range or the caret }
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
- if (BTST(pWE->flags, weFCaretVisible))
- {
- _WEBlinkCaret(hWE);
- }
-
- // { clear the active flag }
- BCLR(pWE->flags, weFActive);
-
- // { frame the selection }
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
-
- // { dispose of the offscreen graphics world, if any }
- if (pWE->offscreenPort != nil)
- {
- DisposeGWorld((GWorldPtr)(pWE->offscreenPort));
- pWE->offscreenPort = nil;
- }
-
- // { notify Text Services }
- if (pWE->tsmReference != nil)
- {
- DeactivateTSMDocument(pWE->tsmReference);
- }
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal void WEActivate(WEHandle hWE)
- {
- WEPtr pWE;
- Boolean saveWELock;
-
- if (WEIsActive(hWE)) return;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { remove the selection frame }
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
-
- // { set the active flag }
- BSET(pWE->flags, weFActive);
-
- // { show the selection range }
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
-
- // { notify Text Services }
- if (pWE->tsmReference != nil)
- {
- ActivateTSMDocument(pWE->tsmReference);
- }
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal Boolean WEIsActive(WEHandle hWE)
- {
- // { return TRUE iff the specified WE instance is currently active }
- return BTST((*hWE)->flags, weFActive);
- }
-
- pascal void WEScroll(long hOffset, long vOffset, WEHandle hWE)
- {
- WEPtr pWE;
- Rect viewRect;
- RgnHandle updateRgn;
- GrafPtr savePort;
- Boolean hideOutline, saveWELock;
-
- // { do nothing if both scroll offsets are zero }
- if ((hOffset == 0) && (vOffset == 0))
- return;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { hide the caret if it's showing }
- if (BTST(pWE->flags, weFCaretVisible))
- {
- _WEBlinkCaret(hWE);
- }
-
- #ifdef WEPINSCROLL
- // CKT Sep 12 94 Begin - Added PinScroll behavior
- if(vOffset > 0){
- // if top of the destRect would be moved below top of the viewRect
- if(pWE->destRect.top + vOffset > pWE->viewRect.top){
- vOffset += -((pWE->destRect.top + vOffset) - pWE->viewRect.top);
- }
- }else if(vOffset < 0){
- //if bottom of the destRect would be moved above bottom of the viewRect
- if(pWE->destRect.bottom + vOffset < pWE->viewRect.bottom){
- vOffset += -((pWE->destRect.bottom + vOffset) - pWE->viewRect.bottom);
- }
- }
- // CKT Sep 12 94 End
- #endif
-
- // { set up the port }
- GetPort(&savePort);
- SetPort(pWE->port);
-
- // { if we're inactive and outline highlighting is on, we have to temporarily }
- // { hide the selection outline while scrolling to avoid a cosmetic bug }
- hideOutline = false;
- if (!BTST(pWE->flags, weFActive))
- if (BTST(pWE->flags, weFOutlineHilite))
- {
- hideOutline = true;
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
- BCLR(pWE->flags, weFOutlineHilite);
- }
-
- // { if we're currently tracking a drag, notify the Drag Manager we're about to scroll }
- if (pWE->currentDrag != kNullDrag)
- DragPreScroll(pWE->currentDrag, hOffset, vOffset);
-
- viewRect = (*pWE->viewRgn)->rgnBBox;
- updateRgn = NewRgn();
-
- // { offset the destination rectangle by the specified amount }
- WEOffsetLongRect(&pWE->destRect, hOffset, vOffset);
-
- // { scroll the view rectangle }
- ScrollRect(&viewRect, hOffset, vOffset, updateRgn);
-
- // { redraw the exposed region }
- WEUpdate(updateRgn, hWE);
- DisposeRgn(updateRgn);
-
- // { notify the Drag Manager }
- if (pWE->currentDrag != kNullDrag)
- DragPostScroll(pWE->currentDrag);
-
- // { redraw the selection outline, if hidden }
- if (hideOutline)
- {
- BSET(pWE->flags, weFOutlineHilite);
- _WEHiliteRange(pWE->selStart, pWE->selEnd, hWE);
- }
-
- // { restore the port }
- SetPort(savePort);
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-
- pascal Boolean _WEScrollIntoView (long offset, WEHandle hWE)
- {
- WEPtr pWE;
- LongPt thePoint;
- short lineHeight;
- long hScroll, vScroll, temp;
- Boolean retval;
-
- pWE = *hWE;
-
- // { do nothing if automatic scrolling is disabled }
- if (!BTST(pWE->flags, weFAutoScroll))
- {
- return false;
- }
-
- // { find the selection point }
- WEGetPoint(offset, &thePoint, &lineHeight, hWE);
-
- // { assume no scrolling is needed }
- retval = false;
- vScroll = 0;
- hScroll = 0;
-
- // { determine if we need to scroll vertically }
- if ((thePoint.v < pWE->viewRect.top) ||
- (thePoint.v + lineHeight >= pWE->viewRect.bottom))
- {
- // { calculate the amount of vertical scrolling needed to center the selection into view }
- vScroll = BSR(pWE->viewRect.top + pWE->viewRect.bottom, 1) - thePoint.v;
-
- // { we'd like to superimpose the bottom margins of the dest/view rects, if possible }
- temp = pWE->viewRect.bottom - pWE->destRect.bottom;
- if (temp > vScroll)
- {
- vScroll = temp;
- }
- // { but we also have to make sure the dest top isn't scrolled below the view top }
- temp = pWE->viewRect.top - pWE->destRect.top;
- if (temp < vScroll)
- {
- vScroll = temp;
- }
- }
-
- // { determine if we need to scroll horizontally }
- if ((thePoint.h - 1 < pWE->viewRect.left) || (thePoint.h >= pWE->viewRect.right))
- {
- // { calculate the amount of horizontal scrolling needed to center the selection into view }
- hScroll = BSR(pWE->viewRect.left + pWE->viewRect.right, 1) - thePoint.h;
-
- // { we'd like to superimpose the right margins of the dest/view rects, if possible }
- temp = pWE->viewRect.right - pWE->destRect.right;
- if (temp > hScroll)
- {
- hScroll = temp;
- }
-
- // { but we also have to make sure the dest left isn't scrolled to the right of the view left }
- temp = pWE->viewRect.left - pWE->destRect.left;
- if (temp < hScroll)
- {
- hScroll = temp;
- }
- }
-
- // { scroll the text if necessary }
- if ((vScroll != 0) || (hScroll != 0))
- {
- retval = true;
- WEScroll(hScroll, vScroll, hWE);
- }
-
- // { call the scroll callback, if any }
- if (pWE->scrollProc != nil)
- {
- ((WEScrollProcPtr)pWE->scrollProc)(hWE);
- }
- return retval;
- }
-
- pascal void WESelView(WEHandle hWE)
- {
- WEPtr pWE;
- long offset;
- Boolean saveWELock;
-
- // { lock the WE record }
- saveWELock = _WESetHandleLock((Handle)hWE, true);
- pWE = *hWE;
-
- // { scroll the free endpoint of the selection into view }
- if (BTST(pWE->flags, weFAnchorIsEnd))
- {
- offset = pWE->selStart;
- }
- else
- {
- offset = pWE->selEnd;
- }
- _WEScrollIntoView(offset, hWE);
-
- // { unlock the WE record }
- _WESetHandleLock((Handle)hWE, saveWELock);
- }
-