(FILECREATED "29-Nov-84 13:33:06" {IVY}<TEDIT>TEDITSCREEN.;10 125600 changes to: (FNS \TEDIT.FIXCHANGEDPART) previous date: "16-Nov-84 19:04:46" {IVY}<TEDIT>TEDITSCREEN.;8) (* Copyright (c) 1983, 1984 by John Sybalsky & Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT TEDITSCREENCOMS) (RPAQQ TEDITSCREENCOMS ((RECORDS THISLINE LINEDESCRIPTOR LINECACHE) (CONSTANTS (LMInvisibleRun 401) (LMLooksChange 400)) (FILES TEXTOFD TEDITLOOKS IMAGEOBJ) (FNS TEDIT.CR.UPDATESCREEN TEDIT.DELETELINE TEDIT.INSERT.DISPLAYTEXT TEDIT.INSERT.UPDATESCREEN TEDIT.UPDATE.SCREEN \BACKFORMAT \DISPLAYLINE \DOFORMATTING \FILLWINDOW \FIXDLINES \FIXILINES \FORMATLINE \PULLTEXT \PUSHTEXT \SHOWTEXT \TEDIT.ADJUST.LINES \TEDIT.BLTCHAR \TEDIT.CLOSEUPLINES \TEDIT.CREATE.LINECACHE \TEDIT.FIXCHANGEDPART \TEDIT.INSERTLINE \TEDIT.LINECACHE \TEDIT.MARK.LINES.DIRTY \TEDIT.PURGE.SPACES))) [DECLARE: EVAL@COMPILE (DATATYPE THISLINE ( (* Cache for line-related character location info, for selection code to use) (DESC FULLXPOINTER) (* Line descriptor for the line this describes now) LEN (* Length of the line in characters) CHARS (* Array of character codes (or objects) on the line (charcode of 400 => dummy entry for looks change--go get next entry in LOOKS)) WIDTHS (* Array of each character's width in points) LOOKS (* Array of any looks changes within the line. LOOKS (0) = starting character looks for the line) ) LEN ← 0 CHARS ←(ARRAY 256 (QUOTE POINTER) 0 0) WIDTHS ←(ARRAY 256 (QUOTE SMALLP) 0 0) LOOKS ←(ARRAY 256 (QUOTE POINTER) NIL 0)) (DATATYPE LINEDESCRIPTOR (YBOT (* Y value for the bottom of the line (below the descent)) YBASE (* Yvalue for the base line the characters sit on) LEFTMARGIN (* Left margin, in screen points) RIGHTMARGIN (* Right margin, in screen points) LXLIM (* X value of right edge of rightmost character on the line (may exceed right margin, if char is a space.)) SPACELEFT (* Space left on the line, ignoring trailing blanks & CRs.) LHEIGHT (* Total height of hte line, Ascent+Descent.) ASCENT (* Ascent of the line above YBASE) DESCENT (* How far line descends below YBASE) LTRUEASCENT (* The TRUE ascent for this line, unadjusted for line leading.) CHAR1 (* CH# of the first character on the line.) CHARLIM (* CH# of the last character on the line) CHARTOP (* CH# of the character which forced the line break (may exceed CHARLIM)) NEXTLINE (* Next line chain pointer) (PREVLINE FULLXPOINTER) (* Previous line chain pointer) LMARK (* One of SOLID, GREY, NIL. Tells what kind of special-line marker should be put in the left margin for this paragraph. (For hardcopy, can also be an indicator for special processing?)) LTEXTOBJ (* A cached TEXTOBJ that this line took its text from. Used in hardcopy to disambiguate when chno's should be updated...) CACHE (* A cached THISLINE, for keeping hardcopy info around while we crunch with the line descriptors to make things fit.) LDOBJ (* The object which lies behind this line of text, for updating, etc.) LFMTSPEC (* The format spec for this line's paragraph (eventually)) (DIRTY FLAG) (* T if this line has changed since it was last formatted.) (CR\END FLAG) (* T if this line ends with a CR.) (DELETED FLAG) (* T if this line has been completely deleted since it was last formatted or displayed. (Used by deletion routines to detect garbage lines)) (LHASPROT FLAG) (* This line contains protected text.) (LHASTABS FLAG) (* If this line has a tab in it, this is the line-relative ch# of the final tab. This is to let us punt properly with tabs in a line.) (1STLN FLAG) (* This line is the first line in a paragraph) (LSTLN FLAG) (* This is the last line in a paragraph) ) CHARLIM ← 1000000 NEXTLINE ← NIL PREVLINE ← NIL DIRTY ← NIL YBOT ← 0 YBASE ← 0 LEFTMARGIN ← 0 DELETED ← NIL) (DATATYPE LINECACHE (LCBITMAP (* The bitmap that will be used by this instance of the cache) (LCNEXTCACHE FULLXPOINTER) (* The next cache in the chain, for screen updates.) )) ] (/DECLAREDATATYPE (QUOTE THISLINE) (QUOTE (FULLXPOINTER POINTER POINTER POINTER POINTER))) (/DECLAREDATATYPE (QUOTE LINEDESCRIPTOR) (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER FULLXPOINTER POINTER POINTER POINTER POINTER POINTER FLAG FLAG FLAG FLAG FLAG FLAG FLAG)) ) (/DECLAREDATATYPE (QUOTE LINECACHE) (QUOTE (POINTER FULLXPOINTER))) (DECLARE: EVAL@COMPILE (RPAQQ LMInvisibleRun 401) (RPAQQ LMLooksChange 400) (CONSTANTS (LMInvisibleRun 401) (LMLooksChange 400)) ) (FILESLOAD TEXTOFD TEDITLOOKS IMAGEOBJ) (DEFINEQ (TEDIT.CR.UPDATESCREEN [LAMBDA (CH# XPOINT TEXTOBJ SEL LINE BLANKSEEN CRSEEN DS CHWIDTH DONTSCROLL) (* jds "15-Aug-84 17:41") (* Update the edit window image after a CR is typed. Move any text after the CR to a new line, and push or pull text as needed.) (PROG ((LINES\DELETED NIL) (LINES (fetch LINES of TEXTOBJ)) (DS (fetch DS of TEXTOBJ)) (WINDOW (fetch \WINDOW of TEXTOBJ)) (NEXTLINE (fetch NEXTLINE of LINE)) (PREVLINE (fetch PREVLINE of LINE)) (WWIDTH (fetch WRIGHT of TEXTOBJ)) NLINE1 LEN NL OLINE DX DY OCHLIM OXLIM OCR\END OLHEIGHT OLASCENT OLDESCENT NYBOT OFLOWFN) (COND ([AND (NOT (fetch CR\END of PREVLINE)) (ILEQ (IDIFFERENCE XPOINT (fetch LEFTMARGIN of LINE)) (IDIFFERENCE (fetch RIGHTMARGIN of PREVLINE) (fetch LXLIM of PREVLINE] (* This CR should push the start of the line back upward.) (replace DIRTY of PREVLINE with T))) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T) (COND (DONTSCROLL (* SO DO NOTHING)) ([OR (NOT (fetch NEXTLINE of LINE)) (ILEQ (fetch YBOT of (fetch NEXTLINE of LINE)) (fetch BOTTOM of (DSPCLIPPINGREGION NIL WINDOW] (* This pushed the caret off-screen. Move it up.) (replace EDITOPACTIVE of TEXTOBJ with NIL) (SCROLLW WINDOW 0 (LLSH (fetch LHEIGHT of (COND ((fetch NEXTLINE of LINE)) (LINE))) 1]) (TEDIT.DELETELINE [LAMBDA (LINE TEXTOBJ) (* jds "18-MAR-83 15:53") (* Remove a complete text line descriptor from the edit window, then move lower lines up over it.) (PROG ((PREV (fetch PREVLINE of LINE)) (NEXT (fetch NEXTLINE of LINE))) (* Fix up the line-descriptor chain to dis-include line) (COND (PREV (replace NEXTLINE of PREV with NEXT))) (COND (NEXT (replace PREVLINE of NEXT with PREV))) (\TEDIT.CLOSEUPLINES TEXTOBJ PREV NEXT) (* And fix up the screen to cover the blank space.) ]) (TEDIT.INSERT.DISPLAYTEXT [LAMBDA (TEXTOBJ CH CHWIDTH LINE XPOINT DS SEL) (* jds "31-Jul-84 12:57") (* This function does the actual displaying of typed-in text on the edit window.) (PROG ((LOOKS (\TEDIT.APPLY.STYLES (fetch CARETLOOKS of TEXTOBJ) (fetch \INSERTPC of TEXTOBJ) TEXTOBJ)) (TERMSA (fetch TXTTERMSA of TEXTOBJ)) DY FONT) (DSPFONT (SETQ FONT (fetch CLFONT of LOOKS)) DS) [COND ((IGREATERP (FONTPROP (fetch CLFONT of LOOKS) (QUOTE ASCENT)) (fetch LTRUEASCENT of LINE)) [\TEDIT.ADJUST.LINES TEXTOBJ LINE DS (fetch YBOT of (fetch PREVLINE of LINE)) (IDIFFERENCE (fetch LTRUEASCENT of LINE) (FONTPROP (fetch CLFONT of LOOKS) (QUOTE ASCENT] (replace LTRUEASCENT of LINE with (FONTPROP (fetch CLFONT of LOOKS) (QUOTE ASCENT] [COND ((IGREATERP (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT)) (fetch DESCENT of LINE)) (* If the caret's font will change the line's descent, adjust lower lines downward) [\TEDIT.ADJUST.LINES TEXTOBJ (fetch NEXTLINE of LINE) DS (fetch YBOT of LINE) (IDIFFERENCE (fetch DESCENT of LINE) (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT] (replace DESCENT of LINE with (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT))) (replace YBOT of LINE with (IDIFFERENCE (fetch YBASE of LINE) (fetch DESCENT of LINE] (BITBLT DS XPOINT (fetch YBOT of LINE) DS (IPLUS XPOINT CHWIDTH) (fetch YBOT of LINE) (IDIFFERENCE (fetch RIGHTMARGIN of LINE) XPOINT) (fetch LHEIGHT of LINE) (QUOTE INPUT) (QUOTE REPLACE)) (* Move the old text over) (BITBLT NIL 0 0 DS XPOINT (fetch YBOT of LINE) CHWIDTH (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Blank out the area we're going to write into) (MOVETO XPOINT (IPLUS (fetch YBASE of LINE) (OR (fetch CLOFFSET of LOOKS) 0)) DS) (* Set the display stream position) [COND [TERMSA (* Special terminal table for controlling character display. Use it.) (RESETLST (RESETSAVE \PRIMTERMSA TERMSA) (replace (TEXTSTREAM REALFILE) of (fetch STREAMHINT of TEXTOBJ) with DS) (COND [(STRINGP CH) (for CHAR instring CH do (SELCHARQ CHAR (TAB (* Put down white) (BITBLT NIL 0 0 DS XPOINT (fetch YBOT of LINE) 36 (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (RELMOVETO 36 0 DS)) (CR (BITBLT NIL 0 0 DS XPOINT (fetch YBOT of LINE) (IMAX 6 (CHARWIDTH CHAR FONT)) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE)) (\DSPPRINTCHAR (fetch STREAMHINT of TEXTOBJ) CHAR] (T (SELCHARQ CH (TAB (* Put down white) (BITBLT NIL 0 0 DS XPOINT (fetch YBOT of LINE) 36 (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (RELMOVETO 36 0 DS)) (CR (BITBLT NIL 0 0 DS XPOINT (fetch YBOT of LINE) (IMAX 6 (CHARWIDTH CH FONT)) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE)) (\DSPPRINTCHAR (fetch STREAMHINT of TEXTOBJ) CH] (T (* No special handling; just use native character codes) (COND [(STRINGP CH) (for CHAR instring CH do (SELCHARQ CHAR (TAB (* Put down white) (BITBLT NIL 0 0 DS (DSPXPOSITION NIL DS) (fetch YBOT of LINE) 36 (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (RELMOVETO 36 0 DS)) (CR (BITBLT NIL 0 0 DS (DSPXPOSITION NIL DS) (fetch YBOT of LINE) (IMAX 6 (CHARWIDTH CHAR FONT)) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE)) (BLTCHAR CHAR DS] (T (SELCHARQ CH (TAB (* Put down white) (BITBLT NIL 0 0 DS (DSPXPOSITION NIL DS) (fetch YBOT of LINE) 36 (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (RELMOVETO 36 0 DS)) (CR (* Blank out the CR's width.) (BITBLT NIL 0 0 DS (DSPXPOSITION NIL DS) (fetch YBOT of LINE) (IMAX 6 (CHARWIDTH CH FONT)) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE)) (BLTCHAR CH DS] (BITBLT NIL 0 0 DS (fetch LXLIM of LINE) (fetch YBOT of LINE) (fetch WRIGHT of TEXTOBJ) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Clear after EOL) (TEDIT.MODIFYLOOKS LINE XPOINT DS LOOKS (fetch YBASE of LINE)) (* Do underlining, strike-out, etc.) ]) (TEDIT.INSERT.UPDATESCREEN [LAMBDA (CH CH# CHARS XPOINT TEXTOBJ SEL LINE OTEXTLEN BLANKSEEN CRSEEN DS DONTSCROLL) (* jds " 1-Nov-84 11:10") (* Update the edit window after an insertion) (PROG ((THISLINE (fetch THISLINE of TEXTOBJ)) (WINDOW (fetch \WINDOW of TEXTOBJ)) (OLHEIGHT (fetch LHEIGHT of LINE)) (OLASCENT (fetch ASCENT of LINE)) (OLDESCENT (fetch DESCENT of LINE)) EOLFLAG CHORIG CHWIDTH OXLIM OCHLIM OCR\END PREVSPACE FIXEDLINE NEXTLINE LINES NEWLINEFLG DX PREVLINE SAVEWIDTH OFLOWFN OLHEIGHT DY TABSEEN IMAGECACHE) (replace CH# of SEL with (IPLUS CHARS CH#)) (* These must be here, since SELs are valid even without a window.) (replace CHLIM of SEL with (fetch CH# of SEL)) (replace POINT of SEL with (QUOTE LEFT)) (replace DCH of SEL with 0) (replace SELKIND of SEL with (QUOTE CHAR)) (COND ((NOT WINDOW) (* If this textobj has no window to update, don't bother) (RETURN)) (T (* FOR NOW, ALWAYS UPDATE THE SCREEN THE HARD WAY) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T)) ((LISTP WINDOW) (* If there are multiple panes, do it the hard way for now.) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T)) ((TEXTPROP TEXTOBJ (QUOTE SLOWUPDATE)) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T)) (LINE (* We're typing into a pre-existing line) [COND [(STRINGP CH) (* Width of the inserted text, if it's > 1 character long) (SETQ CHWIDTH (TEDIT.STRINGWIDTH CH (fetch CLFONT of (\TEDIT.APPLY.STYLES (fetch CARETLOOKS of TEXTOBJ) (fetch \INSERTPC of TEXTOBJ) TEXTOBJ)) (fetch TXTTERMSA of TEXTOBJ))) (for CHAR instring CH do (COND ((EQP CHAR (CHARCODE TAB)) (SETQ TABSEEN T) (RETURN] (T (* Width for a single character) (SETQ CHWIDTH (SELCHARQ CH (TAB (* Make all tabs 1/2 inch for the time being.) (SETQ TABSEEN T) 36) (TEDIT.CHARWIDTH CH (fetch CLFONT of (\TEDIT.APPLY.STYLES (fetch CARETLOOKS of TEXTOBJ) (fetch \INSERTPC of TEXTOBJ) TEXTOBJ)) (fetch TXTTERMSA of TEXTOBJ] [SETQ EOLFLAG (OR (IGREATERP CH# OTEXTLEN) (IGREATERP CH# (fetch CHARLIM of LINE] (* We're inserting at the end of a line.) (replace (SELECTION DX) of SEL with 0) (replace X0 of SEL with (IPLUS CHWIDTH XPOINT)) (replace XLIM of SEL with (IPLUS CHWIDTH XPOINT)) (replace L1 of SEL with LINE) (replace LN of SEL with LINE) (replace Y0 of SEL with (fetch YBOT of LINE)) (replace YLIM of SEL with (fetch YBOT of LINE)) (SETQ OXLIM (fetch LXLIM of LINE)) (* Where the line used to end.) (SETQ OCHLIM (fetch CHARLIM of LINE)) (SETQ OLHEIGHT (fetch LHEIGHT of LINE)) (SETQ OCR\END (AND (fetch CR\END of LINE) (NOT EOLFLAG))) (* Remember whether or not this line used to end with a CR) [SETQ BLANKSEEN (AND BLANKSEEN (SETQ PREVLINE (fetch PREVLINE of LINE)) (NOT (fetch CR\END of PREVLINE)) (ILEQ CH# (fetch CHARTOP of PREVLINE] (COND ((OR TABSEEN (fetch LHASTABS of LINE) (NEQ (fetch QUAD of (fetch LFMTSPEC of LINE)) (QUOTE LEFT)) (LISTP WINDOW)) (* It's anything other than left-ragged formatting. Must do redisplay the hard way.) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ)) ((AND CRSEEN (NOT BLANKSEEN) (OR (NOT (STRINGP CH)) (IEQP 1 CHARS))) (* Only a CR in this stash.) (TEDIT.CR.UPDATESCREEN CH# XPOINT TEXTOBJ SEL LINE BLANKSEEN CRSEEN DS CHWIDTH DONTSCROLL)) [[OR BLANKSEEN CRSEEN (AND EOLFLAG (OR (ILEQ CH# OTEXTLEN) (fetch CR\END of LINE))) (IGREATERP CHWIDTH (IMIN (IDIFFERENCE (fetch RIGHTMARGIN of LINE) XPOINT) (fetch SPACELEFT of LINE] (* MOVE SOME TEXT TO THE NEXT LINE, CREATING IT IF NEED BE.) (COND (BLANKSEEN (* BlankSeen => back up to previous line, and try a pull of text.) (TEDIT.UPDATE.SCREEN TEXTOBJ) (SETQ BLANKSEEN T) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T)) (T (\FORMATLINE TEXTOBJ NIL (fetch CHAR1 of LINE) LINE) (COND ([OR (NOT (IEQP (IPLUS CHWIDTH OXLIM) (fetch LXLIM of LINE))) (NOT (IEQP (IPLUS CHARS OCHLIM) (fetch CHARLIM of LINE] (* The length of the line changed; we have to move some text.) (* THIS USED TO REQUIRE THAT CHARLIM OF LINE BE < TEXTLEN. 9/27/83. WHY?) (COND ((OR (IGREATERP XPOINT (fetch LXLIM of LINE)) (IGREATERP (IPLUS XPOINT CHWIDTH) (fetch LXLIM of LINE))) (* The insertion point moved to the next line.) (replace DIRTY of LINE with T) (replace CHARLIM of LINE with OCHLIM) (\TEDIT.ADJUST.LINES TEXTOBJ (fetch NEXTLINE of LINE) WINDOW (fetch YBOT of LINE) (IDIFFERENCE OLHEIGHT (fetch LHEIGHT of LINE))) (TEDIT.UPDATE.SCREEN TEXTOBJ) (SETQ BLANKSEEN T) (\FIXSEL SEL TEXTOBJ)) (T (SETQ DX (IDIFFERENCE (IPLUS OXLIM CHWIDTH) (fetch LXLIM of LINE))) (replace DIRTY of LINE with NIL) (COND ((fetch NEXTLINE of LINE) [SETQ SAVEWIDTH (IMIN DX (IMAX 0 (IDIFFERENCE (fetch RIGHTMARGIN of LINE) (IDIFFERENCE OXLIM DX] (* Remember how much was REALLY saved in the SAVEBM) (SETQ IMAGECACHE (\TEDIT.LINECACHE (fetch LINECACHE of TEXTOBJ) SAVEWIDTH OLHEIGHT)) (\TEDIT.CHECK (fetch TCUP of (fetch CARET of TEXTOBJ))) (* The caret must be up when the line cache is updated.) (BITBLT WINDOW (IDIFFERENCE OXLIM DX) (fetch YBOT of LINE) IMAGECACHE 0 0 DX OLHEIGHT (QUOTE INPUT) (QUOTE REPLACE)) (\TEDIT.ADJUST.LINES TEXTOBJ LINE DS (IPLUS (fetch YBOT of LINE) (IMIN OLHEIGHT (fetch LHEIGHT of LINE))) (IDIFFERENCE OLASCENT (fetch ASCENT of LINE))) (\TEDIT.ADJUST.LINES TEXTOBJ NEXTLINE WINDOW (fetch YBOT of LINE) (IDIFFERENCE OLDESCENT (fetch DESCENT of LINE))) (TEDIT.INSERT.DISPLAYTEXT TEXTOBJ CH CHWIDTH LINE XPOINT DS SEL) (\PUSHTEXT (fetch NEXTLINE of LINE) (IDIFFERENCE OXLIM DX) (fetch YBOT of LINE) DX (ADD1 (fetch CHARLIM of LINE)) TEXTOBJ OCR\END (fetch LINECACHE of TEXTOBJ) SAVEWIDTH OLDESCENT)) (T (\TEDIT.ADJUST.LINES TEXTOBJ LINE DS (IPLUS (fetch YBOT of LINE) (IMIN OLHEIGHT (fetch LHEIGHT of LINE))) (IDIFFERENCE OLASCENT (fetch ASCENT of LINE))) (\TEDIT.ADJUST.LINES TEXTOBJ NEXTLINE WINDOW (fetch YBOT of LINE) (IDIFFERENCE OLDESCENT (fetch DESCENT of LINE))) (TEDIT.INSERT.DISPLAYTEXT TEXTOBJ CH CHWIDTH LINE XPOINT DS SEL) [replace NEXTLINE of LINE with (\FORMATLINE TEXTOBJ NIL (ADD1 (fetch CHARLIM of LINE] (SETQ NEWLINEFLG T) (replace PREVLINE of (fetch NEXTLINE of LINE) with LINE) (COND ((IGEQ (fetch YBOT of LINE) (IPLUS (fetch LHEIGHT of (fetch NEXTLINE of LINE)) (fetch WBOTTOM of TEXTOBJ))) [replace YBOT of (fetch NEXTLINE of LINE) with (IDIFFERENCE (fetch YBOT of LINE) (fetch LHEIGHT of (fetch NEXTLINE of LINE] [replace YBASE of (fetch NEXTLINE of LINE) with (IPLUS (fetch YBOT of (fetch NEXTLINE of LINE)) (fetch DESCENT of (fetch NEXTLINE of LINE] (\DISPLAYLINE TEXTOBJ (fetch NEXTLINE of LINE))) (T (* A Line fell off the bottom. Remember for potential later handling) (AND (SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN)) ) (APPLY* OFLOWFN WINDOW TEXTOBJ] (T (* This character didn't cause any line overflow. Adjust the line length and display the character) (replace SPACELEFT of LINE with (IDIFFERENCE (fetch SPACELEFT of LINE) CHWIDTH)) (* This is conservative--since SPACELEFT isn't really reduced by spaces at the end of the line, this may cause line reformatting before it's really needed.) (replace LXLIM of LINE with (IPLUS (fetch LXLIM of LINE) CHWIDTH)) (replace DESC of THISLINE with NIL) (TEDIT.INSERT.DISPLAYTEXT TEXTOBJ CH CHWIDTH LINE XPOINT DS SEL))) (\SHOWSEL SEL NIL T)) (T (* There isn't really a line to type into yet. Let's create it.) (SETQ LINE LINES) (replace NEXTLINE of LINE with (SETQ NEXTLINE (\FORMATLINE TEXTOBJ NIL 1))) (* Create the new line) (replace PREVLINE of NEXTLINE with LINE) (replace YBOT of NEXTLINE with (IDIFFERENCE (fetch YBOT of LINE) (fetch LHEIGHT of NEXTLINE))) (* Find where it goes on the screen) (replace YBASE of NEXTLINE with (IPLUS (fetch YBOT of NEXTLINE) (fetch DESCENT of NEXTLINE))) (\DISPLAYLINE TEXTOBJ NEXTLINE) (* Display it and cache the image) (replace L1 of SEL with (replace LN of SEL with NEXTLINE)) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T))) (\COPYSEL SEL TEDIT.SELECTION) (COND (DONTSCROLL (* If scrolling is suppressed, don't bother with the next check:) (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WINDOW)) ((ILEQ (SELECTQ (fetch POINT of SEL) (LEFT (fetch Y0 of SEL)) (RIGHT (fetch YLIM of SEL)) 0) (fetch BOTTOM of (DSPCLIPPINGREGION NIL WINDOW))) (* The caret just went off-screen. Move it up some.) (replace EDITOPACTIVE of TEXTOBJ with NIL) (SCROLLW (fetch SELWINDOW of TEXTOBJ) 0 (LLSH (fetch LHEIGHT of (SELECTQ (fetch POINT of SEL) (LEFT (fetch L1 of SEL)) (RIGHT (fetch LN of SEL)) (SHOULDNT))) 1))) (T (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WINDOW]) (TEDIT.UPDATE.SCREEN [LAMBDA (TEXTOBJ STARTINGLINE) (* jds "15-Mar-84 13:59") (* Update the screen, as needed to fix up "dirty" lines.) (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ)) (for WW inside (fetch \WINDOW of TEXTOBJ) do (PROG ((NLINE (\TEDIT.FIXCHANGEDPART TEXTOBJ STARTINGLINE WW)) ) (AND NLINE (\FILLWINDOW (fetch YBOT of NLINE) NLINE TEXTOBJ NIL WW]) (\BACKFORMAT [LAMBDA (LINES TEXTOBJ) (* jds "22-OCT-83 17:27") (* Move back to the next preceding CR (to guarantee a line break), then format lines to reach where we are now.) (PROG ((LINE1 (fetch NEXTLINE of LINES)) (WHEIGHT (fetch WTOP of TEXTOBJ)) CH1 CHNO CH NLINE) [SETQ CH1 (COND (LINE1 (fetch CHAR1 of LINE1)) (T (fetch TEXTLEN of TEXTOBJ] (COND ((ILEQ CH1 1) (* No more lines can be formatted -- we're at the front of the file.) (RETURN LINES)) (T (* There is more to do.) (\SETUPGETCH (IDIFFERENCE CH1 1) TEXTOBJ) [for old CHNO from (IDIFFERENCE CH1 2) to 1 by -1 do (SETQ CH (\GETCHB TEXTOBJ)) (COND ((EQ CH (CHARCODE CR)) (RETURN] (SETQ CHNO (IMAX (ADD1 CHNO) 1)) [while (ILEQ CHNO (SUB1 CH1)) do (SETQ NLINE (\FORMATLINE TEXTOBJ NIL CHNO)) (replace YBOT of NLINE with WHEIGHT) (replace YBASE of NLINE with WHEIGHT) (replace PREVLINE of NLINE with LINES) (replace NEXTLINE of LINES with NLINE) (SETQ LINES NLINE) (SETQ CHNO (ADD1 (fetch CHARLIM of NLINE] (replace NEXTLINE of NLINE with LINE1) (AND LINE1 (replace PREVLINE of LINE1 with NLINE)) (RETURN NLINE]) (\DISPLAYLINE [LAMBDA (TEXTOBJ LINE WINDOW) (* jds "19-Sep-84 17:27") (* Display the line of text LINE in the edit window where it belongs.) (PROG ((CH 0) (CHLIST (fetch CHARS of (fetch THISLINE of TEXTOBJ))) (WLIST (fetch WIDTHS of (fetch THISLINE of TEXTOBJ))) (LOOKS (fetch LOOKS of (fetch THISLINE of TEXTOBJ))) (WINDOWDS (OR (AND WINDOW (WINDOWPROP WINDOW (QUOTE DSP))) (fetch DS of TEXTOBJ))) (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (THISLINE (fetch THISLINE of TEXTOBJ)) (TERMSA (fetch TXTTERMSA of TEXTOBJ)) (STREAM (fetch STREAMHINT of TEXTOBJ)) (OLDCACHE (fetch LCBITMAP of (fetch DISPLAYCACHE of TEXTOBJ))) CACHE (DS (fetch DISPLAYCACHEDS of TEXTOBJ)) LOOKSTARTX \PCHARSLEFT \PSTRING \PFILE FONT OFONT OLOOKS XOFFSET CLIPLEFT CLIPRIGHT DISPLAYDATA DDPILOTBBT DDWIDTHCACHE DDOFFSETCACHE CURY) (SETQ CACHE (\TEDIT.LINECACHE (fetch DISPLAYCACHE of TEXTOBJ) (fetch RIGHTMARGIN of LINE) (fetch LHEIGHT of LINE))) (COND ((NEQ CACHE OLDCACHE) (* We changed the bitmaps because this line was bigger--update the displaystream, too) (DSPDESTINATION CACHE DS))) (COND ((AND (NOT (ZEROP (fetch CHAR1 of LINE))) (ILEQ (fetch CHAR1 of LINE) TEXTLEN) (IGEQ (fetch YBOT of LINE) (fetch WBOTTOM of TEXTOBJ))) (* Only display the line of it contains text (CHAR1 > 0), appears before the end of the test, and is on-screen.) (COND ((NEQ (fetch DESC of THISLINE) LINE) (* No image cache -- re-format and display) (\FORMATLINE TEXTOBJ NIL (fetch CHAR1 of LINE) LINE))) (MOVETO (fetch LEFTMARGIN of LINE) (fetch DESCENT of LINE) DS) (MOVETO (fetch LEFTMARGIN of LINE) (IPLUS (fetch YBASE of LINE) (fetch WBOTTOM of TEXTOBJ)) WINDOWDS) (* Move to the left margin, on the base line for this line. ..) (SETQ DISPLAYDATA (fetch IMAGEDATA of DS)) (SETQ DDPILOTBBT (ffetch DDPILOTBBT of DISPLAYDATA)) (SETQ XOFFSET (fetch DDXOFFSET of DISPLAYDATA)) (* The X position of the left edge of the window, since \TEDIT.BLTCHAR works on the screen bitmap itself.) (SETQ CLIPLEFT (fetch DDClippingLeft of DISPLAYDATA)) (* The left and right edges of the clipping region for the text display window.) (SETQ CLIPRIGHT (fetch DDClippingRight of DISPLAYDATA)) (BITBLT NIL 0 0 CACHE 0 0 NIL NIL (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Clear the line cache) (SETQ OFONT (DSPFONT (fetch CLFONT of (SETQ OLOOKS (\EDITELT LOOKS 0))) DS)) (* The starting font) (SETQ DDWIDTHCACHE (ffetch DDWIDTHSCACHE of DISPLAYDATA)) (* Cache the character-image widths) (SETQ DDOFFSETCACHE (ffetch DDOFFSETSCACHE of DISPLAYDATA)) (* And the offset-into-strike-bitmap array) (SETQ LOOKSTARTX (fetch LEFTMARGIN of LINE)) (* Starting X position for the current-looks text.) (AND (fetch CLOFFSET of OLOOKS) (RELMOVETO 0 (fetch CLOFFSET of OLOOKS) DS)) (* Any sub- or superscripting at start of line) (bind (LOOKNO ← 1) DX (TX ←(IPLUS XOFFSET (fetch LEFTMARGIN of LINE))) for I from 0 to (fetch LEN of THISLINE) do (* * Display the line character by character) (SETQ CH (\EDITELT CHLIST I)) (* Grab the character (or IMAGEOBJ) to display) (SETQ DX (\WORDELT WLIST I)) (* And its width) [SELECTC CH (LMInvisibleRun (* An INVISIBLE run -- skip it, and skip over the char count) (add LOOKNO 1)) (LMLooksChange (* A LOOKS change) (replace DDXPOSITION of DISPLAYDATA with (IDIFFERENCE TX XOFFSET)) (* Make the displaystream reflect our current X position) (TEDIT.MODIFYLOOKS LINE LOOKSTARTX DS OLOOKS (fetch DESCENT of LINE)) (* Make any necessary changes to the preceding characters (underline, strike-out &c)) (DSPFONT (fetch CLFONT of (SETQ OLOOKS (\EDITELT LOOKS LOOKNO))) DS) (* Set the new font) (SETQ DDWIDTHCACHE (ffetch DDWIDTHSCACHE of DISPLAYDATA)) (* Cache the new widths and offsets from the new font) (SETQ DDOFFSETCACHE (ffetch DDOFFSETSCACHE of DISPLAYDATA) ) (add LOOKNO 1) (* Grab the next set of char looks) (AND (fetch CLOFFSET of OLOOKS) (RELMOVETO 0 (fetch CLOFFSET of OLOOKS) DS)) (* Account for super/subscripting) (SETQ LOOKSTARTX (IDIFFERENCE TX XOFFSET)) (* Remember the starting Xpos for possible later underlining &c) ) (9 (* TAB: use the width from the cache to decide the right formatting.)) (13 (* It's a CR) NIL) (COND [(SMALLP CH) (* Normal character -- just display it.) (COND (TERMSA (* Using special instrns from TERMSA) (\DSPPRINTCHAR STREAM CH)) (T (* Native charcodes) (\TEDIT.BLTCHAR CH DS DX TX DISPLAYDATA DDPILOTBBT DDWIDTHCACHE DDOFFSETCACHE CLIPRIGHT] (T (* CH is an object.) (MOVETO (IDIFFERENCE TX XOFFSET) (SETQ CURY (DSPYPOSITION NIL DS)) DS) (* Go to the base line, left edge of the image region.) (APPLY* (IMAGEOBJPROP CH (QUOTE DISPLAYFN)) CH DS (QUOTE DISPLAY) (fetch STREAMHINT of TEXTOBJ)) (* Tell him to display himself here.) (DSPFONT (fetch CLFONT of OLOOKS) DS) (MOVETO (IDIFFERENCE TX XOFFSET) CURY DS) (* Move to after the object's image) ] (add TX DX) (* Update our X position) finally (replace DDXPOSITION of DISPLAYDATA with (IDIFFERENCE TX XOFFSET)) (* Make any necessary looks mods to the last run of characters) (TEDIT.MODIFYLOOKS LINE LOOKSTARTX DS OLOOKS (fetch DESCENT of LINE))) (BITBLT CACHE 0 0 WINDOWDS 0 (fetch YBOT of LINE) (fetch WRIGHT of TEXTOBJ) (fetch LHEIGHT of LINE) (QUOTE INPUT) (QUOTE REPLACE)) (* Paint the cached image on the screen (this lessens flicker during update)) (SELECTQ (fetch LMARK of LINE) (GREY (* This line has some property that isn't visible to the user. Tell him to be careful) (BITBLT NIL 0 0 WINDOWDS 0 (fetch YBASE of LINE) 4 4 (QUOTE TEXTURE) (QUOTE PAINT) 42405)) (SOLID (* This line has some property that isn't visible to the user. Tell him to be careful) (BITBLT NIL 0 0 WINDOWDS 0 (fetch YBASE of LINE) 4 4 (QUOTE TEXTURE) (QUOTE PAINT) BLACKSHADE)) (BITBLT NIL 0 0 WINDOWDS 0 (fetch YBASE of LINE) 4 4 (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE]) (\DOFORMATTING [LAMBDA (TEXTOBJ LINE FMTSPEC THISLINE #BLANKS PREVSP 1STLN) (* jds "27-Jul-84 10:59") (* Do the formatting work for justified, centered, etc. lines) (PROG ((QUAD (fetch QUAD of FMTSPEC)) (SPACELEFT (LLSH (fetch SPACELEFT of LINE) 5)) (CHLIST (fetch CHARS of THISLINE)) (WLIST (fetch WIDTHS of THISLINE)) (SPACEOFLOW 0) EXTRASP OPREVSP LINELEAD) (* NB that SPACELEFT, OFLOW, etc. are kept in 32 x value form, for rounding ease.) (replace LTRUEASCENT of LINE with (fetch ASCENT of LINE)) (* Save the true ascent value for display purposes) [COND ((SETQ LINELEAD (fetch LINELEAD of FMTSPEC)) (* If line leading was specified, set it) (COND ((ILESSP LINELEAD 0) (replace LHEIGHT of LINE with LINELEAD)) (T (add (fetch LHEIGHT of LINE) (fetch LINELEAD of FMTSPEC)) (* And adjust the line's ascent accordingly) (add (fetch ASCENT of LINE) (fetch LINELEAD of FMTSPEC] [COND ((AND 1STLN (fetch LEADBEFORE of FMTSPEC)) (* If line leading was specified, set it) (add (fetch LHEIGHT of LINE) (fetch LEADBEFORE of FMTSPEC)) (add (fetch ASCENT of LINE) (fetch LEADBEFORE of FMTSPEC] (SELECTQ QUAD (LEFT (* Do nothing for left-justified lines except replace the character codes)) [RIGHT (* Just move the right margin over) (replace LEFTMARGIN of LINE with (IPLUS (fetch LEFTMARGIN of LINE) (fetch SPACELEFT of LINE))) (replace LXLIM of LINE with (fetch RIGHTMARGIN of LINE)) (COND ((OR (ZEROP (fetch LEN of THISLINE)) (ZEROP #BLANKS) (ZEROP PREVSP)) (* For empty lines, and lines with no spaces, don't bother fixing blank widths.) (RETURN] [CENTERED (* Split the difference for centering) (add (fetch LEFTMARGIN of LINE) (LRSH SPACELEFT 6)) (add (fetch LXLIM of LINE) (LRSH SPACELEFT 6)) (COND ((OR (ZEROP (fetch LEN of THISLINE)) (ZEROP #BLANKS) (ZEROP PREVSP)) (* For empty lines, and lines with no spaces, don't bother fixing blank widths.) (RETURN] (JUSTIFIED (* For justified lines, stretch each space so line reaches the right margin) (COND ((OR (ZEROP (fetch LEN of THISLINE)) (ZEROP #BLANKS) (ZEROP PREVSP)) (* For empty lines, and lines with no spaces, don't bother fixing blank widths.) (RETURN))) (COND ((OR (fetch CR\END of LINE) (IGEQ (fetch CHARLIM of LINE) (fetch TEXTLEN of TEXTOBJ))) (* This is the last line in the paragraph; don't stretch it out.) (SETQ EXTRASP 0)) (T (bind (OPREVSP ← PREVSP) while (AND (IGREATERP PREVSP 0) (ILEQ OPREVSP (IPLUS PREVSP 2))) do (* Back up over all trailing white space on the line.) (SETQ OPREVSP (SUB1 PREVSP)) (SETQ PREVSP (\EDITELT CHLIST OPREVSP)) (\EDITSETA CHLIST OPREVSP (CONSTANT (CHARCODE SPACE))) (add #BLANKS -1) %%%%) (AND (ZEROP #BLANKS) (RETURN)) (* If there aren't any blanks except at end-of-line, don't bother going further.) (replace LXLIM of LINE with (fetch RIGHTMARGIN of LINE)) (* Fix the right margin for showing selections &c) (SETQ EXTRASP (IQUOTIENT SPACELEFT #BLANKS)) (* Now apportion the extra space evenly among blanks.) )) [while (IGREATERP PREVSP 0) do (* Fix up the widths of spaces in the line) (SETQ OPREVSP (SUB1 PREVSP)) (SETQ PREVSP (\EDITELT CHLIST OPREVSP)) (\EDITSETA CHLIST OPREVSP (CONSTANT (CHARCODE SPACE))) [OR (fetch CR\END of LINE) (\WORDSETA WLIST OPREVSP (IPLUS (LRSH (IPLUS EXTRASP SPACEOFLOW) 5) (\WORDELT WLIST OPREVSP] (SETQ SPACEOFLOW (LOGAND 31 (IPLUS EXTRASP SPACEOFLOW] (RETURN)) NIL) (\TEDIT.PURGE.SPACES CHLIST PREVSP]) (\FILLWINDOW [LAMBDA (YBOT CURLINE TEXTOBJ DONTFILLFLG WINDOW) (* jds " 1-Nov-84 11:28") (* Fill out TEXTOBJ's window, starting with the line after CURLINE, whose ybottom is YBOT) (* Return T if any lines are moved up.) (* DONTFILLFLG => Don't bother printing any new lines at the bottom of the screen.) (PROG ((LINE (fetch NEXTLINE of CURLINE)) (CHARLIM (fetch CHARLIM of CURLINE)) (PREVLINE CURLINE) WHEIGHT (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (LINES\DELETED NIL) (WINDOW (OR WINDOW (fetch \WINDOW of TEXTOBJ))) NEXTLINE OFLOWFN) (SETQ WHEIGHT (fetch WTOP of TEXTOBJ)) (while (AND LINE (IGEQ (fetch YBOT of LINE) WHEIGHT)) do (* Do not start with a line which is above the top of the screen.) (SETQ PREVLINE LINE) (SETQ CHARLIM (fetch CHARLIM of LINE)) (SETQ LINE (fetch NEXTLINE of LINE))) [repeatwhile (ILESSP CHARLIM TEXTLEN) do (* Walk thru the lines below the starting line.) [COND ((AND LINE (IGEQ (SETQ YBOT (IDIFFERENCE YBOT (fetch LHEIGHT of LINE))) (fetch WBOTTOM of TEXTOBJ))) (* If there is a line to display, and space to display it, go ahead.) (replace YBOT of LINE with YBOT) (replace YBASE of LINE with (IPLUS YBOT (fetch DESCENT of LINE))) (\DISPLAYLINE TEXTOBJ LINE WINDOW)) (LINE (* There is a line, but it won't fit.) (SETQ YBOT (IPLUS YBOT (fetch LHEIGHT of LINE))) (* This existing line won't fit. Punt out of this, setting YBOT so the screen gets cleared right.) [COND ((SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN))) (* Try calling any user-supplied overflow fn, to handle the space overflow) (AND (APPLY* OFLOWFN WINDOW TEXTOBJ) (RETFROM (QUOTE \FILLWINDOW) NIL] (RETURN)) (DONTFILLFLG (* We are instructed NOT to try filling the screen, so punt out.) (RETURN)) ((OR (ILESSP CHARLIM TEXTLEN) (AND (IEQP CHARLIM TEXTLEN) (fetch CR\END of CURLINE)) (ZEROP TEXTLEN)) (* No existing lines to display, but there's text left (or the doc is empty and we need a dummy first line)) (SETQ LINE (\FORMATLINE TEXTOBJ NIL (ADD1 CHARLIM))) (* Format the next line) (replace PREVLINE of LINE with PREVLINE) (* Hook it into the chain of line descriptors) (replace NEXTLINE of LINE with (SETQ NEXTLINE (fetch NEXTLINE of PREVLINE))) (replace NEXTLINE of PREVLINE with LINE) (AND NEXTLINE (replace PREVLINE of NEXTLINE with LINE)) (COND ((IGEQ (SETQ YBOT (IDIFFERENCE YBOT (fetch LHEIGHT of LINE))) (fetch WBOTTOM of TEXTOBJ)) (* If there's room, display the new line) (replace YBOT of LINE with YBOT) (replace YBASE of LINE with (IPLUS YBOT (fetch DESCENT of LINE))) (\DISPLAYLINE TEXTOBJ LINE WINDOW)) (T (* Otherwise, we've overflown the window again) (SETQ YBOT (IPLUS YBOT (fetch LHEIGHT of LINE))) [COND ((SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN))) (AND (APPLY* OFLOWFN WINDOW TEXTOBJ) (RETFROM (QUOTE \FILLWINDOW) NIL] (RETURN] (COND (LINE (* Move forward to the next line in the chain, if any) (SETQ CHARLIM (fetch CHARLIM of LINE)) (SETQ PREVLINE LINE) (SETQ LINE (fetch NEXTLINE of LINE))) (T (* Otherwise, note that we ran off the end of the file.) (SETQ CHARLIM (ADD1 TEXTLEN] (while LINE do (* If there are any existing lines which didn't fit, set their YBOTs to 0 so they don't show) [AND (ILEQ (fetch CHAR1 of LINE) TEXTLEN) (replace YBOT of LINE with (SUB1 (fetch WBOTTOM of TEXTOBJ] (SETQ LINE (fetch NEXTLINE of LINE))) [COND ((IGEQ YBOT (fetch WBOTTOM of TEXTOBJ)) (* If there is space left at the bottom of the window, blank it out.) (BITBLT NIL 0 0 WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) (IDIFFERENCE YBOT (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (COND ([AND PREVLINE (fetch CR\END of PREVLINE) (OR (ILESSP (fetch YBOT of PREVLINE) WHEIGHT) (ILEQ (fetch CHARTOP of PREVLINE) 0)) (IGEQ (fetch CHARLIM of PREVLINE) TEXTLEN) (IGEQ (fetch YBOT of PREVLINE) (IPLUS (fetch LHEIGHT of PREVLINE) (fetch WBOTTOM of TEXTOBJ] (* If the last line ends in a CR, put a dummy line below it.) [SETQ LINE (replace NEXTLINE of PREVLINE with (\FORMATLINE TEXTOBJ NIL (ADD1 TEXTLEN] (replace PREVLINE of LINE with PREVLINE) (replace YBOT of LINE with (IDIFFERENCE (fetch YBOT of PREVLINE) (fetch LHEIGHT of LINE))) (replace YBASE of LINE with (IDIFFERENCE (fetch YBOT of PREVLINE) (fetch ASCENT of LINE))) (replace CHARLIM of LINE with (ADD1 TEXTLEN)) (SETQ PREVLINE LINE))) (COND ((AND (IGEQ (fetch CHARLIM of PREVLINE) TEXTLEN) (NOT (fetch CR\END of PREVLINE))) (* This line lies at end of text, so chop off any following lines.) (replace NEXTLINE of PREVLINE with NIL] (RETURN LINES\DELETED]) (\FIXDLINES [LAMBDA (LINES SEL CH#1 CH#LIM TEXTOBJ) (* jds "16-Nov-84 18:25") (* Fix up the list LINES of line descriptors, given that characters CH#1 thru CH#LIM were deleted.) (* Change CHAR1 and CHARLIM entries in each descriptor, and remove any descriptors for lines which disappeared entirely.) (for WW inside (fetch \WINDOW of TEXTOBJ) do [SETQ LINES (OR LINES (WINDOWPROP WW (QUOTE LINES] (PROG ((NLINES LINES) (DCH (ADD1 (IDIFFERENCE CH#LIM CH#1))) (CH#1L (SUB1 CH#1)) PL NL CHARLIM) (bind (LINE ←(fetch NEXTLINE of LINES)) CHARLIM CHAR1 while LINE do (SETQ CHARLIM (fetch CHARLIM of LINE)) (SETQ CHAR1 (fetch CHAR1 of LINE)) (COND [(ILESSP CHARLIM CH#1) (COND ((AND (IGEQ CH#1 CHAR1) (ILEQ CH#1 (fetch CHARTOP of LINE))) (* This change happened in a place where it may affect this line's break decision. Better reformat to be safe.) (replace DIRTY of LINE with T)) ((AND (fetch CR\END of LINE) (IEQP CHARLIM CH#1L)) (* This line ends in CR, and the deletion starts immediately thereafter. Best to reformat, for safety.) (replace DIRTY of LINE with T] ((IGREATERP CHAR1 CH#LIM) (* This line contains none of the deleted text but is after it. Update CHAR1, CHARLIM and CHARTOP) (replace CHAR1 of LINE with (IMAX 1 (IDIFFERENCE CHAR1 DCH))) (replace CHARLIM of LINE with (IDIFFERENCE CHARLIM DCH)) (replace CHARTOP of LINE with (IDIFFERENCE (fetch CHARTOP of LINE) DCH))) [(OR (ILESSP CHAR1 CH#1) (IGREATERP CHARLIM CH#LIM)) (* This line contains some of the deleted text, mark it as dirty and update CHAR1 and CHARLIM) (replace DIRTY of LINE with T) (replace CHAR1 of LINE with (IMAX 1 (IMIN CHAR1 CH#1))) (COND [(IGREATERP CHARLIM CH#LIM) (replace CHARLIM of LINE with (IDIFFERENCE CHARLIM (IMIN DCH (ADD1 (IDIFFERENCE CH#LIM CHAR1] (T (replace CHARLIM of LINE with CH#1L] (T (* This line is totally within the deleted text, remove it) (SETQ NL (fetch NEXTLINE of LINE)) (SETQ PL (fetch PREVLINE of LINE)) (COND (PL (replace NEXTLINE of PL with NL))) (COND (NL (replace PREVLINE of NL with PL))) (COND ((EQ NLINES LINE) (SETQ NLINES NL))) (replace DELETED of LINE with T) (* Mark this line deleted, so DELETETEXTCHARS know to ignore it.) )) (SETQ LINE (fetch NEXTLINE of LINE))) (\TEDIT.FIXDELSEL (fetch SEL of TEXTOBJ) TEXTOBJ CH#1 CH#LIM DCH) (* Fix up the selections in this textobj) (\TEDIT.FIXDELSEL (fetch SHIFTEDSEL of TEXTOBJ) TEXTOBJ CH#1 CH#LIM DCH) (\TEDIT.FIXDELSEL (fetch MOVESEL of TEXTOBJ) TEXTOBJ CH#1 CH#LIM DCH) (\TEDIT.FIXDELSEL (fetch DELETESEL of TEXTOBJ) TEXTOBJ CH#1 CH#LIM DCH) (RETURN NLINES]) (\FIXILINES [LAMBDA (TEXTOBJ SEL CH#1 DCH OTEXTLEN) (* edited: "21-Aug-84 18:20") (* Fix the list LINES of line descriptors to account for DCH characters inserted before CH#1) (PROG (LINES CH# CHLIM CHAR1 CHARLIM) (SETQ CH#1 (IMAX CH#1 1)) (* Make sure we're inserting in a legit spot.) [bind LINES for WW inside (ffetch \WINDOW of TEXTOBJ) do (* For each pane in the editing window, examine the pane's list of lines) (SETQ LINES (WINDOWPROP WW (QUOTE LINES))) (bind [LINE ←(COND ((IGEQ (ffetch CHARTOP of LINES) 0) (* Make sure to skip the initial dummy line) LINES) (T (ffetch NEXTLINE of LINES] while LINE do (\DTEST LINE (QUOTE LINEDESCRIPTOR)) (COND ((IGREATERP (SETQ CHAR1 (ffetch CHAR1 of LINE)) CH#1) (* This line starts after the insertion point. Update it's CHAR1) (freplace CHAR1 of LINE with (IPLUS CHAR1 DCH))) ((AND (IEQP CH#1 CHAR1) (NEQ LINE (ffetch L1 of SEL))) (* The insertion is at the end of the PRIOR line--so go ahead and update this CHAR1) (freplace CHAR1 of LINE with (IPLUS CHAR1 DCH)) (COND ((ffetch PREVLINE of LINE) (freplace DIRTY of (ffetch PREVLINE of LINE) with T))) (freplace DIRTY of LINE with T)) ((IGEQ (ffetch CHARTOP of LINE) CH#1) (* This line spans the insert point. Mark it DIRTY.) (freplace DIRTY of LINE with T)) ((AND (IGEQ (SETQ CHARLIM (ffetch CHARLIM of LINE)) OTEXTLEN) (NOT (ffetch CR\END of LINE))) (* This line is the last in the file, and its CHAR1 is <= the insert point, and it doesn't end in a CR. Therefore, move the line's end upward to accomodate the insertion.) (freplace DIRTY of LINE with T))) [COND ([OR (IGEQ (SETQ CHARLIM (ffetch CHARLIM of LINE)) CH#1) (AND (IGEQ CHARLIM OTEXTLEN) (NOT (ffetch CR\END of LINE] (freplace CHARLIM of LINE with (IPLUS CHARLIM DCH)) (COND ((IGEQ (ffetch CHARTOP of LINE) CH#1) (freplace CHARTOP of LINE with (IPLUS (ffetch CHARTOP of LINE) DCH] (SETQ LINE (ffetch NEXTLINE of LINE] (\TEDIT.FIXINSSEL (fetch MOVESEL of TEXTOBJ) TEXTOBJ CH#1 DCH) (\TEDIT.FIXINSSEL (fetch SHIFTEDSEL of TEXTOBJ) TEXTOBJ CH#1 DCH) (\TEDIT.FIXINSSEL SEL TEXTOBJ CH#1 DCH]) (\FORMATLINE [LAMBDA (TEXTOBJ FMTSPEC CH#1 OLINE 1STLN) (* jds "18-Oct-84 16:15") (* Given a starting place, format the next line of text. Return the LINEDESCRIPTOR; reusing OLINE if it's given.) (* If CH#1 is past end of document, \FORMATLINE returns an empty line descriptor that is set up right wrt leading and font. This is used by \FILLWINDOW to create the dummy line at end of document when you hit a CR there.) (PROG (TX [LINE (OR OLINE (create LINEDESCRIPTOR RIGHTMARGIN ←(fetch WRIGHT of TEXTOBJ) YBOT ←(SUB1 (fetch WBOTTOM of TEXTOBJ] DX (CH#B CH#1) TXB CH (FORCEEND NIL) (GATHERBLANK T) (T1SPACE NIL) TXB1 DXB WIDTH LOOK#B FONT (TLEN 0) (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (THISLINE (ffetch THISLINE of TEXTOBJ)) FONTWIDTHS (CHNO CH#1) (LOOKNO 0) (INVISIBLERUNS 0) (ASCENT 0) (DESCENT 0) (PREVSP 0) (#BLANKS 0) TERMSA CLOOKS TEXTSTREAM CHLIST WLIST LOOKS ASCENTB DESCENTB INVISIBLERUNSB TABPENDING BOX PC PCNO) % (* * Variables % (TLEN = Current character count on the line) (CHNO = Current character # in the %text) (DX = width of current char/object) (TX = current right margin) % (TXB1 = right margin of the first space/tab/CR in a row of space/tab/CR) % (CH#B = The CHNO of most recent space/tab) (TXB = right margin of most recent %space/tab) (DXB = width of most recent space/tab) (PREVSP = location on the line %of the previous space/tab to this space/tab + 1) (T1SPACE = a space/CR/TAB has been seen) (#BLANKS = # of spaces/tabs seen) % (LOOKNO = Current index into the LOOKS array. Updated by \TEDIT.LOOKS.UPDATE as %characters are read in) (LOOK#B = The LOOKNO of the most recent space/tab) (ASCENTB = Ascent at most recent potential line break point) (DESCENTB = Descent at most recent potential line break point)) (SETQ CHLIST (fetch (ARRAYP BASE) of (fetch CHARS of THISLINE))) (SETQ WLIST (fetch (ARRAYP BASE) of (fetch WIDTHS of THISLINE))) (SETQ LOOKS (fetch LOOKS of THISLINE)) (SETQ TEXTSTREAM (fetch STREAMHINT of TEXTOBJ)) (SETQ TERMSA (fetch TXTTERMSA of TEXTOBJ)) (replace LOOKSUPDATEFN of TEXTSTREAM with (QUOTE \TEDIT.LOOKS.UPDATE)) (freplace CHARLIM of LINE with TEXTLEN) (* Force each new line to find its true CHARLIM.) (freplace DIRTY of LINE with NIL) (* And as unchanged since the last formatting.) (freplace CHAR1 of LINE with CH#1) (freplace CR\END of LINE with NIL) (* Assume we won't see a CR.) (replace LHASTABS of LINE with NIL) (* And has no TABs.) (COND [(COND ((AND (ILEQ CH#1 TEXTLEN) (NOT (ZEROP TEXTLEN))) (* Only continue if there's really text we can format.) (\SETUPGETCH CH#1 TEXTOBJ) (* Starting place) (* And starting character looks) (SETQ CLOOKS (fetch (TEXTSTREAM CURRENTLOOKS) of TEXTSTREAM)) (COND ((fetch CLINVISIBLE of CLOOKS) (* We've hit a run of invisible characters. Skip them, and insert a marker in the line cache) (add LOOKNO 1) (* Fix the counter of charlooks changes) (SETQ PC (fetch (TEXTSTREAM PIECE) of TEXTSTREAM)) (\EDITSETA LOOKS LOOKNO (SETQ INVISIBLERUNS (fetch PLEN of PC))) (\RPLPTR CHLIST 0 401) (\PUTBASE WLIST 0 0) (add TLEN 1) (SETQ CHLIST (\ADDBASE CHLIST 2)) (SETQ WLIST (\ADDBASE WLIST 1)) (SETQ PC (fetch NEXTPIECE of PC)) (SETQ PCNO (ADD1 (fetch (TEXTSTREAM PCNO) of TEXTSTREAM))) (SETQ CLOOKS (AND PC (\TEDIT.APPLY.STYLES (ffetch PLOOKS of PC) PC TEXTOBJ))) (while (AND PC (fetch CLINVISIBLE of CLOOKS)) do (\EDITSETA LOOKS LOOKNO (add INVISIBLERUNS (fetch PLEN of PC))) (SETQ PC (fetch NEXTPIECE of PC)) (SETQ CLOOKS (AND PC (\TEDIT.APPLY.STYLES (ffetch PLOOKS of PC) PC TEXTOBJ))) (add PCNO 1)) (add CHNO (\EDITELT LOOKS LOOKNO)) (\SETUPGETCH (create EDITMARK PC ←(OR PC (QUOTE LASTPIECE)) PCOFF ← 0 PCNO ← PCNO) TEXTOBJ))) (ILEQ CHNO TEXTLEN))) (SETQ FONT (FONTCOPY (fetch CLFONT of CLOOKS) (QUOTE DEVICE) (QUOTE DISPLAY))) [SETQ ASCENTB (SETQ ASCENT (IMAX ASCENT (IPLUS (fetch \SFAscent of FONT) (OR (fetch CLOFFSET of CLOOKS) 0] [SETQ DESCENTB (SETQ DESCENT (IMAX DESCENT (IDIFFERENCE (fetch \SFDescent of FONT) (OR (fetch CLOFFSET of CLOOKS) 0] [SETQ FONTWIDTHS (COND (TERMSA (\TEDIT.GET.TERMSA.WIDTHS TERMSA FONT)) (T (fetch \SFWidths of FONT] (\EDITSETA LOOKS 0 CLOOKS) (* Save looks in the line cache) [OR FMTSPEC (SETQ FMTSPEC (OR (fetch PPARALOOKS of (fetch (TEXTSTREAM PIECE) of TEXTSTREAM)) (fetch FMTSPEC of TEXTOBJ] (* Get the paragraph looks) [SETQ 1STLN (OR (IEQP CH#1 1) (AND (fetch (TEXTSTREAM PIECE) of TEXTSTREAM) (fetch PREVPIECE of (fetch (TEXTSTREAM PIECE) of TEXTSTREAM)) (fetch PPARALAST of (fetch PREVPIECE of (fetch (TEXTSTREAM PIECE) of TEXTSTREAM))) (IEQP (fetch (TEXTSTREAM PCSTARTCH) of TEXTSTREAM) (fetch COFFSET of TEXTSTREAM)) (IEQP (fetch (TEXTSTREAM PCSTARTPG) of TEXTSTREAM) (fetch CPAGE of TEXTSTREAM] (replace LMARK of LINE with NIL) (* Start by assuming that we don't want a margin marker for this line.) (replace 1STLN of LINE with 1STLN) (* Are we on the first line of a paragraph?) [COND (1STLN (* This is the first line of a paragraph. Check for special paragraph types, like headings, that get marked in the margin.) (COND ((EQ (fetch FMTPARATYPE of FMTSPEC) (QUOTE PAGEHEADING)) (replace LMARK of LINE with (QUOTE GREY))) ((OR (fetch FMTNEWPAGEBEFORE of FMTSPEC) (fetch FMTNEWPAGEAFTER of FMTSPEC)) (replace LMARK of LINE with (QUOTE GREY))) ([AND (fetch FMTSPECIALX of FMTSPEC) (NOT (ZEROP (fetch FMTSPECIALX of FMTSPEC] (replace LMARK of LINE with (QUOTE GREY))) ([AND (fetch FMTSPECIALY of FMTSPEC) (NOT (ZEROP (fetch FMTSPECIALY of FMTSPEC] (replace LMARK of LINE with (QUOTE GREY] [SETQ TX (replace LEFTMARGIN of LINE with (IPLUS 8 (fetch WLEFT of TEXTOBJ) (COND (1STLN (fetch 1STLEFTMAR of FMTSPEC)) (T (fetch LEFTMAR of FMTSPEC] (* Set the left margin accordingly) [replace RIGHTMARGIN of LINE with (SETQ WIDTH (COND ((NOT (ZEROP (fetch RIGHTMAR of FMTSPEC))) (IPLUS 8 (fetch RIGHTMAR of FMTSPEC))) (T (IDIFFERENCE (fetch WRIGHT of TEXTOBJ) 8] (* RIGHTMAR = 0 => follow the window's width.) (SETQ TXB1 WIDTH) (for old TLEN from TLEN to 254 as old CHNO from CHNO to TEXTLEN when (SETQ CH (\BIN TEXTSTREAM) ) do (* The character loop) (* Get the next character for the line.) [SETQ DX (COND ((SMALLP CH) (* CH is really a character) (\GETWIDTH FONTWIDTHS CH)) (T (* CH is an object) (SETQ BOX (APPLY* (IMAGEOBJPROP CH (QUOTE IMAGEBOXFN)) CH (fetch DS of TEXTOBJ) TX WIDTH)) (* Get its size) [SETQ ASCENT (IMAX ASCENT (IDIFFERENCE (fetch YSIZE of BOX) (fetch YDESC of BOX] (SETQ DESCENT (IMAX DESCENT (fetch YDESC of BOX))) (IMAGEOBJPROP CH (QUOTE BOUNDBOX) BOX) (COND ([NEQ 1 (fetch PLEN of (SETQ PC (fetch (TEXTSTREAM PIECE) of TEXTSTREAM] (* The object is several chars wide, but doesn't have a subsidiary stream to pull those chars from. Build an invisible run to fill the space.) (add LOOKNO 1) (* Fix the counter of charlooks changes) (\EDITSETA LOOKS LOOKNO (SUB1 (fetch PLEN of PC))) (\RPLPTR CHLIST 0 LMInvisibleRun) (* Note the existence of an invisible run of characters here.) (\PUTBASE WLIST 0 0) (add TLEN 1) (SETQ CHLIST (\ADDBASE CHLIST 2)) (SETQ WLIST (\ADDBASE WLIST 1)) (add CHNO (SUB1 (fetch PLEN of PC))) (add INVISIBLERUNS (\EDITELT LOOKS LOOKNO)) (* Keep track of how much invisible text we cross over) )) (fetch XSIZE of BOX] (* Get CH's X width.) [SELCHARQ CH (SPACE (* CH is a <Space>. Remember it, in case we need to break the line.) (COND (GATHERBLANK (SETQ TXB1 TX) (SETQ GATHERBLANK NIL))) (SETQ CH#B CHNO) (* put the location # of the previous space/tab in the character array instead of the space itself) (\RPLPTR CHLIST 0 PREVSP) (\PUTBASE WLIST 0 DX) (SETQ PREVSP (ADD1 TLEN)) (SETQ T1SPACE T) (add TX DX) (SETQ TXB TX) (SETQ DXB DX) (SETQ LOOK#B LOOKNO) (SETQ ASCENTB ASCENT) (SETQ DESCENTB DESCENT) (SETQ INVISIBLERUNSB INVISIBLERUNS) (add #BLANKS 1)) (CR (* Ch is a <Return>. Force an end to the line.) (freplace CHARLIM of LINE with CHNO) (SETQ FORCEEND T) (\RPLPTR CHLIST 0 (CHARCODE CR)) (\PUTBASE WLIST 0 (SETQ DX (IMAX DX 6))) (COND (GATHERBLANK (SETQ TXB1 TX) (SETQ GATHERBLANK NIL))) (SETQ T1SPACE T) (freplace CR\END of LINE with T) (SETQ TX (IPLUS TX DX)) (replace LSTLN of LINE with T) (* This has to be done better when we get non-para breaking CRs.) (RETURN)) (TAB (* Try to be reasonable with tabs. This will create trouble when doing fast-case insert/delete, but Pah! for now.) (replace LHASTABS of LINE with T) (* To disable smart screen update) (SETQ TABPENDING (\TEDIT.FORMATTABS TEXTOBJ FMTSPEC THISLINE CHLIST WLIST TX 36 8 TABPENDING)) (* Figure out which tab stop to use, and what we need to do to get there.) [COND ((FIXP TABPENDING) (* If it returns a number, that is the new TX, adjusted for any prior tabs) (SETQ TX TABPENDING) (SETQ TABPENDING NIL)) (TABPENDING (* Otherwise, look in the PENDINGTAB for the new TX) (SETQ TX (fetch PTNEWTX of TABPENDING] (COND (GATHERBLANK (SETQ TXB1 TX) (SETQ GATHERBLANK NIL))) (SETQ CH#B CHNO) (SETQ DX (\GETBASE WLIST 0)) (\RPLPTR CHLIST 0 CH) (\TEDIT.PURGE.SPACES (fetch CHARS of THISLINE) PREVSP) (* All the spaces before a tab don't take part in justification from here on.) (SETQ PREVSP 0) (SETQ T1SPACE T) (SETQ TX (IPLUS TX DX)) (SETQ TXB TX) (* Remember the world in case this is the "space" before the line breaks) (SETQ DXB DX) (SETQ LOOK#B LOOKNO) (SETQ ASCENTB ASCENT) (SETQ DESCENTB DESCENT) (SETQ INVISIBLERUNSB INVISIBLERUNS)) (PROGN (SETQ GATHERBLANK T) (COND ((IGREATERP (SETQ TX (IPLUS TX DX)) WIDTH) (* We're past the right margin; stop formatting at the last blank.) (SETQ FORCEEND T) (COND (T1SPACE (* There's a breaking point on this line. Go back there and break the line.) (freplace CHARLIM of LINE with CH#B) (SETQ TX TXB) (SETQ DX DXB) (SETQ ASCENT ASCENTB) (SETQ DESCENT DESCENTB) (SETQ LOOKNO LOOK#B) (SETQ INVISIBLERUNS INVISIBLERUNSB)) ((IGREATERP TLEN 0) (freplace CHARLIM of LINE with (IMAX (SUB1 CHNO) CH#1)) (SETQ TX (IDIFFERENCE TX DX)) (* No spaces on this line; break it before this character.) ) (T (* Can't split BEFORE the first thing on the line!) (freplace CHARLIM of LINE with CHNO) (\RPLPTR CHLIST 0 CH) (\PUTBASE WLIST 0 DX))) (RETURN)) (T (* Not past the rightmargin yet...) (\RPLPTR CHLIST 0 CH) (\PUTBASE WLIST 0 DX] (SETQ CHLIST (\ADDBASE CHLIST 2)) (* Move the pointers forward for the next character.) (SETQ WLIST (\ADDBASE WLIST 1))) (COND ((AND (IEQP TLEN 255) (ILESSP CHNO TEXTLEN)) (* This line is too long for us to format??) (TEDIT.PROMPTPRINT TEXTOBJ "Line too long to format." T))) (COND (TABPENDING (* There is a TAB outstanding. Go handle it.) (SETQ TABPENDING (\TEDIT.FORMATTABS TEXTOBJ FMTSPEC THISLINE CHLIST WLIST TX 36 8 TABPENDING)) [COND ((FIXP TABPENDING) (* If it returns a number, that is the new TX, adjusted for any prior tabs) (SETQ TX TABPENDING) (SETQ TABPENDING NIL)) (TABPENDING (* Otherwise, look in the PENDINGTAB for the new TX) (SETQ TX (fetch PTNEWTX of TABPENDING] (\TEDIT.PURGE.SPACES (fetch CHARS of THISLINE) PREVSP) (SETQ PREVSP 0] (T (* No text to go in this line; set Ascent/Descent to the default font from the window.) [SETQ PC (AND (IGREATERP TEXTLEN 0) (\CHTOPC TEXTLEN (fetch PCTB of TEXTOBJ] (* Grab the last real part of the document, to get paragraph looks) (SETQ FONT (OR (AND (fetch CARETLOOKS of TEXTOBJ) (fetch CLFONT of (fetch CARETLOOKS of TEXTOBJ))) (AND (fetch DEFAULTCHARLOOKS of TEXTOBJ) (fetch CLFONT of (fetch DEFAULTCHARLOOKS of TEXTOBJ))) DEFAULTFONT)) (* The font we use is preferably the caret looks, else the default for this edit, else the system default) (SETQ ASCENT (FONTPROP FONT (QUOTE ASCENT))) (SETQ DESCENT (FONTPROP FONT (QUOTE DESCENT))) (SETQ FMTSPEC (OR FMTSPEC (AND PC (fetch PPARALOOKS of PC)) (fetch FMTSPEC of TEXTOBJ))) (* Use the preceding paragraph's looks) (SETQ 1STLN (OR (NOT PC) (fetch PPARALAST of PC))) (replace 1STLN of LINE with 1STLN) [SETQ TX (COND [1STLN (replace LEFTMARGIN of LINE with (IPLUS 8 (fetch WLEFT of TEXTOBJ) (fetch 1STLEFTMAR of FMTSPEC] (T (replace LEFTMARGIN of LINE with (IPLUS 8 (fetch WLEFT of TEXTOBJ) (fetch LEFTMAR of FMTSPEC] [replace RIGHTMARGIN of LINE with (SETQ WIDTH (COND ((NOT (ZEROP (fetch RIGHTMAR of FMTSPEC))) (fetch RIGHTMAR of FMTSPEC)) (T (IDIFFERENCE (fetch WRIGHT of TEXTOBJ) 8] (SETQ TXB1 WIDTH))) [COND ((ZEROP (freplace LHEIGHT of LINE with (IPLUS ASCENT DESCENT))) (replace LHEIGHT of LINE with (FONTPROP (OR (AND (fetch DEFAULTCHARLOOKS of TEXTOBJ) (fetch CLFONT of (fetch DEFAULTCHARLOOKS of TEXTOBJ))) DEFAULTFONT) (QUOTE HEIGHT] (* Line's height (or 12 for an empty line)) (replace ASCENT of LINE with ASCENT) (replace DESCENT of LINE with DESCENT) (freplace CHARTOP of LINE with CHNO) [COND (FORCEEND NIL) (T (SETQ CHNO (SUB1 CHNO)) (SETQ TLEN (SUB1 TLEN] (* If we ran off the end of the text, then keep true space left on the line.) (freplace LXLIM of LINE with TX) [freplace SPACELEFT of LINE with (COND (FORCEEND (* The line was forced to end. Back up to start of last blank section) (IDIFFERENCE WIDTH TXB1)) (GATHERBLANK (* Otherwise, use the rightmost character on the line.) (IDIFFERENCE WIDTH TX)) (T (* The line ended with a run of white space. Ignore it for purposes of deciding how much more we can fit on the line.) (IDIFFERENCE WIDTH TXB1] (freplace DESC of THISLINE with LINE) [freplace LEN of THISLINE with (IMIN 254 (COND ((ILESSP TEXTLEN CH#1) -1) (T (IPLUS LOOKNO (IDIFFERENCE (IMIN (fetch CHARLIM of LINE) TEXTLEN) (IPLUS INVISIBLERUNS (fetch CHAR1 of LINE] (\DOFORMATTING TEXTOBJ LINE FMTSPEC THISLINE #BLANKS PREVSP 1STLN) (replace LFMTSPEC of LINE with FMTSPEC) (replace LOOKSUPDATEFN of TEXTSTREAM with NIL) (RETURN LINE]) (\PULLTEXT [LAMBDA (LINE DX CH1 TEXTOBJ) (* jds "31-Oct-84 14:57") (* Reset start of line to ch1, and pull dx off the front.) (COND ((ILESSP DX 0) (ERROR "MOVING TEXT DOWN AFTER A DELETE??!" DX))) (PROG ((OXLIM (fetch LXLIM of LINE)) (OCHLIM (fetch CHARLIM of LINE)) (OLEFTMAR (fetch LEFTMARGIN of LINE)) (OLHEIGHT (fetch LHEIGHT of LINE)) (OLASCENT (fetch ASCENT of LINE)) (OLDESCENT (fetch DESCENT of LINE)) (OSPACE (IPLUS (fetch SPACELEFT of LINE) DX)) NLINE NDX NL (DEL NIL) (DS (fetch DS of TEXTOBJ)) (OCH1 (fetch CHAR1 of LINE))) (replace DIRTY of LINE with NIL) (replace SPACELEFT of LINE with OSPACE) (* There's going to be more space on this line when we're done.) (replace CHAR1 of LINE with CH1) (BITBLT DS (IPLUS (fetch LEFTMARGIN of LINE) DX) (fetch YBOT of LINE) DS (fetch LEFTMARGIN of LINE) (fetch YBOT of LINE) (fetch RIGHTMARGIN of LINE) (fetch LHEIGHT of LINE) (QUOTE INPUT) (QUOTE REPLACE)) (* Move remaining text over) (SETQ OXLIM (IDIFFERENCE OXLIM DX)) (* And shorten the line accordingly) (BITBLT NIL 0 0 DS (IDIFFERENCE (fetch RIGHTMARGIN of LINE) OSPACE) (fetch YBOT of LINE) (fetch RIGHTMARGIN of LINE) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Blank the newly-cleared section of the line's image) (COND ((IEQP OXLIM (fetch LEFTMARGIN of LINE)) (TEDIT.DELETELINE LINE TEXTOBJ) (* The call to \PULLTEXT emptied this line completely. Throw it away.) (SETQ DEL T)) [T (* Need to check for flow-in from the next line.) (\FORMATLINE TEXTOBJ NIL CH1 LINE) (\TEDIT.ADJUST.LINES TEXTOBJ LINE DS (IPLUS (fetch YBOT of LINE) (IMIN OLHEIGHT (fetch LHEIGHT of LINE))) (IDIFFERENCE OLASCENT (fetch ASCENT of LINE))) (* Allow for differences in ascent of the line) (\TEDIT.ADJUST.LINES TEXTOBJ NEXTLINE WINDOW (fetch YBOT of LINE) (IDIFFERENCE OLDESCENT (fetch DESCENT of LINE))) (COND ([NOT (ZEROP (SETQ NDX (IDIFFERENCE (IDIFFERENCE (fetch LXLIM of LINE) (fetch LEFTMARGIN of LINE)) (IDIFFERENCE OXLIM OLEFTMAR] (* The line length changed from what we'd expected. Some text got moved up from below.) (COND ((ILESSP NDX 0) (ERROR "Moving Text down after DEL." NDX)) (T (COND [(AND (SETQ NLINE (fetch NEXTLINE of LINE)) (IGEQ (fetch YBOT of NLINE) (fetch WBOTTOM of TEXTOBJ))) (COND ((OR (fetch LHASTABS of LINE) (fetch LHASTABS of NLINE)) (* There are TABS involved. punt out.) (\DISPLAYLINE TEXTOBJ LINE) (replace CHAR1 of NLINE with (ADD1 (fetch CHARLIM of LINE))) (replace DIRTY of NLINE with T) (TEDIT.UPDATE.SCREEN TEXTOBJ NLINE) (RETURN NIL)) [(IGEQ (IDIFFERENCE (fetch LXLIM of NLINE) (fetch LEFTMARGIN of NLINE)) NDX) (* There's enough on the next line to grab) (BITBLT DS (fetch LEFTMARGIN of NLINE) (fetch YBOT of NLINE) DS OXLIM (IPLUS (fetch YBOT of LINE) (IDIFFERENCE (fetch DESCENT of LINE) (fetch DESCENT of NLINE))) NDX (IMIN (fetch LHEIGHT of LINE) (fetch LHEIGHT of NLINE)) (QUOTE INPUT) (QUOTE PAINT)) (* Move the text up from the next line) (COND ((ILESSP (fetch CHARLIM of LINE) (fetch TEXTLEN of TEXTOBJ)) (* There are more characters to go on the next line.) (SETQ DEL (\PULLTEXT NLINE NDX (ADD1 (fetch CHARLIM of LINE)) TEXTOBJ))) (T (* This line is the last. Delete all the others) (SETQ DEL T) (replace NEXTLINE of LINE with NIL) (replace PREVLINE of NLINE with NIL) (BITBLT NIL 0 0 DS 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) (IDIFFERENCE (SUB1 (fetch YBOT of LINE)) (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE] (T (* Not enough on next line;; grab it and loop) (ERROR "PULLING TEXT FROM TOO SHORT A LINE"] (T (\DISPLAYLINE TEXTOBJ LINE) (replace NEXTLINE of LINE with NIL) (AND NLINE (replace PREVLINE of NLINE with NIL] (T (replace LXLIM of LINE with OXLIM))) (RETURN DEL]) (\PUSHTEXT [LAMBDA (LINE X Y DX CH TEXTOBJ FORCEFORMAT IMAGECACHE SAVEWIDTH PREVDESCENT) (* jds "31-Oct-84 14:02") (* MOVE TEXT FROM THE LINE ABOVE ONTO THIS LINE) (PROG ((NDX 0) (OXLIM (fetch LXLIM of LINE)) (OCHLIM (fetch CHARLIM of LINE)) (OSPACE (fetch SPACELEFT of LINE)) (OLHEIGHT (fetch LHEIGHT of LINE)) (OLASCENT (fetch ASCENT of LINE)) (OLDESCENT (fetch DESCENT of LINE)) (OTABS (fetch LHASTABS of LINE)) (DS (ffetch DS of TEXTOBJ)) (NEXTCACHE (fetch LCNEXTCACHE of IMAGECACHE)) NEXTLINE OCR\END NEWLINE NSAVEWIDTH OFLOWFN DY IMAGE) (replace CHAR1 of LINE with CH) (* Fix up this line to start just after old line ends) (SETQ OCR\END (fetch CR\END of LINE)) (\FORMATLINE TEXTOBJ NIL CH LINE) (\TEDIT.ADJUST.LINES TEXTOBJ LINE DS (IPLUS (fetch YBOT of LINE) (IMIN OLHEIGHT (fetch LHEIGHT of LINE))) (IDIFFERENCE OLASCENT (fetch ASCENT of LINE))) (\TEDIT.ADJUST.LINES TEXTOBJ NEXTLINE WINDOW (fetch YBOT of LINE) (IDIFFERENCE OLDESCENT (fetch DESCENT of LINE))) (COND ((OR (fetch LHASTABS of LINE) OTABS) (* Punt if this line has tabs in it.) (replace DIRTY of LINE with T) (TEDIT.UPDATE.SCREEN TEXTOBJ LINE) (RETURN))) [COND [(OR FORCEFORMAT (IGREATERP DX OSPACE)) (* May need to move some text to yet another line...) (SETQ NDX (IDIFFERENCE (IPLUS OXLIM DX) (fetch LXLIM of LINE))) (* NDX ← Amount of text to be moved to the next line) (COND ((IGREATERP NDX 0) (* There is excess on this line--move it to the next line) (COND (OCR\END (* This line ends in a CR -- just create a new line with the overflow on it) [SETQ NEWLINE (\FORMATLINE TEXTOBJ NIL (ADD1 (fetch CHARLIM of LINE] (replace YBOT of NEWLINE with (IDIFFERENCE (fetch YBOT of LINE) (fetch LHEIGHT of NEWLINE))) (replace YBASE of NEWLINE with (IPLUS (fetch YBOT of NEWLINE) (fetch DESCENT of NEWLINE))) (COND ((AND (SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN))) (APPLY* OFLOWFN DS TEXTOBJ)) (RETURN NIL)) ((SETQ NEXTLINE (fetch NEXTLINE of LINE)) (* There's another line to push onto.) (OR (\TEDIT.ADJUST.LINES TEXTOBJ NEXTLINE DS (fetch YBOT of LINE) (IMINUS (fetch LHEIGHT of NEWLINE))) (RETURN NIL)) (* If pushing overflowed the window, punt here and now.) (BITBLT NIL 0 0 DS 0 (IDIFFERENCE (fetch YBOT of LINE) (fetch LHEIGHT of NEWLINE)) (fetch WRIGHT of TEXTOBJ) (fetch LHEIGHT of NEWLINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (replace PREVLINE of NEXTLINE with NEWLINE))) (replace NEXTLINE of NEWLINE with NEXTLINE) (replace PREVLINE of NEWLINE with LINE) (replace NEXTLINE of LINE with NEWLINE) (\TEDIT.CHECK (fetch TCUP of (fetch CARET of TEXTOBJ)) "Caret visible during pushtext move down.") (BITBLT DS (IDIFFERENCE OXLIM NDX) (fetch YBOT of LINE) DS (fetch LEFTMARGIN of NEWLINE) (fetch YBOT of NEWLINE) NDX (fetch LHEIGHT of NEWLINE) (QUOTE INPUT) (QUOTE REPLACE)) (* Move the text onto the newly-built line) (SETQ NDX 0)) ((fetch NEXTLINE of LINE) (* There is text to be moved onto the next line; save its image for the move which happens later) [SETQ NSAVEWIDTH (IMIN NDX (IMAX 0 (IDIFFERENCE (fetch RIGHTMARGIN of LINE) (IDIFFERENCE OXLIM NDX] (\TEDIT.CHECK (fetch TCUP of (fetch CARET of TEXTOBJ))) (* THE CARET MUST BE INVISIBLE) (SETQ IMAGE (\TEDIT.LINECACHE NEXTCACHE NSAVEWIDTH (fetch LHEIGHT of LINE))) (BITBLT DS (IDIFFERENCE OXLIM NDX) (fetch YBOT of LINE) IMAGE 0 0 NDX (fetch LHEIGHT of LINE) (QUOTE INPUT) (QUOTE REPLACE)) (* Save the text that will be moved down later on) ) (T (* No succeeding line, so create one.) [SETQ NEXTLINE (\FORMATLINE TEXTOBJ NIL (ADD1 (fetch CHARLIM of LINE] (COND ((IGEQ (fetch YBOT of LINE) (IPLUS (fetch LHEIGHT of NEXTLINE) (fetch WBOTTOM of TEXTOBJ))) (replace YBOT of NEXTLINE with (IDIFFERENCE (fetch YBOT of LINE) (fetch LHEIGHT of NEXTLINE))) (replace YBASE of NEXTLINE with (IPLUS (fetch YBOT of NEXTLINE) (fetch DESCENT of NEXTLINE))) (\DISPLAYLINE TEXTOBJ NEXTLINE NIL NEXTCACHE)) ((AND (SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN))) (APPLY* OFLOWFN DS TEXTOBJ)) (* This line overflowed the window. If it gets handled by user handler, just punt out.) (RETURN NIL))) (replace NEXTLINE of LINE with NEXTLINE) (replace PREVLINE of NEXTLINE with LINE) (SETQ NDX 0] (T (* There is enough room on this line, so not to worry about moving text down.) (replace SPACELEFT of LINE with (IDIFFERENCE (fetch SPACELEFT of LINE) DX)) (replace LXLIM of LINE with (IPLUS OXLIM DX] (COND ((IGEQ (fetch YBOT of LINE) (fetch WBOTTOM of TEXTOBJ)) (* This line is fully on-screen. Move it over to make room for text, then move the text in from above.) (BITBLT DS (fetch LEFTMARGIN of LINE) (fetch YBOT of LINE) DS (IPLUS (fetch LEFTMARGIN of LINE) DX) (fetch YBOT of LINE) OXLIM (fetch LHEIGHT of LINE) (QUOTE INPUT) (QUOTE REPLACE)) (* Move this line over to make room.) (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LINE) (fetch YBOT of LINE) DX (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Blank out the space just cleared.) (BITBLT (fetch LCBITMAP of IMAGECACHE) 0 0 DS (fetch LEFTMARGIN of LINE) (IPLUS (fetch YBOT of LINE) (IDIFFERENCE PREVDESCENT (fetch DESCENT of LINE))) SAVEWIDTH (fetch LHEIGHT of LINE) (QUOTE INPUT) (QUOTE PAINT)) (* Move the text in from above.) (BITBLT NIL 0 0 DS (fetch LXLIM of LINE) (fetch YBOT of LINE) (fetch WRIGHT of TEXTOBJ) (fetch LHEIGHT of LINE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Blank out the area beyond the end of this line) (* Cache the new image) (OR (ILEQ NDX 0) (\PUSHTEXT (fetch NEXTLINE of LINE) (IDIFFERENCE OXLIM NDX) (fetch YBOT of LINE) NDX (ADD1 (fetch CHARLIM of LINE)) TEXTOBJ OCR\END NEXTCACHE NSAVEWIDTH (fetch DESCENT of LINE))) (* Now propogate the change to the next line.) )) (replace DIRTY of LINE with NIL) (RETURN T]) (\SHOWTEXT [LAMBDA (TEXTOBJ LINES WINDOW) (* edited: "22-Aug-84 18:24") (* Fill the editor window with text, starting from the top of the file.) (COND ((fetch \WINDOW of TEXTOBJ) (* If there is no edit window, just return.) (PROG (WREG) (SETQ WINDOW (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ))) (DSPFILL (CREATEREGION (fetch WLEFT of TEXTOBJ) (fetch WBOTTOM of TEXTOBJ) (IDIFFERENCE (fetch WRIGHT of TEXTOBJ) (fetch WLEFT of TEXTOBJ)) (IDIFFERENCE (fetch WTOP of TEXTOBJ) (fetch WBOTTOM of TEXTOBJ))) WHITESHADE (QUOTE REPLACE) WINDOW) (* Clear the window.) (RETURN (RESETLST (RESETSAVE (CURSOR WAITINGCURSOR)) (* Display the hourglass cursor as we work) (SETQ LINES (create LINEDESCRIPTOR YBOT ←(fetch WTOP of TEXTOBJ) CHAR1 ← 0 CHARLIM ← 0 SPACELEFT ← -1 RIGHTMARGIN ←(SUB1 (fetch WRIGHT of TEXTOBJ)) NEXTLINE ← NIL CHARTOP ← -1 LHEIGHT ← 0 LXLIM ←(fetch WRIGHT of TEXTOBJ) CR\END ← T ASCENT ← 0 DESCENT ← 0 LTRUEASCENT ← 0)) (* Make sure we have the anchor pseudo-line) (\FILLWINDOW (fetch WTOP of TEXTOBJ) LINES TEXTOBJ NIL WINDOW) (* Fill the window as usual) (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WINDOW) LINES]) (\TEDIT.ADJUST.LINES [LAMBDA (TEXTOBJ FIRSTLINE WINDOW LINETOP DY) (* edited: "11-Sep-84 16:15") (* Move all lines from FIRSTLINE (inclusive) on up or down. Fill in a line or drop one off, accordingly. Positive DY means move UP.) (* LINETOP is the top of the region to be moved as the adjustment is made. It corresponds to the TOP of FIRSTLINE.) (PROG ((OFLOW NIL) OFLOWFN OYBOT PREVLINE) [COND ((NOT (ZEROP DY)) (* This line's total height changed -- must move the rest of the window, and adjust YBOT/BASEs.) (bind (LL ← FIRSTLINE) while (AND LL (IGEQ (fetch YBOT of LL) (fetch WBOTTOM of TEXTOBJ))) do (* Loop thru the line descriptors that are affected by the change (i.e., those below it), and adjust their Y locations.) (SETQ OYBOT (fetch YBOT of LL)) [COND ((ILESSP (replace YBOT of LL with (IPLUS OYBOT DY)) (fetch WBOTTOM of TEXTOBJ)) (* This line moved below the bottom of the screen) (BITBLT NIL 0 0 WINDOW 0 OYBOT (fetch WRIGHT of TEXTOBJ) (fetch LHEIGHT of LL) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* So clear the space it used to occupy.) (COND ((AND (SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN))) (SETQ OFLOW T) (APPLY* OFLOWFN WINDOW TEXTOBJ) (RETURN NIL)) (* We walked off the bottom, and the user gave us an OFLOWFN to handle it. Give it a try.) ] (add (fetch YBASE of LL) DY) (* Adjust the baseline of the line, as well as its physical bottom.) (replace YBOT of LL with (IDIFFERENCE (fetch YBASE of LL) (fetch DESCENT of LL))) (* I realize this looks redundant, but the line's descent may have changed, too.) (SETQ PREVLINE LL) (* Remember the prior line, since we'll need it if we later try to fill out the window with more text.) (SETQ LL (fetch NEXTLINE of LL)) (* Move to the next line.)) (AND OFLOW (RETURN NIL)) (* If there was an overflow, and it got handled by the user's OFLOWFN, don't bother trying anything further.) (COND [(IGREATERP DY 0) (* The line is shorter; move the rest up.) (BITBLT WINDOW 0 (fetch WBOTTOM of TEXTOBJ) WINDOW 0 (IPLUS DY (fetch WBOTTOM of TEXTOBJ)) (fetch WRIGHT of TEXTOBJ) LINETOP (QUOTE INPUT) (QUOTE REPLACE)) (* Move the text up) (BITBLT NIL 0 0 WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) DY (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Now clear the bottom part of the window, which got vacated by the adjustment) (COND ((AND PREVLINE (IGEQ (fetch YBOT of PREVLINE) (fetch WBOTTOM of TEXTOBJ))) (* If there is space left on the screen, try to fill it with new text.) (\FILLWINDOW (fetch YBOT of PREVLINE) PREVLINE TEXTOBJ NIL WINDOW] (T (* The line is taller; move the rest down.) (BITBLT WINDOW 0 (IPLUS (fetch WBOTTOM of TEXTOBJ) (IMINUS DY)) WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) (IDIFFERENCE LINETOP (fetch WBOTTOM of TEXTOBJ)) (QUOTE INPUT) (QUOTE REPLACE)) (* Move the text down) (BITBLT NIL 0 0 WINDOW 0 (IPLUS LINETOP DY) (fetch WRIGHT of TEXTOBJ) (IMINUS DY) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Now clear the region we moved it out of.) ] (RETURN T]) (\TEDIT.BLTCHAR [LAMBDA (CHARCODE DISPLAYSTREAM WIDTH CURX DISPLAYDATA DDPILOTBBT DDWIDTHCACHE DDOFFSETCACHE CLIPRIGHT) (* jds "15-Mar-84 16:26") (* Version of BLTCHAR peculiar to TEdit -- relies on \DISPLAYLINE to make sure things keep working right.) (* puts a character on a guaranteed display stream. Much of the information needed by the BitBlt microcode is prestored by the routines that change it. This is kept in the BitBltTable.) (* knows about the representation of display stream image data) (* MUST NOT POINT AT A WINDOW'S DISPLAYSTREAM!!!) (* ASSUMES THAT WE NEVER WANT TO PRINT TO THE LEFT OF ORIGIN 0 ON THE LINE CACHE BITMAP, OR THAT IF WE DO, ALL BETS ARE OFF) (DECLARE (LOCALVARS . T)) (PROG (NEWX LEFT RIGHT) (SETQ NEWX (IPLUS CURX WIDTH)) (SETQ LEFT (IMAX 0 CURX)) (SETQ RIGHT (IMIN CLIPRIGHT NEWX)) (COND ((ILESSP LEFT RIGHT) (* Only print anything if there is a place to put it) (UNINTERRUPTABLY (freplace PBTDESTBIT of DDPILOTBBT with LEFT) (* Set up the bitblt-table source left) (freplace PBTWIDTH of DDPILOTBBT with (IMIN (\GETBASE DDWIDTHCACHE CHARCODE) (IDIFFERENCE RIGHT LEFT))) (freplace PBTSOURCEBIT of DDPILOTBBT with (\GETBASE DDOFFSETCACHE CHARCODE)) (\PILOTBITBLT DDPILOTBBT 0)) T]) (\TEDIT.CLOSEUPLINES [LAMBDA (TEXTOBJ PREVLINE NEXTLINE DONTFILLFLG) (* jds "31-Oct-84 12:08") (* Given a gap between PREVLINE and NEXTLINE, move NEXTLINE et seq up to coverthe gap, and adjust the YBOTs. If DONTFILLFLG is T then we're not filling the screen) (* PREVLINE = NIL => close it up to the top of the screen) (* NEXTLINE = NIL => remove all lower lines.) (SETQ PREVLINE (OR PREVLINE (fetch LINES of TEXTOBJ))) (PROG [DY (DS (fetch DS of TEXTOBJ)) (WWIDTH (IDIFFERENCE (fetch WRIGHT of TEXTOBJ) (fetch WLEFT of TEXTOBJ))) (LOWESTY (COND (PREVLINE (fetch YBOT of PREVLINE)) (T (ADD1 (fetch WTOP of TEXTOBJ] [COND (NEXTLINE (* If the gap isn't at the end, move whatever else up over it.) [SETQ DY (IDIFFERENCE LOWESTY (IPLUS (fetch YBOT of NEXTLINE) (fetch LHEIGHT of NEXTLINE] (AND (ILEQ DY 0) (RETURN)) (* If there's no gap, don't bother with anything else.) (BITBLT DS (fetch WLEFT of TEXTOBJ) (fetch WBOTTOM of TEXTOBJ) DS (fetch WLEFT of TEXTOBJ) (IPLUS DY (fetch WBOTTOM of TEXTOBJ)) WWIDTH (IPLUS (IDIFFERENCE (fetch YBOT of NEXTLINE) (fetch WBOTTOM of TEXTOBJ)) (fetch LHEIGHT of NEXTLINE)) (QUOTE INPUT) (QUOTE REPLACE)) (* Move the remaining lines upward.) (bind ((LINE ← NEXTLINE) (NYBOT ← LOWESTY)) while LINE do (* Scan the remaining lines, fixing up the vertical spacing information) (SETQ NYBOT (IDIFFERENCE NYBOT (fetch LHEIGHT of LINE))) (COND ((IGEQ NYBOT (fetch WBOTTOM of TEXTOBJ)) (SETQ LOWESTY NYBOT))) [COND [(ILESSP (fetch YBOT of LINE) (fetch WBOTTOM of TEXTOBJ)) (* Line is off screen. Display it at the right spot.) (AND DONTFILLFLG (RETURN)) (* If we're not filling the screen, then stop here.) (replace YBOT of LINE with NYBOT) (replace YBASE of LINE with (IPLUS NYBOT (fetch DESCENT of LINE))) (\DISPLAYLINE TEXTOBJ LINE) (COND ((fetch NEXTLINE of LINE) (* There's a next line after the current one. Use it) ) ((IGEQ (fetch CHARLIM of LINE) (fetch TEXTLEN of TEXTOBJ)) (* We're at the end of the text; don't bother trying to add more lines) ) (T (* There's more; try adding another line.) [replace NEXTLINE of LINE with (\FORMATLINE TEXTOBJ NIL (ADD1 (fetch CHARLIM of LINE] (replace PREVLINE of (fetch NEXTLINE of LINE) with LINE] (T (* Line is visible; just update YBOT/YBASE) (replace YBOT of LINE with NYBOT) (replace YBASE of LINE with (IPLUS (fetch YBOT of LINE) (fetch DESCENT of LINE] (SETQ LINE (fetch NEXTLINE of LINE)) until (ILESSP NYBOT (fetch WBOTTOM of TEXTOBJ] (BITBLT NIL 0 0 DS (fetch WLEFT of TEXTOBJ) (fetch WBOTTOM of TEXTOBJ) WWIDTH (IDIFFERENCE LOWESTY (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Clear the part of the screen below the lowest line now displayed) (RETURN T]) (\TEDIT.CREATE.LINECACHE [LAMBDA (#CACHES) (* jds "21-Apr-84 00:58") (* Create a linked-together set of LINECACHEs, for saving line images.) (PROG [(CACHES (for I from 1 to #CACHES collect (create LINECACHE LCBITMAP ←(BITMAPCREATE 100 15] [for CACHE on CACHES do (* Link the caches together.) (replace LCNEXTCACHE of (CAR CACHE) with (OR (CADR CACHE) (CAR CACHES] (RETURN CACHES]) (\TEDIT.FIXCHANGEDPART [LAMBDA (TEXTOBJ STARTINGLINE WINDOW) (* jds "29-Nov-84 07:10") (* Reformat lines as needed after a change. Return the last line changed, or NIL if there's no need for a \FILLWINDOW.) (PROG ([LINES (fetch NEXTLINE of (WINDOWPROP (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ)) (QUOTE LINES] (YBOT (fetch WTOP of TEXTOBJ)) (FORMATDONE NIL) LIMITCHANGED WASDIRTY CHARLIM OCHLIM OLHEIGHT (PREVLINE NIL) (FOUND NIL) (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (THISLINE (fetch THISLINE of TEXTOBJ)) (WHEIGHT (fetch WTOP of TEXTOBJ)) DY OFLOWFN NEWLINE) [COND (STARTINGLINE (* If we were handed a starting line, use it.) (COND ((ZEROP (fetch CHARLIM of STARTINGLINE)) (* This is the dummy first line. Skip it.) (replace DIRTY of STARTINGLINE with NIL) (SETQ LINES (fetch NEXTLINE of STARTINGLINE))) (T (* Normally, whatever line he says to start with, we start with) (SETQ LINES STARTINGLINE))) (SETQ YBOT (fetch YBOT of LINES))) (T (* Otherwise, go looking for work) [while LINES do (* Find the first line descriptor of a DIRTY line.) (SETQ YBOT (fetch YBOT of LINES)) (COND ((ILESSP 0 (SETQ DY (IDIFFERENCE (IDIFFERENCE (fetch YBOT of (fetch PREVLINE of LINES)) (fetch LHEIGHT of LINES)) YBOT))) (* There used to be another line above this one. Move this up to cover it.) (\TEDIT.ADJUST.LINES TEXTOBJ LINES (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ)) (IPLUS YBOT (fetch LHEIGHT of LINES)) DY))) (COND ((ILESSP YBOT (fetch WBOTTOM of TEXTOBJ)) (* We've run off the bottom of the screen.) (replace NEXTLINE of (fetch PREVLINE of LINES) with NIL) (* There may be unfixed changes there, so chop off any further lines.) (SETQ LINES NIL)) ((fetch DIRTY of LINES) (RETURN)) (T (SETQ LINES (fetch NEXTLINE of LINES] (COND ((AND LINES (ILESSP (fetch CHARTOP of LINES) 0)) (* If we hit on the dummy first line, skip over it -- never try to reformat it.) (SETQ LINES (fetch NEXTLINE of LINES] [COND ((NOT LINES) (* No changed lines found -- clear below last line on screen) (BITBLT NIL 0 0 WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WIDTH of (DSPCLIPPINGREGION NIL WINDOW)) (IDIFFERENCE YBOT (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (COND ([OR (ZEROP TEXTLEN) (NOT (fetch NEXTLINE of (fetch LINES of TEXTOBJ] (* If there is no text, or no image, force a call to \FILLWINDOW, to provide a dummy empty line descriptor for the guy to type at.) (RETURN (fetch LINES of TEXTOBJ))) (T (* We found no changes; return a NIL last-line-changed) (RETURN NIL] [SETQ YBOT (fetch YBOT of (SETQ PREVLINE (fetch PREVLINE of LINES] (* Y bottom of the first line to reformat.) (SETQ CHARLIM (fetch CHAR1 of LINES)) (* SUB1 of char to start formatting with) (while (AND LINES (IGEQ YBOT (fetch WBOTTOM of TEXTOBJ))) do (* Fix things up) (COND ([ILESSP 0 (SETQ DY (IDIFFERENCE (IDIFFERENCE YBOT (fetch LHEIGHT of LINES)) (fetch YBOT of LINES] (* There used to be another line above this one. Move this up to cover it.) (\TEDIT.ADJUST.LINES TEXTOBJ LINES (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ)) (IPLUS (fetch YBOT of LINES) (fetch LHEIGHT of LINES)) DY))) [COND ((IGREATERP CHARLIM (IMIN (IMAX 1 (fetch CHARLIM of LINES)) TEXTLEN)) (* This line has been rendered superfluous -- Delete it.) (TEDIT.DELETELINE LINES TEXTOBJ)) [[OR (fetch DIRTY of LINES) (NOT (IEQP CHARLIM (fetch CHAR1 of LINES] (* Only act if this line has changed, or if there is a gap or overlap between this line and the next.) (SETQ OCHLIM (fetch CHARLIM of LINES)) (* This line's old CHLIM, for seeing if it changes) (SETQ OLHEIGHT (fetch LHEIGHT of LINES)) (* This line's old height, for seeing if it changes.) (SETQ NEWLINE (\FORMATLINE TEXTOBJ NIL CHARLIM)) (* Create the fresh line) (COND ((AND (ILESSP (fetch CHAR1 of NEWLINE) (fetch CHAR1 of LINES)) (ILESSP (fetch CHARLIM of NEWLINE) (fetch CHARLIM of LINES))) (* There is a gap to be filled; insert the new line) (* NOTE: The fresh line is inserted only if it isn't likely to overlay the existing line. This minimizes hiccups and screen movement.) (replace YBASE of NEWLINE with (IDIFFERENCE YBOT (fetch ASCENT of NEWLINE))) (* Put it in place vertically) (replace YBOT of NEWLINE with (IDIFFERENCE YBOT (fetch LHEIGHT of NEWLINE))) (\TEDIT.INSERTLINE NEWLINE LINES) (* And insert it in the chain of line descriptors) ) (T (* The new line starts beyond where the old one started. Re-use the old line descriptor instead of splicing in the new one.) (freplace LEFTMARGIN of LINES with (ffetch LEFTMARGIN of NEWLINE)) (freplace RIGHTMARGIN of LINES with (ffetch RIGHTMARGIN of NEWLINE)) (freplace LXLIM of LINES with (ffetch LXLIM of NEWLINE)) (freplace SPACELEFT of LINES with (ffetch SPACELEFT of NEWLINE)) (freplace LHEIGHT of LINES with (ffetch LHEIGHT of NEWLINE)) (freplace CHAR1 of LINES with (ffetch CHAR1 of NEWLINE)) (freplace CHARLIM of LINES with (ffetch CHARLIM of NEWLINE)) (freplace CHARTOP of LINES with (ffetch CHARTOP of NEWLINE)) (freplace DIRTY of LINES with NIL) (freplace CR\END of LINES with (ffetch CR\END of NEWLINE)) (freplace LDOBJ of LINES with (ffetch LDOBJ of NEWLINE)) (freplace LHASPROT of LINES with (ffetch LHASPROT of NEWLINE)) (freplace LFMTSPEC of LINES with (ffetch LFMTSPEC of NEWLINE)) (freplace LTRUEASCENT of LINES with (ffetch LTRUEASCENT of NEWLINE)) (freplace LHASTABS of LINES with (ffetch LHASTABS of NEWLINE)) (replace DESC of THISLINE with LINES) (* And pretend that LINES is the line we just formatted--since it effectively IS.) (SETQ NEWLINE LINES) (* And copy it back over the original) )) (* Format a line, starting 1 past the end of the prior line) (SETQ CHARLIM (ADD1 (fetch CHARLIM of NEWLINE))) (* Find the end of the new line (this MUST be before this COND, because LINES is set to NIL inside it.)) (COND ((IGEQ (fetch YBOT of LINES) WHEIGHT) (* Do nothing until we see a change to a line which is on-screen.) (replace YBOT of NEWLINE with (fetch YBOT of LINES)) (* Except to make sure that the fresh line also thinks it is off screen) ) ((AND (IGEQ (SETQ YBOT (IDIFFERENCE YBOT (fetch LHEIGHT of NEWLINE))) (fetch WBOTTOM of TEXTOBJ)) (NEQ LINES NEWLINE)) (* If there's space left on the screen for this line, (and it is a new line)) (\TEDIT.ADJUST.LINES TEXTOBJ (fetch NEXTLINE of NEWLINE) WINDOW (fetch YBOT of (fetch PREVLINE of NEWLINE)) (IMINUS (fetch LHEIGHT of NEWLINE))) (* Move the existing lines down to fit it in) (replace YBOT of NEWLINE with YBOT) (* Display it where we are now) (replace YBASE of NEWLINE with (IPLUS YBOT (fetch DESCENT of NEWLINE))) (* Base line for the characters to sit on) (\DISPLAYLINE TEXTOBJ NEWLINE WINDOW) (* Display it) ) ((IGEQ YBOT (fetch WBOTTOM of TEXTOBJ)) (* If there's space left on the screen for this line, and we're overlaying an existing line.) (\TEDIT.ADJUST.LINES TEXTOBJ (fetch NEXTLINE of LINES) WINDOW (IPLUS YBOT (fetch LHEIGHT of LINES) (IMINUS OLHEIGHT)) (IDIFFERENCE OLHEIGHT (fetch LHEIGHT of LINES))) (* Adjust for the possible difference in heights between old and new line) (replace YBOT of LINES with YBOT) (* Display it where we are now) (replace YBASE of LINES with (IPLUS YBOT (fetch DESCENT of LINES))) (* Base line for the characters to sit on) (\DISPLAYLINE TEXTOBJ LINES WINDOW) (* Display it) ) (T (* We have walked off the bottom of the screen. Chop off the lines from here.) (SETQ LINES NEWLINE) (AND (SETQ OFLOWFN (TEXTPROP TEXTOBJ (QUOTE OVERFLOWFN))) (APPLY* OFLOWFN WINDOW TEXTOBJ) (RETFROM (QUOTE \TEDIT.FIXCHANGEDPART))) [replace YBOT of LINES with (replace YBASE of LINES with (SUB1 (fetch WBOTTOM of TEXTOBJ] (SETQ YBOT (IPLUS YBOT (fetch LHEIGHT of LINES))) (SETQ PREVLINE LINES) (replace NEXTLINE of PREVLINE with NIL) (SETQ LINES NIL) (RETURN))) (SETQ LINES NEWLINE) (* So that if we inserted a line, we start by moving up to the pre-existing line) (COND ((IGEQ CHARLIM TEXTLEN) (* We've run off the end of the text.) (SETQ PREVLINE LINES) (replace NEXTLINE of PREVLINE with NIL) (RETURN] (T (* Nothing to do on this line; move the counter up to the next line) (SETQ CHARLIM (ADD1 (fetch CHARLIM of LINES))) (SETQ YBOT (fetch YBOT of LINES] (SETQ PREVLINE LINES) (* Move to the next line) (SETQ LINES (fetch NEXTLINE of LINES))) (COND ((ILESSP YBOT (fetch WBOTTOM of TEXTOBJ)) (* If we made changes all the way to the bottom of the screen,) (COND (PREVLINE (replace NEXTLINE of PREVLINE with NIL) (BITBLT NIL 0 0 WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) (IDIFFERENCE (fetch YBOT of (fetch PREVLINE of PREVLINE)) (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE))) (* Discard any remaining lines below that, to force reformatting.) (RETURN) (* This prevents loss of changes which go past end of screen.) ) (T (* We didn't go off-screen, but we MAY have lost a line, so clear below the last thing we know of.) (BITBLT NIL 0 0 WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) (IDIFFERENCE YBOT (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (RETURN PREVLINE]) (\TEDIT.INSERTLINE [LAMBDA (NEWLINE BEFORELINE) (* jds "15-Mar-84 13:58") (* Inserts NEWLINE in front of BEFORELINE in the line-descriptor chain) (PROG ((PREVLINE (fetch PREVLINE of BEFORELINE))) (replace PREVLINE of NEWLINE with PREVLINE) (replace NEXTLINE of NEWLINE with BEFORELINE) (replace PREVLINE of BEFORELINE with NEWLINE) (AND PREVLINE (replace NEXTLINE of PREVLINE with NEWLINE]) (\TEDIT.LINECACHE [LAMBDA (CACHE WIDTH HEIGHT) (* jds "21-Apr-84 00:52") (* Given a candidate line cache, return the bitmap, making sure it's at least WIDTH by HEIGHT big.) (PROG ((BITMAP (fetch LCBITMAP of CACHE)) CW CH) (SETQ CW (fetch BITMAPWIDTH of BITMAP)) (SETQ CH (fetch BITMAPHEIGHT of BITMAP)) (COND ((AND (IGEQ CW WIDTH) (IGEQ CH HEIGHT)) (RETURN BITMAP)) (T (RETURN (replace LCBITMAP of CACHE with (BITMAPCREATE (IMAX CW WIDTH) (IMAX CH HEIGHT]) (\TEDIT.MARK.LINES.DIRTY [LAMBDA (TEXTOBJ CH1 CHLIM) (* jds "23-Apr-84 16:05") (* Mark dirty the lines that intersect the range ch1 t chlim inclusive) (bind (CH# ←(IMIN CH1 (fetch TEXTLEN of TEXTOBJ))) (CHLIM# ←(COND ((IEQP CHLIM -1) (fetch TEXTLEN of TEXTOBJ)) (T CHLIM))) for WW inside (fetch \WINDOW of TEXTOBJ) do (bind (LL ←(WINDOWPROP WW (QUOTE LINES))) while LL do (* Mark changed lines as DIRTY.) (COND ((AND (ILEQ (fetch CHAR1 of LL) CHLIM#) (IGEQ (fetch CHARLIM of LL) CH#)) (replace DIRTY of LL with T))) (SETQ LL (fetch NEXTLINE of LL]) (\TEDIT.PURGE.SPACES [LAMBDA (CHLIST PREVSP) (* jds " 9-NOV-83 17:12") (bind OPREVSP while (IGREATERP PREVSP 0) do (SETQ OPREVSP (SUB1 PREVSP)) (SETQ PREVSP (\EDITELT CHLIST OPREVSP)) (\EDITSETA CHLIST OPREVSP (CONSTANT (CHARCODE SPACE]) ) (PUTPROPS TEDITSCREEN COPYRIGHT ("John Sybalsky & Xerox Corporation" 1983 1984)) (DECLARE: DONTCOPY (FILEMAP (NIL (6192 125497 (TEDIT.CR.UPDATESCREEN 6202 . 8094) (TEDIT.DELETELINE 8096 . 8849) ( TEDIT.INSERT.DISPLAYTEXT 8851 . 15017) (TEDIT.INSERT.UPDATESCREEN 15019 . 28698) (TEDIT.UPDATE.SCREEN 28700 . 29275) (\BACKFORMAT 29277 . 30946) (\DISPLAYLINE 30948 . 40161) (\DOFORMATTING 40163 . 45272) (\FILLWINDOW 45274 . 52472) (\FIXDLINES 52474 . 56392) (\FIXILINES 56394 . 59434) (\FORMATLINE 59436 . 80274) (\PULLTEXT 80276 . 86139) (\PUSHTEXT 86141 . 95205) (\SHOWTEXT 95207 . 97049) ( \TEDIT.ADJUST.LINES 97051 . 101669) (\TEDIT.BLTCHAR 101671 . 103460) (\TEDIT.CLOSEUPLINES 103462 . 107786) (\TEDIT.CREATE.LINECACHE 107788 . 108449) (\TEDIT.FIXCHANGEDPART 108451 . 122976) ( \TEDIT.INSERTLINE 122978 . 123590) (\TEDIT.LINECACHE 123592 . 124278) (\TEDIT.MARK.LINES.DIRTY 124280 . 125182) (\TEDIT.PURGE.SPACES 125184 . 125495))))) STOP