(FILECREATED "25-Sep-86 23:20:47" {ERIS}<TEDIT>TEDITSCREEN.;39 126812 changes to: (VARS TEDITSCREENCOMS) previous date: "24-Sep-86 03:05:27" {ERIS}<TEDIT>TEDITSCREEN.;38) (* " Copyright (c) 1983, 1984, 1985, 1986 by John Sybalsky & Xerox Corporation. All rights reserved. ") (PRETTYCOMPRINT TEDITSCREENCOMS) (RPAQQ TEDITSCREENCOMS ((FILES TEDITDECLS) (FNS TEDIT.CR.UPDATESCREEN TEDIT.DELETELINE TEDIT.INSERT.DISPLAYTEXT TEDIT.INSERT.UPDATESCREEN TEDIT.UPDATE.SCREEN \BACKFORMAT \DISPLAYLINE \DOFORMATTING \FILLWINDOW \FIXDLINES \FIXILINES \FORMATLINE \SHOWTEXT \TEDIT.ADJUST.LINES \TEDIT.BLTCHAR \TEDIT.CLEAR.SCREEN.BELOW.LINE \TEDIT.CLOSEUPLINES \TEDIT.COPY.LINEDESCRIPTOR \TEDIT.CREATE.LINECACHE \TEDIT.FIXCHANGEDLINE \TEDIT.FIXCHANGEDPART \TEDIT.INSERTLINE \TEDIT.LINE.LIST \TEDIT.LINECACHE \TEDIT.MARK.LINES.DIRTY \TEDIT.NEXT.LINE.BOTTOM \TEDIT.PURGE.SPACES))) (FILESLOAD TEDITDECLS) (DEFINEQ (TEDIT.CR.UPDATESCREEN [LAMBDA (CH# XPOINT TEXTOBJ SEL LINE BLANKSEEN CRSEEN DS CHWIDTH DONTSCROLL) (* jds " 9-Feb-86 15:24") (* 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.) (HELP) (* (PROG ((WINDOW (fetch \WINDOW of TEXTOBJ)) (PREVLINE (fetch PREVLINE of LINE))) (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) (replace TXTNEEDSUPDATE of TEXTOBJ with T))) (TEDIT.UPDATE.SCREEN TEXTOBJ PREVLINE T) (\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 WINDOW) (* jds " 8-Feb-85 18:26") (* 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 NIL WINDOW) (* And fix up the screen to cover the blank space.) ]) (TEDIT.INSERT.DISPLAYTEXT [LAMBDA (TEXTOBJ CH CHWIDTH LINE XPOINT DS SEL) (* jds " 9-Feb-86 15:26") (* This function does the actual displaying of typed-in text on the edit window.) (HELP) (* (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) (* Change the font) (COND ((IGREATERP (FONTPROP (fetch CLFONT of LOOKS) (QUOTE ASCENT)) (fetch LTRUEASCENT of LINE)) (* The font this character is in is taller than the existing line. Adjust the LINEDESCRIPTOR's ascent.) (\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)))) (* Move other text to allow for the new height) (add (fetch (LINEDESCRIPTOR ASCENT) of LINE) (IDIFFERENCE (FONTPROP (fetch CLFONT of LOOKS) (QUOTE ASCENT)) (fetch LTRUEASCENT of LINE))) (replace (LINEDESCRIPTOR LTRUEASCENT) of LINE with (FONTPROP (fetch CLFONT of LOOKS) (QUOTE ASCENT))))) (COND ((IGREATERP (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT)) (fetch LTRUEDESCENT 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 LTRUEDESCENT of LINE) (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT)))) (add (fetch (LINEDESCRIPTOR DESCENT) of LINE) (IDIFFERENCE (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT)) (fetch LTRUEDESCENT of LINE))) (* Fix the line's leading-adjusted descent to account for this change) (replace LTRUEDESCENT of LINE with (FONTPROP (fetch CLFONT of LOOKS) (QUOTE DESCENT))) (* Also the unadjusted descent) (replace YBOT of LINE with (IDIFFERENCE (fetch YBASE of LINE) (fetch DESCENT of LINE))) (* And note our new location.))) (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 OTEXTLEN BLANKSEEN CRSEEN DONTSCROLL INCREMENTAL) (* jds "24-Sep-86 01:13") (* Update the edit window after an insertion) (PROG ((THISLINE (fetch THISLINE of TEXTOBJ)) (WINDOW (fetch \WINDOW of TEXTOBJ)) 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 ((AND INCREMENTAL (\SYSBUFP)) (* We're doing incremental updates, and there's type-in waiting. Bail out, now that we have fixed up the selection.) (RETURN)) ((fetch TXTDON'TUPDATE of TEXTOBJ) (* ; "Don't update the screen if updates are being inhibited.") (RETURN)) ((NOT WINDOW) (* If this textobj has no window to update, don't bother) (RETURN)) ((OR T (LISTP WINDOW) (TEXTPROP TEXTOBJ (QUOTE SLOWUPDATE))) (* FOR NOW, ALWAYS UPDATE THE SCREEN THE HARD WAY) (TEDIT.UPDATE.SCREEN TEXTOBJ NIL T (fetch CH# of SEL)) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T))) (\COPYSEL SEL TEDIT.SELECTION) [for WW inside WINDOW as L1 inside (fetch L1 of SEL) as LN inside (fetch LN of SEL) as L1LIST on (fetch L1 of SEL) as LNLIST on (fetch LN of SEL) do (COND (DONTSCROLL (* If scrolling is suppressed, don't bother with the next check:) (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WW)) [(EQ WW (fetch SELWINDOW of TEXTOBJ)) (COND ([OR (NULL (SELECTQ (fetch POINT of SEL) (LEFT L1) (RIGHT LN) NIL)) (ILEQ (SELECTQ (fetch POINT of SEL) (LEFT (fetch YBOT of L1)) (RIGHT (fetch YBOT of LN)) 0) (fetch BOTTOM of (DSPCLIPPINGREGION NIL WW] (* The caret is off-window in the selection window. Need to scroll it up so the caret is visible.) (while (OR [COND ((SETQ SELINE (SELECTQ (fetch POINT of SEL) (LEFT (CAR L1LIST)) (RIGHT (CAR LNLIST)) NIL)) (ILESSP (fetch YBOT of SELINE) (fetch WBOTTOM of TEXTOBJ))) (T (ILESSP (fetch Y0 of SEL) (fetch WBOTTOM of TEXTOBJ] (AND (IGEQ (fetch Y0 of SEL) (fetch WTOP of TEXTOBJ)) (NULL SELINE))) do (* The caret just went off-screen. Move it up some.) (replace EDITOPACTIVE of TEXTOBJ with NIL) (SCROLLW WW 0 (LLSH (COND [(SELECTQ (fetch POINT of SEL) (LEFT (CAR L1LIST)) (RIGHT (CAR LNLIST)) NIL) (fetch LHEIGHT of (SELECTQ (fetch POINT of SEL) (LEFT (CAR L1LIST)) (RIGHT (CAR LNLIST)) (SHOULDNT] (T 12)) 1] (T (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WW] (\COPYSEL SEL TEDIT.SELECTION]) (TEDIT.UPDATE.SCREEN [LAMBDA (TEXTOBJ STARTINGLINE INCREMENTAL? NEXTCARETCH#) (* jds "24-Sep-86 01:21") (* Update the screen, as needed to fix up "dirty" lines.) (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ)) (COND ((NOT (fetch TXTDON'TUPDATE of TEXTOBJ)) (* ; "Only update the screen if we aren't suppressing updating.") (bind NLINE for WW inside (fetch \WINDOW of TEXTOBJ) as LINE inside (OR STARTINGLINE (fetch LINES of TEXTOBJ)) do (SETQ NLINE (\TEDIT.FIXCHANGEDPART TEXTOBJ LINE WW INCREMENTAL? NEXTCARETCH#)) (* The last line in the edit window) (AND NLINE (\FILLWINDOW (fetch YBOT of NLINE) NLINE TEXTOBJ NIL WW NEXTCARETCH#]) (\BACKFORMAT [LAMBDA (LINES TEXTOBJ WHEIGHT) (* jds " 7-May-85 00:48") (* Move back to the next preceding CR (to guarantee a line break), then format lines to reach where we are now.) (* LINES is the dummy first line for this window in TEXTOBJ) (* Returns a pointer to the last of the back-formatted lines (i.e., the one that comes latest in the document), or to LINES if no lines are formatted) (PROG ((LINE1 (fetch NEXTLINE of LINES)) 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 (* Back up until we find a CR) (SETQ CH (\GETCHB TEXTOBJ)) (COND ((EQ CH (CHARCODE CR)) (RETURN] (SETQ CHNO (IMAX (ADD1 CHNO) 1)) (* But never further than the front of the document) (while (ILEQ CHNO (SUB1 CH1)) do (* Now move forward, formatting lines until we catch up with where we were.) (SETQ NLINE (\FORMATLINE TEXTOBJ NIL CHNO)) (* Format the next line) (replace YBOT of NLINE with WHEIGHT) (* Make sure it thinks it's off-window) (replace YBASE of NLINE with WHEIGHT) (replace PREVLINE of NLINE with LINES) (* Hook it onto the end of the chain) (replace NEXTLINE of LINES with NLINE) (SETQ LINES NLINE) (SETQ CHNO (ADD1 (fetch CHARLIM of NLINE))) (* And find the start of the next line)) (replace NEXTLINE of NLINE with LINE1) (* Now, with the final line we formatted, hook the rest of the line chain onto it.) (AND LINE1 (replace PREVLINE of LINE1 with NLINE)) (RETURN NLINE]) (\DISPLAYLINE [LAMBDA (TEXTOBJ LINE WINDOW) (* jds "23-Oct-85 12:19") (* Display the line of text LINE in the edit window where it belongs.) (PROG ((CH 0) (CHLIST (fetch (THISLINE CHARS) of (fetch THISLINE of TEXTOBJ))) (WLIST (fetch (THISLINE WIDTHS) of (fetch THISLINE of TEXTOBJ))) (LOOKS (fetch (THISLINE LOOKS) of (fetch THISLINE of TEXTOBJ))) (WINDOWDS (WINDOWPROP (OR WINDOW (CAR (fetch (TEXTOBJ \WINDOW) of TEXTOBJ))) (QUOTE DSP))) (TEXTLEN (fetch (TEXTOBJ TEXTLEN) of TEXTOBJ)) (THISLINE (fetch (TEXTOBJ THISLINE) of TEXTOBJ)) (TERMSA (fetch (TEXTOBJ TXTTERMSA) of TEXTOBJ)) (STREAM (fetch (TEXTOBJ STREAMHINT) of TEXTOBJ)) (OLDCACHE (fetch LCBITMAP of (fetch (TEXTOBJ DISPLAYCACHE) of TEXTOBJ))) (DS (fetch (TEXTOBJ DISPLAYCACHEDS) of TEXTOBJ)) (HCPYDS (fetch (TEXTOBJ DISPLAYHCPYDS) of TEXTOBJ)) (HARDCOPYMODE (fetch (FMTSPEC FMTHARDCOPY) of (fetch (LINEDESCRIPTOR LFMTSPEC) of LINE))) LOOKSTARTX CACHE \PCHARSLEFT \PSTRING \PFILE FONT OFONT OLOOKS XOFFSET CLIPLEFT CLIPRIGHT DISPLAYDATA DDPILOTBBT DDWIDTHCACHE DDOFFSETCACHE CURY LHEIGHT SCALE) [SETQ LHEIGHT (COND ((fetch (LINEDESCRIPTOR PREVLINE) of LINE) (* So if theres a base-to-base measure, we clear everything right.) (IMAX (IDIFFERENCE (fetch YBOT of (fetch (LINEDESCRIPTOR PREVLINE) of LINE)) (fetch (LINEDESCRIPTOR YBOT) of LINE)) (fetch (LINEDESCRIPTOR LHEIGHT) of LINE))) (T (fetch (LINEDESCRIPTOR LHEIGHT) of LINE] (COND (HARDCOPYMODE (* This is a hardcopy-mode line. Scale things.) (* (SETQ DS HCPYDS)) (SETQ SCALE (DSPSCALE NIL HCPYDS))) (T (SETQ SCALE 1))) (SETQ CACHE (\TEDIT.LINECACHE (fetch (TEXTOBJ DISPLAYCACHE) of TEXTOBJ) (COND (HARDCOPYMODE (FIXR (FQUOTIENT (fetch RIGHTMARGIN of LINE) SCALE))) (T (fetch RIGHTMARGIN of LINE))) LHEIGHT)) (COND ((NEQ CACHE OLDCACHE) (* We changed the bitmaps because this line was bigger--update the displaystream, too) (DSPDESTINATION CACHE DS) (DSPCLIPPINGREGION (create REGION LEFT ← 0 BOTTOM ← 0 WIDTH ←(fetch BITMAPWIDTH of CACHE) HEIGHT ←(fetch BITMAPHEIGHT of CACHE)) DS))) (BITBLT NIL 0 0 CACHE 0 0 NIL NIL (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE) (* Clear the line cache) (COND (HARDCOPYMODE (* This is a hardcopy-mode line. Scale things.) (* (SETQ DS HCPYDS)) (SETQ SCALE (DSPSCALE NIL HCPYDS))) (T (SETQ SCALE 1))) [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) (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)) (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 (FIXR (FTIMES SCALE (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) (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) ) [(CHARCODE (TAB #↑I)) (* TAB: use the width from the cache to decide the right formatting.) (COND ((OR (IEQP CH (CHARCODE #↑I)) (fetch CLLEADER of OLOOKS) (EQ (fetch CLUSERINFO of OLOOKS) (QUOTE DOTTEDLEADER))) (LET* [[LEADERFONT (COND (HARDCOPYMODE (FONTCOPY (fetch CLFONT of OLOOKS) (QUOTE DEVICE) HCPYDS)) (T (fetch CLFONT of OLOOKS] (DOTWIDTH (CHARWIDTH (CHARCODE %.) LEADERFONT)) (TTX (IPLUS TX DOTWIDTH (IDIFFERENCE DOTWIDTH (IREMAINDER TX DOTWIDTH] (while (ILEQ TTX (IPLUS TX DX)) do (COND (HARDCOPYMODE (\TEDIT.BLTCHAR (CHARCODE %.) DS (FIXR (FQUOTIENT (IDIFFERENCE TTX DOTWIDTH) SCALE)) DISPLAYDATA DDPILOTBBT CLIPRIGHT)) ((OR TERMSA HARDCOPYMODE) (* Using special instrns from TERMSA) (\DSPPRINTCHAR DS (CHARCODE %.))) (T (* Native charcodes) (\TEDIT.BLTCHAR (CHARCODE %.) DS (IDIFFERENCE TTX DOTWIDTH) DISPLAYDATA DDPILOTBBT CLIPRIGHT))) (add TTX DOTWIDTH] (13 (* It's a CR) NIL) (COND [(SMALLP CH) (* Normal character -- just display it.) (COND (HARDCOPYMODE (\TEDIT.BLTCHAR CH DS (FIXR (FQUOTIENT TX SCALE)) DISPLAYDATA DDPILOTBBT CLIPRIGHT)) ((OR TERMSA HARDCOPYMODE) (* Using special instrns from TERMSA) (\DSPPRINTCHAR DS CH)) (T (* Native charcodes) (\TEDIT.BLTCHAR CH DS TX DISPLAYDATA DDPILOTBBT CLIPRIGHT] (T (* CH is an object.) (MOVETO (IDIFFERENCE (FIXR (FQUOTIENT TX SCALE)) 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 (FIXR (FQUOTIENT TX SCALE)) XOFFSET) CURY DS) (* Move to after the object's image) ] (add TX DX) (* Update our X position) finally (replace DDXPOSITION of DISPLAYDATA with (IDIFFERENCE (FIXR (FQUOTIENT TX SCALE)) 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) LHEIGHT (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) 6 6 (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) 6 6 (QUOTE TEXTURE) (QUOTE PAINT) BLACKSHADE)) (BITBLT NIL 0 0 WINDOWDS 0 (fetch YBASE of LINE) 6 6 (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE]) (\DOFORMATTING [LAMBDA (TEXTOBJ LINE FMTSPEC THISLINE #BLANKS PREVSP 1STLN) (* jds "20-Mar-86 17:22") (* Do the formatting work for justified, centered, etc. lines) (PROG ((QUAD (fetch QUAD of FMTSPEC)) (SPACELEFT (LLSH (fetch SPACELEFT of LINE) 5)) (EXISTINGSPACE 0) (CHLIST (fetch (THISLINE CHARS) of THISLINE)) (WLIST (fetch (THISLINE WIDTHS) of THISLINE)) (SPACEOFLOW 0) EXTRASP OPREVSP LINELEAD) (* NB that SPACELEFT, OFLOW, etc. are kept in 32 x value form, for rounding ease.) (replace LTRUEDESCENT of LINE with (fetch DESCENT of LINE)) (replace LTRUEASCENT of LINE with (fetch ASCENT of LINE)) (* Save the true ascent value for display purposes) (replace (THISLINE TLSPACEFACTOR) of THISLINE with 1) (* Start by assuming that we want a space factor of 1.0) [COND ((SETQ LINELEAD (fetch LINELEAD of FMTSPEC)) (* If line leading was specified, set it) (COND (T (add (fetch LHEIGHT of LINE) (fetch LINELEAD of FMTSPEC)) (* And adjust the line's descent accordingly) (add (fetch DESCENT of LINE) (fetch LINELEAD of FMTSPEC] [COND ((AND 1STLN (fetch LEADBEFORE of FMTSPEC)) (* If paragraph pre-leading was specified, set it) (add (fetch LHEIGHT of LINE) (fetch LEADBEFORE of FMTSPEC)) (* And adjust the line's ascent accordingly.) (add (fetch ASCENT of LINE) (fetch LEADBEFORE of FMTSPEC] [COND ((AND (fetch LSTLN of LINE) (fetch LEADAFTER of FMTSPEC)) (* If paragraph pre-leading was specified, set it) (add (fetch LHEIGHT of LINE) (fetch LEADAFTER of FMTSPEC)) (* And adjust the line's ascent accordingly.) (add (fetch DESCENT of LINE) (fetch LEADAFTER 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 (ILESSP (fetch LEN of THISLINE) 0) (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 (ILESSP (fetch LEN of THISLINE) 0) (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 (ILESSP (fetch LEN of THISLINE) 0) (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)) ((IEQP PREVSP (ADD1 (fetch LEN of THISLINE))) (* Only if the last character on the line is a space should we remove trailing spaces from the list) (bind (OPREVSP ←(SUB1 PREVSP)) while (AND (IGREATERP PREVSP 0) (ILEQ OPREVSP PREVSP)) do (* Back up over all trailing white space on the line. So that those blanks don't get counted when computing the space to be added to each REAL space on the line, when it is justified.) (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.) ) (T (SETQ EXTRASP 0))) [while (IGREATERP PREVSP 0) do (* Fix up the widths of spaces in the line) (SETQ OPREVSP (SUB1 PREVSP)) (SETQ PREVSP (\EDITELT CHLIST OPREVSP)) (add EXISTINGSPACE (\WORDELT WLIST 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] (COND ((NOT (ZEROP EXTRASP)) (* Only if we really expanded the line --) (replace (THISLINE TLSPACEFACTOR) of THISLINE with (FQUOTIENT (IPLUS EXISTINGSPACE (fetch (LINEDESCRIPTOR SPACELEFT ) of LINE)) EXISTINGSPACE)) (* And set the space factor for display) )) (RETURN)) NIL) (\TEDIT.PURGE.SPACES CHLIST PREVSP) (* Change all the spaces--chained for justification--back into regular spaces, for the display code.) ]) (\FILLWINDOW [LAMBDA (YBOT CURLINE TEXTOBJ DONTFILLFLG WINDOW NEXTCARETCH#) (* jds " 5-Oct-85 11:50") (* 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.) (* NEXTCARETCH# => always format to at least this CH#, to assure that we know where the caret will next be.) (PROG* ((LINE (fetch NEXTLINE of CURLINE)) (CHARLIM (fetch CHARLIM of CURLINE)) (PREVLINE CURLINE) (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (LINES\DELETED NIL) (WINDOW (OR WINDOW (fetch \WINDOW of TEXTOBJ))) (WHEIGHT (WINDOWPROP WINDOW (QUOTE HEIGHT))) NEXTLINE OFLOWFN) (replace TXTNEEDSUPDATE of TEXTOBJ with NIL) (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 (\TEDIT.NEXT.LINE.BOTTOM YBOT LINE PREVLINE)) (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)) [(AND LINE NEXTCARETCH# (ILEQ (fetch CHAR1 of LINE) NEXTCARETCH#)) (* There's a line, and it's earlier than the next caret location. Keep going.) (replace YBOT of LINE with YBOT) (replace YBASE of LINE with (IPLUS YBOT (fetch DESCENT of LINE] (LINE (* There is a line, but it won't fit.) [COND ((fetch FMTBASETOBASE of (fetch LFMTSPEC of LINE)) (SETQ YBOT (fetch YBOT of PREVLINE))) (T (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 [COND [(fetch FMTBASETOBASE of (fetch LFMTSPEC of LINE)) (SETQ YBOT (IDIFFERENCE (IPLUS YBOT (fetch DESCENT of PREVLINE)) (IPLUS (fetch FMTBASETOBASE of (fetch LFMTSPEC of LINE)) (fetch DESCENT of LINE] (T (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)) [(AND NEXTCARETCH# (ILEQ (fetch CHAR1 of LINE) NEXTCARETCH#)) (* This line is needed to find the next caret location, even tho it won't fit on the screen) (replace YBOT of LINE with YBOT) (replace YBASE of LINE with (IPLUS YBOT (fetch DESCENT of LINE] (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)) (* 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 "21-Sep-85 09:20") (* 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 (WINDOWPROP WW (QUOTE LINES))) (PROG ((NLINES LINES) (DCH (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) (replace TXTNEEDSUPDATE of TEXTOBJ 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) (replace TXTNEEDSUPDATE of TEXTOBJ with T] ((IGEQ 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) (IGEQ 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 TXTNEEDSUPDATE of TEXTOBJ with T) (replace CHAR1 of LINE with (IMAX 1 (IMIN CHAR1 CH#1))) (COND [(IGEQ CHARLIM CH#LIM) (replace CHARLIM of LINE with (IDIFFERENCE CHARLIM (IMIN DCH (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.) (AND NL (replace DIRTY of NL with T)) (* This may well force a reformatting of the next line. Mark it dirty just in case.) )) (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) (* jds "19-Jan-85 16:51") (* 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.) [for WW inside (ffetch \WINDOW of TEXTOBJ) as LINES inside (fetch LINES of TEXTOBJ) as L1 in (fetch L1 of SEL) do (* For each pane in the editing window, examine the pane's list of 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 L1)) (* 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) (replace TXTNEEDSUPDATE of TEXTOBJ with T)) ((IGEQ (ffetch CHARTOP of LINE) CH#1) (* This line spans the insert point. Mark it DIRTY.) (freplace DIRTY of LINE with T) (replace TXTNEEDSUPDATE of TEXTOBJ 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) (replace TXTNEEDSUPDATE of TEXTOBJ 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 "17-Oct-85 11:57") (* 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.) (DECLARE (SPECVARS LOOKS CHLIST WLIST FONTWIDTHS CHNO ASCENT DESCENT LOOKNO LINE FONT INVISIBLERUNS DEVICE SCALE NEWASCENT NEWDESCENT)) (PROG ([LINE (OR OLINE (create LINEDESCRIPTOR RIGHTMARGIN ←(fetch WRIGHT of TEXTOBJ) YBOT ←(SUB1 (fetch WBOTTOM of TEXTOBJ] (CH#B CH#1) (GATHERBLANK T) (TLEN 0) (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (THISLINE (ffetch THISLINE of TEXTOBJ)) (CHNO CH#1) (LOOKNO 0) (INVISIBLERUNS 0) (ASCENT 0) (DESCENT 0) (PREVSP 0) (#BLANKS 0) (DEFAULTTAB 36) (DS (WINDOWPROP (CAR (fetch \WINDOW of TEXTOBJ)) (QUOTE DSP))) LEFTEDGE TX DX TXB CH FORCEEND T1SPACE TXB1 DXB WIDTH LOOK#B FONT FONTWIDTHS TERMSA CLOOKS TEXTSTREAM CHLIST WLIST LOOKS ASCENTB DESCENTB INVISIBLERUNSB TABPENDING BOX PC PCNO DEVICE SCALE NEWASCENT NEWDESCENT TABSPEC HARDCOPYMODE ORIGFMTSPEC) (* * 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 (THISLINE 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 (FUNCTION \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 LMInvisibleRun) (\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))) (AND PC (SETQ CLOOKS (\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)) (AND PC (SETQ CLOOKS (\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))) (replace LHASPROT of LINE with (fetch CLPROTECTED of CLOOKS)) (* Remember if the first character on the line is protected.) [SETQ ORIGFMTSPEC (OR FMTSPEC (SETQ FMTSPEC (OR (fetch PPARALOOKS of (fetch (TEXTSTREAM PIECE) of TEXTSTREAM)) (fetch FMTSPEC of TEXTOBJ] (* Get the paragraph looks) (COND [(SETQ HARDCOPYMODE (fetch FMTHARDCOPY of FMTSPEC)) (* This line is a hardcopy line. Scale things for it.) [SETQ DEVICE (OR (fetch DISPLAYHCPYDS of TEXTOBJ) (replace DISPLAYHCPYDS of TEXTOBJ with (OPENIMAGESTREAM (QUOTE {NODIRCORE}) (QUOTE INTERPRESS] (SETQ SCALE (DSPSCALE NIL DEVICE)) (SETQ FMTSPEC (\TEDIT.HCPYFMTSPEC FMTSPEC DEVICE)) (SETQ DEFAULTTAB (FIXR (FTIMES 36 SCALE))) (SETQ LEFTEDGE (FIXR (FTIMES 8 SCALE] (T (* Regular line. Format at display resolutions) (SETQ DEVICE (fetch DISPLAYCACHEDS of TEXTOBJ)) (SETQ SCALE 1) (SETQ LEFTEDGE 8))) (SETQ TABSPEC (fetch TABSPEC of FMTSPEC)) [COND ((type? FONTCLASS (SETQ FONT (fetch CLFONT of CLOOKS))) (SETQ FONT (FONTCOPY (fetch CLFONT of CLOOKS) (QUOTE DEVICE) (QUOTE DISPLAY] (* Grab the initial font for this line) [SETQ ASCENTB (SETQ NEWASCENT (IPLUS (fetch \SFAscent of FONT) (OR (fetch CLOFFSET of CLOOKS) 0] (* The initial ascent, per the initial font) [SETQ DESCENTB (SETQ NEWDESCENT (IDIFFERENCE (fetch \SFDescent of FONT) (OR (fetch CLOFFSET of CLOOKS) 0] (* Initial descent, per the initial font.) [COND (HARDCOPYMODE (* If this is a hardcopy line, fetch the hardcopy version of the font) (SETQ FONT (FONTCOPY (fetch CLFONT of CLOOKS) (QUOTE DEVICE) DEVICE] (\EDITSETA LOOKS 0 CLOOKS) (* Save looks in the line cache) [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] (* If this is the start of a paragraph, mark it so.) (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 [FIXR (FTIMES SCALE (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 LEFTEDGE (fetch RIGHTMAR of FMTSPEC))) (T (FIXR (FTIMES SCALE (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) (\FGETCHARWIDTH FONT CH)) (T (* CH is an object) (SETQ BOX (APPLY* (IMAGEOBJPROP CH (QUOTE IMAGEBOXFN)) CH DS TX WIDTH)) (* Get its size) (SETQ NEWASCENT (IDIFFERENCE (fetch YSIZE of BOX) (fetch YDESC of BOX))) (SETQ NEWDESCENT (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) )) (COND [HARDCOPYMODE (FIXR (FTIMES SCALE (fetch XSIZE of BOX] (T (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) (COND (NEWASCENT (* The ascent has changed; catch it) (SETQ ASCENT (IMAX ASCENT NEWASCENT)) (SETQ DESCENT (IMAX DESCENT NEWDESCENT)) (SETQ NEWASCENT NIL))) (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) (COND ((AND NEWASCENT (ZEROP ASCENT) (ZEROP DESCENT)) (* The ascent has changed; catch it) (SETQ ASCENT NEWASCENT) (SETQ DESCENT NEWDESCENT))) (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) (COND (NEWASCENT (* The ascent has changed; catch it) (SETQ ASCENT (IMAX ASCENT NEWASCENT)) (SETQ DESCENT (IMAX DESCENT NEWDESCENT)) (SETQ NEWASCENT NIL))) (\RPLPTR CHLIST 0 CH) (SETQ TABPENDING (\TEDIT.FORMATTABS TEXTOBJ TABSPEC THISLINE CHLIST WLIST TX DEFAULTTAB LEFTEDGE TABPENDING NIL) ) (* 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)) (\TEDIT.PURGE.SPACES (fetch CHARS of THISLINE) PREVSP) (* All the spaces before a tab don't take part in justification from here on.) (SETQ #BLANKS 0) (* Also reset the count of spaces on this line, so we widen later spaces enough.) (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 ((AND (SMALLP CH) (IGEQ CH 192) (ILEQ CH 207)) (* This is an NS accent character. Space it 0.0) (SETQ DX 0))) (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) (COND (NEWASCENT (* The ascent has changed; catch it) (SETQ ASCENT (IMAX ASCENT NEWASCENT)) (SETQ DESCENT (IMAX DESCENT NEWDESCENT)) (SETQ NEWASCENT NIL] (RETURN)) (T (* Not past the rightmargin yet...) (COND (NEWASCENT (* The ascent has changed; catch it) (SETQ ASCENT (IMAX ASCENT NEWASCENT)) (SETQ DESCENT (IMAX DESCENT NEWDESCENT)) (SETQ NEWASCENT NIL))) (\RPLPTR CHLIST 0 CH) (\PUTBASE WLIST 0 DX) (* Check for decimal tabs) (COND ((AND (SMALLP CH) (EQ CH (CHARCODE %.)) TABPENDING (NOT (FIXP TABPENDING)) (EQ (fetch PTTYPE of TABPENDING) (QUOTE DECIMAL))) (* Figure out which tab stop to use, and what we need to do to get there.) (SETQ TABPENDING (\TEDIT.FORMATTABS TEXTOBJ TABSPEC THISLINE CHLIST WLIST TX DEFAULTTAB LEFTEDGE TABPENDING T)) [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) (\TEDIT.PURGE.SPACES (fetch CHARS of THISLINE) PREVSP) (* All the spaces before a tab don't take part in justification from here on.) (SETQ #BLANKS 0) (* Also reset the count of spaces on this line, so we widen later spaces enough.) (SETQ PREVSP 0) (SETQ T1SPACE T) (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] (SETQ CHLIST (\ADDBASE CHLIST 2)) (* Move the pointers forward for the next character.) (SETQ WLIST (\ADDBASE WLIST 1))) (* End of char loop) (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 TABSPEC THISLINE CHLIST WLIST TX DEFAULTTAB LEFTEDGE TABPENDING T)) (* Finish up processing the outstanding TAB. We get back the new X position, with that taken into account.) (SETQ TX TABPENDING) (SETQ TABPENDING NIL) (\TEDIT.PURGE.SPACES (fetch CHARS of THISLINE) PREVSP) (* Don't use the spaces before the TAB in justification.) (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) (\EDITSETA LOOKS 0 CLOOKS) (* Set up the initial looks so that \DISPLAYLINE doesn't complain) (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 (OR ORIGFMTSPEC FMTSPEC) THISLINE #BLANKS PREVSP 1STLN) (replace LFMTSPEC of LINE with FMTSPEC) (replace LOOKSUPDATEFN of TEXTSTREAM with NIL) (RETURN LINE]) (\SHOWTEXT [LAMBDA (TEXTOBJ LINES WINDOW) (* jds "14-Jun-85 09:57") (* 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 [PROG1 (DSPCLIPPINGREGION NIL WINDOW) (* For region within a window:) (* (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 ←(WINDOWPROP WINDOW (QUOTE HEIGHT)) 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 LFMTSPEC ← TEDIT.DEFAULT.FMTSPEC)) (* Make sure we have the anchor pseudo-line) (WINDOWPROP WINDOW (QUOTE LINES) LINES) (\FILLWINDOW (WINDOWPROP WINDOW (QUOTE HEIGHT)) 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) (* jds "17-May-85 15:19") (* 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 ((ZEROP DY) (* This line's total height HAS NOT CHANGED. Don't make any adjustments.) ) ((ILESSP LINETOP (fetch WBOTTOM of TEXTOBJ)) (* This line is off the screen. Don't bother adjusting it.) ) (FIRSTLINE (* 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 CURX DISPLAYDATA DDPILOTBBT CLIPRIGHT) (* jds " 9-Jan-86 17:14") (* 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 IMAGEWIDTH (CHAR8CODE (\CHAR8CODE CHARCODE))) [COND ((NEQ (ffetch DDCHARSET of DISPLAYDATA) (\CHARSET CHARCODE)) (\CHANGECHARSET.DISPLAY DISPLAYDATA (\CHARSET CHARCODE] (SETQ IMAGEWIDTH (\GETBASE (fetch DDCHARIMAGEWIDTHS of DISPLAYDATA) (\CHAR8CODE CHARCODE))) (SETQ NEWX (IPLUS CURX IMAGEWIDTH)) (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 IMAGEWIDTH (IDIFFERENCE RIGHT LEFT))) (freplace PBTSOURCEBIT of DDPILOTBBT with (\GETBASE (fetch DDOFFSETSCACHE of DISPLAYDATA) (\CHAR8CODE CHARCODE)) ) (\PILOTBITBLT DDPILOTBBT 0)) T]) (\TEDIT.CLEAR.SCREEN.BELOW.LINE [LAMBDA (TEXTOBJ WINDOW LINE) (* jds "17-Jan-85 12:38") (* Clears the edit window to white, clearing only the sapce below the line given.) (BITBLT NIL 0 0 WINDOW 0 (fetch WBOTTOM of TEXTOBJ) (fetch WRIGHT of TEXTOBJ) (IDIFFERENCE (fetch YBOT of LINE) (fetch WBOTTOM of TEXTOBJ)) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE]) (\TEDIT.CLOSEUPLINES [LAMBDA (TEXTOBJ PREVLINE NEXTLINE DONTFILLFLG WINDOW) (* jds " 8-May-85 16:31") (* 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) (* NEXTLINE = NIL => remove all lower lines.) (COND (PREVLINE (* PREVLINE = NIL => DON'T close up anything.) (PROG [DY (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 WINDOW (fetch WLEFT of TEXTOBJ) (fetch WBOTTOM of TEXTOBJ) WINDOW (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 WINDOW) (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 WINDOW (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.COPY.LINEDESCRIPTOR [LAMBDA (FROMLINE TOLINE) (* jds "12-Mar-85 04:23") (* Copy the contents of one line descriptor into another -- except for chaining and Y-location info.) (freplace LEFTMARGIN of TOLINE with (ffetch LEFTMARGIN of FROMLINE)) (freplace RIGHTMARGIN of TOLINE with (ffetch RIGHTMARGIN of FROMLINE)) (freplace LXLIM of TOLINE with (ffetch LXLIM of FROMLINE)) (freplace SPACELEFT of TOLINE with (ffetch SPACELEFT of FROMLINE)) (freplace LHEIGHT of TOLINE with (ffetch LHEIGHT of FROMLINE)) (freplace CHAR1 of TOLINE with (ffetch CHAR1 of FROMLINE)) (freplace CHARLIM of TOLINE with (ffetch CHARLIM of FROMLINE)) (freplace CHARTOP of TOLINE with (ffetch CHARTOP of FROMLINE)) (freplace DIRTY of TOLINE with NIL) (freplace CR\END of TOLINE with (ffetch CR\END of FROMLINE)) (freplace LDOBJ of TOLINE with (ffetch LDOBJ of FROMLINE)) (freplace LHASPROT of TOLINE with (ffetch LHASPROT of FROMLINE)) (freplace LFMTSPEC of TOLINE with (ffetch LFMTSPEC of FROMLINE)) (freplace LTRUEDESCENT of TOLINE with (ffetch LTRUEDESCENT of FROMLINE)) (freplace LTRUEASCENT of TOLINE with (ffetch LTRUEASCENT of FROMLINE)) (freplace ASCENT of TOLINE with (ffetch ASCENT of FROMLINE)) (freplace DESCENT of TOLINE with (ffetch DESCENT of FROMLINE)) (freplace LHASTABS of TOLINE with (ffetch LHASTABS of FROMLINE)) (freplace LMARK of TOLINE with (ffetch LMARK of FROMLINE)) (freplace 1STLN of TOLINE with (ffetch 1STLN of FROMLINE)) (freplace LSTLN of TOLINE with (ffetch LSTLN of FROMLINE]) (\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.FIXCHANGEDLINE [LAMBDA (TEXTOBJ PREVYBOT LINES WINDOW TEXTLEN THISLINE WHEIGHT CHARLIM NEXTCARETCH# PREVDESCENT) (* jds " 5-Oct-85 11:53") (* Reformat a single line, if need be. Returns the changed line) (PROG ((YBOT PREVYBOT) (FORMATDONE NIL) LIMITCHANGED WASDIRTY OCHLIM OLHEIGHT (PREVLINE NIL) (FOUND NIL) DY OFLOWFN NEWLINE) [COND ((IEQP CHARLIM 1) (SETQ CHARLIM (fetch CHAR1 of LINES] (COND ([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 prior one) (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 CHARLIM (fetch CHAR1 of LINES)) (IEQP (ADD1 (fetch CHARLIM of NEWLINE)) (fetch CHAR1 of LINES))) (* If this is a space-filling line, just move the other lines down.) (\TEDIT.INSERTLINE NEWLINE LINES)) (T (* Otherwise, write over existing lines) (\TEDIT.COPY.LINEDESCRIPTOR NEWLINE LINES) (* Move it into place in the chain) (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) )) (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 (\TEDIT.NEXT.LINE.BOTTOM YBOT NEWLINE (fetch PREVLINE 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)) (COND ((fetch FMTBASETOBASE of (fetch LFMTSPEC of LINES)) (IDIFFERENCE (fetch YBOT of LINES) YBOT)) (T (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) ) ((AND NEXTCARETCH# (ILEQ (fetch CHAR1 of LINES) NEXTCARETCH#)) (* This line is off-screen, but is needed for finding the caret's new location) (replace YBOT of LINES with YBOT) (replace YBASE of LINES with YBOT)) (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 (FUNCTION \TEDIT.FIXCHANGEDLINE))) [replace YBOT of LINES with (replace YBASE of LINES with (SUB1 (fetch WBOTTOM of TEXTOBJ] (* Mark this line as being off-screen) (COND ((IGREATERP (fetch CHARLIM of LINES) NEXTCARETCH#) (replace NEXTLINE of LINES with NIL))) (* Chop off any lines below it, to preserve changes that may propogate off the bottom of the window) (\TEDIT.CLEAR.SCREEN.BELOW.LINE TEXTOBJ WINDOW (fetch PREVLINE of LINES)) (* And clear the space below the bottom line on the screen) (RETURN))) (SETQ LINES NEWLINE) (* So that if we inserted a line, we start by moving up to the pre-existing line) )) (RETURN LINES]) (\TEDIT.FIXCHANGEDPART [LAMBDA (TEXTOBJ STARTINGLINE WINDOW INCREMENTAL? NEXTCARETCH#) (* jds " 5-Oct-85 11:55") (* Reformat lines as needed after a change. Return the last line changed, or NIL if there's no need for a \FILLWINDOW.) (PROG* ((THISW (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ))) [LINES (fetch NEXTLINE of (WINDOWPROP THISW (QUOTE LINES] (REGION (DSPCLIPPINGREGION NIL THISW)) (YBOT (fetch PTOP of REGION)) (FORMATDONE NIL) LIMITCHANGED WASDIRTY CHARLIM OCHLIM OLHEIGHT (PREVLINE NIL) (TPREVLINE NIL) (TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (THISLINE (fetch THISLINE of TEXTOBJ)) (WHEIGHT (fetch PTOP of REGION)) (WBOTTOM (fetch BOTTOM of REGION)) (CLEARBOTTOM T) [NEXTCARETCH# (OR NEXTCARETCH# (fetch CH# of (fetch SEL of TEXTOBJ] DY OFLOWFN NEWLINE TYBOT) [COND [NIL (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) (AND LINES (SETQ TPREVLINE (fetch PREVLINE of LINES))) [while LINES do (* Find the first line descriptor of a DIRTY line.) (SETQ YBOT (fetch YBOT of LINES)) (COND ((ILESSP 0 (SETQ DY (IDIFFERENCE (\TEDIT.NEXT.LINE.BOTTOM YBOT LINES (fetch (LINEDESCRIPTOR PREVLINE) of LINES)) YBOT))) (* There used to be another line above this one. Move this up to cover it.) (\TEDIT.CLOSEUPLINES TEXTOBJ (fetch PREVLINE of LINES) LINES NIL (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ))) (* This HAS to fill the window, or we may wind up with missing lines at the bottom of the screen) )) (COND ((AND (ILESSP YBOT (fetch WBOTTOM of TEXTOBJ)) (IGREATERP (fetch CHAR1 of LINES) NEXTCARETCH#)) (* We've run off the bottom of the screen.) (replace NEXTLINE of TPREVLINE with NIL) (* There may be unfixed changes there, so chop off any further lines.) (SETQ LINES NIL)) ((fetch DIRTY of LINES) (RETURN)) ([AND [NOT (IEQP (fetch CHAR1 of LINES) (ADD1 (fetch CHARLIM of TPREVLINE] (NOT (ZEROP (fetch CHARLIM of TPREVLINE] (* This line doesn't match up with the previous line; we should start updating here. But don't worry about the dummy first line) (RETURN)) (T (SETQ TPREVLINE LINES) (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 (WINDOWPROP (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ)) (QUOTE LINES] (* 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 (WINDOWPROP WINDOW (QUOTE LINES] (T (* We found no changes; return a NIL last-line-changed) (replace TXTNEEDSUPDATE of TEXTOBJ with NIL) (* Reset the "needs-update" flag so we don't come back looking for work again.) (RETURN NIL] [SETQ YBOT (fetch YBOT of (SETQ PREVLINE (fetch PREVLINE of LINES] (* Y bottom of the first line to reformat.) (SETQ CHARLIM (ADD1 (fetch CHARLIM of PREVLINE))) (* char to start formatting with) (while (AND LINES (OR (IGEQ YBOT (fetch WBOTTOM of TEXTOBJ)) (ILEQ CHARLIM NEXTCARETCH#))) do (* Run thru lines, cleaning them up. Start with the first dirty line, and only stop if we're both past the place the caret will be AND off the bottom of the screen.) [COND ([ILESSP 0 (SETQ DY (IDIFFERENCE (\TEDIT.NEXT.LINE.BOTTOM YBOT LINES (fetch (LINEDESCRIPTOR PREVLINE) of LINES)) (fetch YBOT of LINES] (* There used to be another line above this one. Move this up to cover it.) (\TEDIT.CLOSEUPLINES TEXTOBJ (fetch PREVLINE of LINES) LINES T (OR WINDOW (\TEDIT.PRIMARYW TEXTOBJ] [COND ((IGREATERP CHARLIM (IMIN (IMAX 1 (fetch CHARLIM of LINES)) TEXTLEN)) (* This line has been rendered superfluous -- Delete it.) (TEDIT.DELETELINE LINES TEXTOBJ WINDOW)) (T (* Try updating the line. If the updater returns NIL, it ran off the bottom of the screen, and we should give up.) (COND ((SETQ LINES (\TEDIT.FIXCHANGEDLINE TEXTOBJ YBOT LINES WINDOW TEXTLEN THISLINE WHEIGHT CHARLIM NEXTCARETCH# (fetch DESCENT of PREVLINE))) (* We're still on screen; update the character and Y-position counters for the next loop) (SETQ CHARLIM (ADD1 (fetch CHARLIM of LINES))) (SETQ YBOT (fetch YBOT of LINES))) (T (* Ran off the bottom of the window; the bottom has already been cleared, so avoid doing it here.) (SETQ CLEARBOTTOM NIL) (RETURN] (COND ((IGEQ CHARLIM TEXTLEN) (* If we've run out of text, chop off any remaining line descriptors, since we won't be needing them.) (replace NEXTLINE of LINES with NIL) (replace TXTNEEDSUPDATE of TEXTOBJ with NIL) (* And there's no more screen updating to do, either.) ) ((AND INCREMENTAL? (fetch NEXTLINE of LINES) (IGREATERP CHARLIM NEXTCARETCH#) (\SYSBUFP)) (* This is an incremental update, and he hit a key. Stop updating and listen to him) (* HOWEVER, NEVER STOP ON THE LAST LINE -- IF THERE ARE NEW LINES TO ADD, ADD ONE.) (SETQ PREVLINE NIL) (SETQ CLEARBOTTOM NIL) (RETURN))) (SETQ PREVLINE LINES) (* Remember the last line we really formatted.) (SETQ LINES (fetch NEXTLINE of LINES)) (* Move to the next line)) (COND (CLEARBOTTOM (* There had been lines yet to be formatted, so there may be garbage below the end of the screen.) (\TEDIT.CLEAR.SCREEN.BELOW.LINE TEXTOBJ WINDOW PREVLINE))) (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.LINE.LIST [LAMBDA (TEXTOBJ WINDOW) (* jds " 7-Feb-85 14:13") (for WW inside (fetch \WINDOW of TEXTOBJ) as LINES inside (fetch LINES of TEXTOBJ) when (EQ WW WINDOW) do (RETURN LINES]) (\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) (* gbn "10-May-85 21:21") (* 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) (ADD1 (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 CHARTOP of LL) CH#)) (* The dirty range overlaps with this line -- it is between the 1st char on the line, and the last char examined when deciding where to break the line.) (replace DIRTY of LL with T))) (SETQ LL (fetch NEXTLINE of LL))) finally (replace TXTNEEDSUPDATE of TEXTOBJ with T]) (\TEDIT.NEXT.LINE.BOTTOM [LAMBDA (CURYBOT LINE PREVLINE) (* jds " 5-Oct-85 11:50") (* * Given a current Y-bottom for PREVLINE, and a LINE to follow it, compute the new line's YBOT value. Takes into account Base-to-base leasing, as well as paragraph leadings.) (PROG (NEWYBOT PARALEADING PARALOOKS BASETOBASE) [COND [[SETQ BASETOBASE (fetch (FMTSPEC FMTBASETOBASE) of (SETQ PARALOOKS (fetch (LINEDESCRIPTOR LFMTSPEC) of LINE] (* If base-to-base spacing is specified, we have to do this in two parts: First, compute the proper spacing between the lines; then add in any paragraph leading.) [SETQ NEWYBOT (IDIFFERENCE (IPLUS YBOT (fetch (LINEDESCRIPTOR DESCENT) of PREVLINE)) (IPLUS BASETOBASE (fetch (LINEDESCRIPTOR DESCENT) of LINE] (COND ((fetch (LINEDESCRIPTOR 1STLN) of LINE) (* This is the first line of a new paragraph. Add in any paragraph leading.) [SETQ PARALEADING (IPLUS (fetch (FMTSPEC LEADBEFORE) of PARALOOKS) (fetch (FMTSPEC LEADAFTER) of (fetch (LINEDESCRIPTOR LFMTSPEC) of PREVLINE] (* The inter-paragraph space is the sum of the previous para's post-leading and this para's pre-leading.) (SETQ NEWYBOT (IDIFFERENCE NEWYBOT PARALEADING] (T (* If there's no base-to-base spacing, then paragraph leading was taken into account in the line formatter, and is already part of LHEIGHT.) (SETQ NEWYBOT (IDIFFERENCE YBOT (fetch (LINEDESCRIPTOR LHEIGHT) of LINE] (RETURN NEWYBOT]) (\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 1985 1986)) (DECLARE: DONTCOPY (FILEMAP (NIL (1019 126699 (TEDIT.CR.UPDATESCREEN 1029 . 2568) (TEDIT.DELETELINE 2570 . 3412) ( TEDIT.INSERT.DISPLAYTEXT 3414 . 9464) (TEDIT.INSERT.UPDATESCREEN 9466 . 15506) (TEDIT.UPDATE.SCREEN 15508 . 16559) (\BACKFORMAT 16561 . 19371) (\DISPLAYLINE 19373 . 31866) (\DOFORMATTING 31868 . 44922) (\FILLWINDOW 44924 . 53593) (\FIXDLINES 53595 . 57867) (\FIXILINES 57869 . 61210) (\FORMATLINE 61212 . 88816) (\SHOWTEXT 88818 . 90934) (\TEDIT.ADJUST.LINES 90936 . 95974) (\TEDIT.BLTCHAR 95976 . 98186) (\TEDIT.CLEAR.SCREEN.BELOW.LINE 98188 . 98749) (\TEDIT.CLOSEUPLINES 98751 . 103058) ( \TEDIT.COPY.LINEDESCRIPTOR 103060 . 105172) (\TEDIT.CREATE.LINECACHE 105174 . 105835) ( \TEDIT.FIXCHANGEDLINE 105837 . 112486) (\TEDIT.FIXCHANGEDPART 112488 . 121615) (\TEDIT.INSERTLINE 121617 . 122241) (\TEDIT.LINE.LIST 122243 . 122540) (\TEDIT.LINECACHE 122542 . 123228) ( \TEDIT.MARK.LINES.DIRTY 123230 . 124441) (\TEDIT.NEXT.LINE.BOTTOM 124443 . 126384) ( \TEDIT.PURGE.SPACES 126386 . 126697))))) STOP