supermario/base/SuperMarioProj.1994-02-09/Toolbox/TextEdit/StyledTextEdit.a
2019-06-29 23:17:50 +08:00

8178 lines
264 KiB
Plaintext

;
; File: StyledTextEdit.a (formerly te68k_style.a)
;
; Contains: TextEdit for ROM or (when included in TextEditPatch.a) 'ptch' 0
;
; Written by: S Capps, M Kaptanoglu, R Wetmore, Sue Bartalo (most recently)
;
; Copyright: © 1982-1989, 1991 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <4> 1/17/92 DCL Backed out the previous change because this file is not supposed
; to be touched. Holy File.
; <3> 12/12/91 DCL #1009157: Changed a Tst to Tst.b so as not to test the potential
; garbage in the other byte. Changed procedure noClickProc in
; TextEdit.a, StyledTextEdit.a, and TextEditPatchIIciROM.a
; <2> 1/16/90 SMB Included TextEditPriv.a
; <1> 12/18/89 CCH Adding for the first time into BBS.
; BBS versions above:
;___________________________________________________________________________________________________
;EASE READ ONLY COPY of file “StyledTextEdit.a”
; 1.7 SMB 08/25/1989 Removed load of nEqu.d.
; 1.6 smb 05/20/1989 Had to reset A2 to selStart(a3) in TECopy after a NewHandle call, which may
; have invalidated the pointer to the teRecord (upon which A2 was based!). See bug #46036.
; Fix for bug 39276: changed add operation in TECustomHook from a long op to a word op.
; Must lock the StScrpHandle for SetStylScrap to work correctly: see bug #36986.
; 1.5 smb 03/02/1989 Added Script Manager patch for setting up teSysJust from the system script
; for Harpo.
; 1.4 SMB 02/22/1989 Replaced hardware casms with feature casms, and changed
; routine names so they would not conflict with mpw includes. Also
; removed additional equates that are in ToolEqu.a. Also renamed this
; file from te68k_patch.a to StyledTextEdit.a to be used for Harpo Rom and
; 6.0.4 System builds.
; 1.3 SMB 02/22/1989 Test
; •1.2 CCH 02/15/1989 Submitting REAL 6.0.3 te68k source until BigBang sources
; get rolled in.
; FILE: TE68K.TEXT
; '/<RWW[0-9]«6»>[¬NO]/'
; © Apple Computer, Inc. 1982-1988
; All Rights Reserved
;
;find /<<<END HISTORY>>>/ "{active}" # Execute to find the next available change number.
; ----------------------------------------------------------------------
;
; Text Edit
;
; Modification history:
;
; 23-Jul-83 New Today
; 2-Aug-83 Code review changes:
; added std2Offset constant
; stdEntry points to param via A2
; changed #7 to #Lock
; moved epilog4
; flags trick in lock/unlock in stdentry/exit
; cleaned up selection safety chk in stdentry
; used grafGlobals(A5) instead of 0(A5)
; cleaned up(Ha!) TEClick
; Changed DoFind to handle top and pin H to DestRect
; switched end checks for teFind in DoText
; Changed and commented selsort- now returns A2^ to selStart
; callers of selSort now use A2
; Shortened rect stuff in RecalDraw
; CallBreak uses reg arguments instead of stack
; 3-Aug-83 Cleaned up TEKey a bit
; Cleaned up refresh a bit
; Changed all indices to unsigned (BGE's)
; Added idle proc for scroll and key
; Addes TEInsert
; Fixed the Bryan Stearns memorial 1-char bug in RecalDraw
; Added hilite hook for MicroSoft and other bizarre things
; Added caret hook too
; SetSelect uses longs
; Added TESetJust, TEGetText
; 5-Aug-83 Fixed a bug in FindLine
; Fixed bug in Recaline (now waits for whole text to finish)
; Optimized dobackgnd to always stop at end
; 6-Aug-83 Dropped total dobackgnd from recal(I guess addition IS communitive)
; 7-Aug-83 Reinstated total dobackgnd from recal(FUCK!)
; 8-Aug-83 Dropped pinrects and used extended rects in DoText to save code
; 17-Aug-83 Fixed Rony bug in RecalDraw
; 19-Aug-83 Added system double/caret times
; 21-Aug-83 Added DoText and recal hooks
; 25-Aug-83 Fixed unwind bug in stdexit
; 25-Aug-83 Fixed Insert D7 bug
; 4-Sep-83 Fixed First char select bug in DoText
; 9-Sep-83 Fixed caret activate problem w/ inactive records
; Dropped background stuff(Finally gave up)
; Added global word break for Europe.
; 12-Sep-83 Made InvertHook push the rectangle
; -----------------------------------------------------------------------
; 23 Jan 85 LAK Adapted for new equate files.
; 24-Jan-85 EHB Added patch in RecalDraw
; 25-Jan-85 EHB Fixed Refresh to only hilight visible part of selection
; 25-Jan-85 EHB Added Capp's TextBox fix
; 16-Jan-85 EHB Fixed center/right justify in TextBox fix
; 03-May-85 SC Fixed the <CR>-in-1st-char bug with word select. FindWord
; would abort if the left char scan got to the beginning, but
; it wouldn't check if the 0th char was a break character or not
; 03-May-85 SC Dropped forROM and for44T compile switches for readability
; 03-May-85 SC New version of FindLine, cleaner and fixes bugs. Still
; inefficient because it measures whole line repeatedly, but
; faster quickdraw fixes this.
; 03-May-85 SC Made trim measure skip wordBreak code and only trim chars
; <= space. This should truly measure only the black characters
; And not the word break chars now.
; 04-May-85 SC Changed D2 usage in TEClick to D5 long sign bit
; 04-May-85 SC SkipLoop in TrimMeasure could go negative
; 04-May-85 SC Dropped DelGuts and InsGuts call from PasteGuts and made a
; combined inline call for munger speed. Could make DelGuts and
; InsGuts inline since only 1 caller, but left that for another day
; 05-May-85 SC Made StdEntry/Exit use LINK instructions not SP based
; 05-May-85 SC TESetSelect trashed teSelPoint, cleaned up code a bit
; 05-May-85 SC Dropped teSelPoint usage, get off stack frame instead of TeHandle
; 05-May-85 SC Tricks played with A0 and teCarOn, teCarAct in DrawCaret, cleaned
; up for readability.
; 05-May-85 SC Longized all the 0(A0,DX.L) and call to _TextWidth and _DrawText
; 05-May-85 SC Fixed up recalLines to reduce flashiness
; 06-May-85 SC DoFormat had an extra measure for left justify that was not needed
; 06-May-85 SC DoText used tempRect, use stack frame instead
; 07-May-85 SC Undo refresh hilite stuff, moved similar stuff to Hilite
; 08-May-85 SC Added default click proc for auto scrolling
; 08-May-85 SC Added TEPinScroll which does a pinned scroll (Not upward
; compatible so I couldn't include in real scroll, but it is
; used by the default click proc and TEScrollView
; 08-May-85 SC Added TEScrollView which insures selection is visible before
; doing something. Called from TEKey, TEPaste, TECut, TEIdle, etc.
; 09-May-85 SC StdEntry/Exit save restore teTextH flags
; 09-May-85 SC teLftClick not a byte, now the tefLeftClk bit in teFlags
; 09-May-85 SC Made SelView local proc
; 09-May-85 SC Dropped trim measure black stuff
; 09-May-85 SC Made a local CalText proc to avoid StdEntry
; 11-May-85 SC Completely trashed DoText, OffsetStuff, DoFormat and
; replaced them with a clean versions of DoFind, DoHilite,
; DoDraw, DoCaret. This was to clean up the scaled fonts
; problem, the direct pen adjustment and general mayhem
; With the old DoText.
; 11-May-85 SC Local proc Scroll broken out for use by TEScroll and TEPinScroll
; 11-May-85 SC Reinstated teSelPoint, it's in documentation
; 11-May-85 SC Added TEAutoView trap to enable/disable the auto scrolling
; 11-May-85 SC Use _XMunger instead of _Munger
; 12-May-85 SC New local proc MungeSetup to do common munger stuff
; 12-May-85 SC Use D5 in recallines to hold telength
; 13-May-85 SC Save/Restore text stuff in std entry/exit and made setlinarray
; avoid calling _GethandleSize(done once in stdEntry)
; 13-May-85 SC Added preflight routine to check memory. Called from
; pasteguts, insertGuts, and TextBox. Did similar to TENew
; 15-May-85 SC Multiple standard entries with stack peel amount in D1. Does
; a preflight and then escapes if the preflight fails
; 18-May-85 SC Put back DoText funnel for compatibility
; 18-May-85 SC Dropped printable trim in FindLine @ end
; 18-May-85 SC LineWidth didn't handle the line past teLength correctly
; 18-May-85 SC Merged LineWidth and TrimMeasure
; 18-May-85 SC Made trim measure skip wordBreak code and only trim chars
; <= space. This should truly measure only the black characters
; And not the word break chars now. (Deja Vu - did this on 3 May
; but a bug in FindLine made it LOOK as though it didn't work
; so I undid it on 9-May)
; 18-May-85 SC New routine PinDisplay replaces pin code in Hilite and Refresh
; 18-May-85 SC Made DefClikProc obey autoScroll bit
; 20-May-85 SC DoSearch longize D3-D4 (Thanks Bill and Larry)
; 20-May-85 SC CleanupSel saved teTextH flags twice!!
; 20-May-85 SC Fast TextBox didn't catch zero string length case (oops)
; 20-May-85 SC SelView called before caret view in DelGuts and PasteGuts;
; should be after (leaves carets behind in Dialogs)
; 21-May-85 SC Added negative length to Fast TextBox
; 23-May-85 SC Dropped port save/restore font
; 7-Jun-85 EHB Fast TextBox shouldn't catch zero strings else no EraseRect(oops)
; 10-Jun-85 SC CharbyChar had a BLT that should've been a BLE (It gets there
; by a BGE so it should stay in loop if BLE).
; 10-Jun-85 SC DoText links a stack frame/DoBye and findDone UNLK
; 10-Jun-85 SC In rangeRect, stuff the rect.left in tempRect and set pen to
; right for compatibility with old DoText
; 10-Jun-85 SC DoSearch returns in D0 as before
; 15-Jun-85 SC Undid "teLftClick not a byte, now the tefLeftClk bit in teFlags"
; had to drop back to old one for compatibility. TERecback is
; now the TEFlags
; 15-Jun-85 SC DoText must return ThePort in A0 for compatibility
; 16-July-85 SC PinDisplay has new entry point for TEUpdate compatability
; Refresh changed to take A0 pointing to an update rect not
; D0/D1, calls PinA0Rect.
; 26-Jul-85 EHB Added ShowCaret to end of TEPinScroll (needed for null scroll)
; 01-Oct-85 EHB Set up D2 for all calls to CallBreak (identifies caller)
; 01-Oct-85 EHB Added hooks for TrimMeasure, FindWord, and FindLine.
; 30-Oct-85 EHB In DoFind, set up D3/D4 with selStart/selEnd before calling DoText
; 31-Oct-85 EHB In RecalDraw, draw whole words if WordRedraw (new lowMem) is TRUE
; 31-Oct-85 EHB Fast TextBox was scanning 0 len strings for CR's
; 01-Nov-85 EHB If WordRedraw=0->draw normal, if >0 -> draw word, if <0 -> draw line
; 03-Nov-85 SC Fixed special case D3=0 in DoCaret
; 05-Nov-85 EHB Moved label to make WordRedraw fix work right
; --------------------------------- Lonely Heifer ROMs ----------------------------
; 14-Jan-85 EHB In PasteGuts, call SelSort and get sel length for preflight
; Fix longize bug in the beginning of DoSearch
; Added cursor key support to TEKey
; <19feb86> BBM Made some modifications to work under MPW
; --------------------------------- ROM 76 ----------------------------
; <C78/17jul86> MBK removed equates to an external file; added four new
; traps (TEStylNew, iTEStylPaste, iTESetStyle, iTEGetStyle);
; added the following new routines: SetOneStyle, GetDefStyle,
; ScanMeasure, GetLineHites, GetHite, CopyStyle, DeleteStyle,
; DecStyleCount, StylMeasure, SetLineHite, PasteStyle, MakeRoom,
; DupStyle, FindStyle, CompareStyles, AddStyle, ExtendStyle,
; FindLineHite, GetCurStyle, GetNumStyles, GetStyle,
; RecalstStarts, SetHiteAscent, SetStyle, ConcatStyles,
; ChangeStyle, and FindFeature; modified the following routines:
; TESetText, LineRect, PinDisplay, StdEntry, TECopy, DelGuts,
; RecalDraw, FindLine, RecalLines, SetLineArray, TEPaste,
; InsGuts, TEKey, TEPinScroll and TESelView.
; <C94/29jul86> MBK Added 3 more traps (iTEReplaceStyle, TEGetOffset, TEFindStyle);
; renamed iTEGetStyle to TEFindStyle (iTEGetStyle now returns the
; style handle); fixed selection bug, the problem was in
; ScanMeasure and DoSearch. Fixed bug in CharByChar. Started
; fixing recalibration problem.
; <C95/4aug86> MBK Fixed the scrolling problem in SelView; Modified
; Recallines to take into account changes in point size.
; <C105/3Sep86> MBK Renamed iTEGetStyle to iGetStylHandle and TEFindStyle to
; iTEGetStyle. Added iSetStylHandle. Added TEDispatch to handle
; All style traps (except TEStylNew) with only 1 real trap for
; them all. Made the following changes for International:
; added the Pixel2Char, Char2Pixel, and HiliteText hooks;
; modified doSearch and doDraw to test teSysJust and perform
; their functions backwards if it's set; totally rewrote
; DoHilite. Added NextLineRect to speed up DoDraw. Rewrote
; stages 2 and 3 of Recal for speed. Added new feature of
; Not resetting the line heights in Recallines if the high bit
; of the line height already stored is set. Changed the
; iTESetStyle and iTEReplaceStyle input modes to be OR'able.
; Also combined the body of these 2 routines for efficiency.
; Added stuff to compute distance to be auto-scrolled for
; TERecs with style, in DefClikProc. Changed BSET and BCLR
; of handles to _HLock and _HUnlock.
; <C139/10Sep86> MBK Fixed iTEGetStyle to return the grafport settings for
; records without style. Made addSize OR'able in StyleGuts.
; Fixed "index expected in D0" bug in DoSearch. Added
; DoMeasure, ChkBounds, and made FindLine call Pixel2Char
; for International. Fixed word-wrapping with spaces. Put
; local equates back in this file and put the rest of the
; equates in nToolEqu.a. Got rid of scrp equates, since they
; were the same as the st- equates.
; <C182/6oct86> MBK Changed colorBit to clrBit since colorBit is a Quickdraw
; Trap already. Modified DoHilite to always measure from start
; of line, to fix highlighting problem with scaled fonts. Got
; rid of special code in PasteStyle to prevent style duplication,
; And just call ConcatStyles at the end. Added DoErase to fix
; italics erase problem. Removed code to shrink style runs array
; in ConcatStyles. Fixed problem of not clearing flag bits in
; ptrs before doing operations on an address. Changed color from
; LONGINT to RGBColor, and added Ernie's RGBForeColor and
; GetForeColor to handle this for the Alladin world.
; <C207/16oct86>MBK Fixed problem in which CR at bottom of ViewRect did not cause
; scrolling (cleaned up DefClikProc, which fixed the problem seen
; in the Poke program). Changed Pixel2Char not to expect a buffer
; ptr as input, and to allocate the space itself on the stack.
; Added StylTextBox. Changed scrpStartChar to a LONGINT. Changed
; TECopy and TEPaste not to touch the desk scrap if the TERec is
; an old one (since David G. mentioned a lot of old applications
; may need to preserve the desk scrap for Undo). Changed DoHilite
; back to what it was (except with middle lines being highlighted
; as a block for speed) because the International version was
; just too slow; this means I also removed the HiliteText hook.
; Modified RecalDraw to adjust the redraw selection according to
; changes in line height.
; <C229/29oct86>MBK Fixed 2 register preservation problems. Fixed InsertRecal
; memory overload problem. Redesigned method of updating line heights.
; <C381/8nov86>MBK Made all changes resulting from code review.
; <C393/10nov86>MBK Fixed CopyStyle and InsertRecal to reset ptr values after a
; memory allocation call (the ptrs were pointing to trash).
; --------------------------------- ROM 77 ----------------------------
; <C440/19nov86>MBK Fixed SetLineHite to take the line height from the only style
; when text length is 0 (instead of using the system font as a default).
; Fixed RecalLines to consider the next character the start of the
; next line if the width of the viewRect is less than the width of
; a single character. Fixed styleGuts to access FmDefaultSize as
; a byte, not a word. Fixed RecalLines bug in which lines are not
; recalibrated when text is typed over a single CR.
; <C454/21nov86>MBK Fixed bug in RangeRect that caused selection to be off in MultiPlan.
; Fixed special case in which line redraw did not work, in RecalLines.
; <C475/02dec86>MBK Set the high bit of the pnMode before highlighting, to use the new
; background color highlighting method.
; <C485/04dec86>MBK Set the error code in D0 before calling SysError. Fixed bug in which
; carets left on the screen were not getting erased (in Mac3D).
; <C513/12dec86>MBK Changed to clear bit in HiliteMode instead of setting bit in pnMode
; for color hilighting. Fixed selection bug in Pixel2Char.
; <C574/30dec86>MBK Fixed SetStyle to save D2 on the stack because _RGBForeColor destroys it.
; Fixed Pixel2Char to restore D0 from D1 if NewPtr has to be called.
; <C597/06jan87>MBK Restore A3 ptr after RGBForeColor call in StdExit, in case TERec gets moved.
; <C622/13jan87>MBK Changed to clear the color highlight bit only if a highlight
; hook has not been installed (this was a problem with highlighting
; in the hex editor of ResEdit). Modified DoErase to erase the previous
; character if the mode is XOR, otherwise redrawing it will wipe it out
; (this was a problem in NetTrek). Modified StylMeasure to lock the style
; Record so that dereferenced pointer doesn't end up pointing to garbage.
; Also fixed Pixel2Char to do a signed comparison on the stack space.
; This bug was discovered by tEx, when the RAM cache was set high.
; ** BETA 3 **
; <C676/23jan87>MBK Added iGetStylScrap, PutStylScrap, iTEGetPoint, and iTEGetHeight.
; ** BETA 4 **
; <C717/28jan87>MBK Made changes in GetDefStyle, DoDraw, MeasureIt,
; StylMeasure, SetHiteAscent, and SetStyle to protect unlocked
; pointers from memory reallocation. Added startLine and
; endLine input to iTEGetHeight. Added RecalDraw to PutStylScrap.
; <C719/29jan87>MBK I removed the C717 change to SetHiteAscent. The ptr there
; was not an offset from styleTab, it was an addr on the stack.
; ** BETA 5 **
; <C734/30jan87>MBK I changed PutStylScrap to iTEStylInsert, which unlike
; PutStylScrap will insert the text as well as the style info.
; Fixed StyleGuts to check for point sizes <= 0 when an addSize
; is done. It now converts such values to 1. Modified iTEGetHeight
; to subtract 1 from startLine because GetLineHites wants it
; 0-based. iSetStylHandle fixed to dispose of old style handle
; before setting new one.
; ** BETA 6 **
; <C766/05feb87>MBK Fixed CopyStyle to lock my style handle before calling
; PutScrap. Fixed DelGuts to relock text handle after munging.
; Removed call to StdEntry from iTEStylInsert because TEDispatch
; does it.
; <C788/11feb87>MBK Fixed iTEStylInsert to get the input parameters in the
; correct order.
; <C815/13feb87>MBK Fixed StdEntry to set the Grafport's txMode from TERec.teMode.
; Fixed RangeRect to set pnLoc correctly for compatibility with
; old applications. Fixed FindLine to check for a CR at the end
; of a string of unwrapped blanks.
; ** BETA 8 **
; <C851/27Apr87>MBK Miscellaneous bug fixes (search on 851 to get more detailed
; descriptions); added code to handle setting styles on null
; selections.
; <C854/21may87>MBK Changed TECalText delta to 8001, fixed Pixel2Char disposhandle
; problem, fixed find style problem in PstStylScrap, fixed GetLineHites
; to work with fixed height, fixed recal deletion problem, restored input
; parameter order of iTEGetHeight.
; <C858/4jun87>MBK Fixed problems of iTEStylInsert destroying the StScrpHandle, style
; duplication problem in PstStylGuts, and iTEGetPoint returning incorrect
; offset when text ends in CR. Removed conditionals around bug fixes.
; <C905/13oct87> MSH Port to HcMac (Laguna). No color on this machine
; <C914/29Oct87> rwh Port to Modern Victorian
; ------------------------------ System 6.0 ----------------------------
; <C971/RWW101287> Did some personal cleanup. Added new equates for new structures.
; Changed Bcc's and Bcs's to more logical forms.
; Began comparing various patches against this source to resolve differences.
; <C971/RWW101987> Fixed 0 length bug in iTEStylInsert
; <C971/RWW102187> Added conditional equates to make RAM-based testing easier
; <C971/RWW102287> Patched ReCalLines to properly shrink lineStarts array
; <C971/RWW102387> Broke out some common code, trying not to reinvent the wheel:
; AnyNullStyle, GetTrueStyle, GetOneStyle
; Changed iGetStylScrap to return a proper scrap record, even if
; there is no selection range. Prevents apps from having
; to special case insertion points
; Rewrote most of iTEGetHeight to properly sort and pin start/end
; Added conditional inclusion of TEDispatch'ed routine addresses
; so I can find them without a Cray
; <C971/RWW102687> InitRsrved had some strangeness in it
; Added TESetEraseFlag and iTEContinuousStyle. Added in code to check
; for erase flag before performing _EraseRect's
; <C971/RWW102787> Changed references to faces to be byte instead of word length
; <C971/RWW102887> Changed branches to optimal form. Those patches marked "<C971/RWW102887>NO"
; are for new ROMs and total replacement patches only.
; (There were an awful lot of word branches where shorts would do!)
; Added SetStyleScrap
; <C971/RWW102987> Changed fail test in SetGuts to masking uninteresting bits
; Added doToggle functionality to SetGuts, StyleGuts, SetRsrved, CheckMatch
; <C971/RWW103087> Added some hysteresis to lineStarts hack, to try to prevent some
; heap thrashing from constant SetHandleSize calls
; <C971/RWW110387> Added new internal dispatch table to (quasi-) support tabs. We won't
; officially support tabs, but these hooks will make the job a lot
; simpler for those who need it. (It used to be a lot easier to hook
; in tab support than it is now that styles have to be reckoned with.)
; <C971/RWW110487> Yanked SetEraseFlag and associated logic. Only bought us about 10% - not
; enough to get excited over. Added iTECustomHook to give a high end
; way to stuff new internal dispatch table addresses
; <PMAB381/RWW020488> Took out some redundancies and moved autoscroll flag from its position in
; "teFlags" (née teRecBack) to the new dispatch record. Ooops. It acted as
; a high bit set in the new handle to the TEDispatchRec
; <PMAB387/DBG021088> Fixed bug in TEDispose where dispatch vector was not getting released for
; unstyled TE records.
; <S425/RWW031688> Fixed bug in iTEContinuousStyle and changed the way it handles face
; attributes
; <S508/RWW080288> Revisiting of S508, installed on Altair only by mistake.
; Fixes problem of TEHandle being dereferenced across a call to
; InstallIntDispatch in TEStylNew, which could thrash the heap.
; <19Feb89smb> Replaced hardware casms with feature casms, and changed routine names
; so they would not conflict with mpw includes. Also removed additional
; equates that are in ToolEqu.a.
; <28Feb89smb> Added Script Manager patch for setting up teSysJust from the system script
; for Harpo.
; <16May89smb> Had to reset A2 to selStart(a3) in TECopy after a NewHandle call, which may
; have invalidated the pointer to the teRecord (upon which A2 was based!).
; See bug #46036. Fix for bug 39276: changed add operation in TECustomHook
; from a long op to a word op.
; <17May89smb> Must lock the StScrpHandle for SetStylScrap to work correctly: see bug #36986.
; _______________________________________________________________________
;<<<END HISTORY>>> <- This is to make the end of these comments easy to find with MPW.
Blanks On
String AsIs
If &TYPE('&RWWDebug') = 'UNDEFINED' Then
If &TYPE('InsideTEPatch') = 'UNDEFINED' Then ; <S383>
LOAD 'StandardEqu.d'
INCLUDE 'ScriptPriv.a' ; <28Feb89smb>
INCLUDE 'TextEditPriv.a' ; <1/9/90smb>
EndIf ; <S383>
EndIf
; *************************************************************************************************
; *************************************************************************************************
; *************************************************************************************************
TextEdit Proc Export
Export TextBox
Export TEActivate
Export TEClick
Export TECopy
Export TECut
Export TEDeactivate
Export TEDelete
Export TEInit
Export TENew
Export TEDispose
Export TEKey
Export TEPaste
Export TEIdle
Export TEUpdate
Export TEInsert
Export TESetText
Export TECalText
Export TESetSelect
Export TEScroll
Export TESetJust
Export TEGetText
Export TEAutoView
Export TEPinScroll
Export TESelView
Export TEStylNew
Export TEGetOffset
Export TEDispatch
; hooks to be stored in the trap table
Export XTrimMeasure
Export XFindWord
Export XFindLine
Export vPixel2Char
Export vChar2Pixel
;-----------------------
teStylSize Equ 28 ; initial size of teStylesRec with 2 entries
stBaseSize Equ 20 ; added to fix MakeRoom bug
; iTESetStyle/iTEContinuousStyle modes
doAll2 Equ $1F ; all of the above + add size
doAll3 Equ $3F ; all of the above + toggle faces
;-----------------------
teFind Equ 0
teMark Equ 1
teDraw Equ -1
teLoc Equ -2
teLFlush Equ 0 ; default
teRFlush Equ -1
teCenter Equ 1
; constants for identifying the routine that called callbreak
teWordSelect Equ 4 ; clickExpand to select word
teWordDrag Equ 8 ; clickExpand to drag new word
teFromFind Equ 12 ; FindLine called it
teFromRecal Equ 16 ; RecalLines called it
inHandle Equ 8 ; TE handle offset
saveHandle Equ -2 ; incoming handle flags
savePort Equ saveHandle-4 ; incoming graf port
saveClip Equ savePort-4 ; incoming clip in TE port
saveTH Equ saveClip-2 ; saved text handle flags
saveFont Equ saveTH-2 ; Grafport's font
saveFace Equ saveFont-2 ; Grafport's face
saveSize Equ saveFace-2 ; Grafport's size
saveColor Equ saveSize-6 ; Grafport's color
stdLink Equ saveColor
; standard frame for doText
saveLeft Equ -2 ; true left
saveJust Equ saveLeft-2 ; left setting after justification
txtLink Equ saveJust
; frame for recallines
savedD4 Equ -2
savedD2 Equ savedD4-2
startHndl Equ savedD2-4
savePtr Equ startHndl-4
oldNLines Equ savePtr-2
RecalLink Equ oldNLines
AddrTable DC.W iTEStylPaste-AddrTable ; 0
DC.W iTESetStyle-AddrTable ; 1
DC.W iTEReplaceStyle-AddrTable ; 2
DC.W iTEGetStyle-AddrTable ; 3
DC.W iGetStylHandle-AddrTable ; 4
DC.W iSetStylHandle-AddrTable ; 5
DC.W iGetStylScrap-AddrTable ; 6
DC.W iTEStylInsert-AddrTable ; 7
DC.W iTEGetPoint-AddrTable ; 8
DC.W iTEGetHeight-AddrTable ; 9
; ** <C971/RWW102687> New entry points
DC.W iTEContinuousStyle-AddrTable ; 10
DC.W iSetStylScrap-AddrTable ; 11
DC.W iTECustomHook-AddrTable ; 12
DC.W iTENumStyles-AddrTable ; 13
; ----------------------------------------------------------------------
; FUNCTION TEGetText( h: TEHandle ): Handle;
; Returns the text handle
; ----------------------------------------------------------------------
TEGetText
Bsr StdEntry
Move.L teTextH(A3),(A2) ; return the text handle
Bra epilog4
; ----------------------------------------------------------------------
; PROCEDURE TEInit
; ----------------------------------------------------------------------
TEInit
MoveQ #0,D0
Move D0,TEScrpLength ; save in global space
_NewHandle
Move.L A0,TEScrpHandle ; Save in global space
Lea XDoText,A0 ; set up doText hook
Move.L A0,teDoText
Lea XRecalLines,A0 ; set up recal hook
Move.L A0,teRecal
Lea DefWordBrk,A0 ; get default word break
Move.L A0,teWdBreak
; <28Feb89smb>
If onHcMac then
WITH SMgrRecord,ScriptRecord
GetSMgrCore a0 ; load SMgr globals pointer.
tst.b smgrEnabled(a0) ; script manager disabled?
beq @bail ; yes -> bail out.
move.w smgrSysScript(a0),d0 ; get system script code.
lsl.w #2,d0 ; script code is long offset.
move.l smgrEntry(a0,d0.w),a0 ; load system script entry.
move.b scriptJust(a0),d0 ; load script just.
ext.w d0 ; sign extend just.
move.w d0,TESysJust ; set global just.
endWith
@bail
endif
Rts
; ----------------------------------------------------------------------
; PROCEDURE TEDispose( h: TEHandle )
; ** <C207/13oct86/MBK> ** Added code to dispose of style
; related handles if this TERec has style.
; ----------------------------------------------------------------------
TEDispose
Link A6,#0
MoveM.L D2-D7/A2-A4,-(SP) ; save stdregs
Move.L 8(A6),A4 ; Pop handle into A4
Move.L (A4),A3 ; Dereference into A3
Move.L teTextH(A3),A0 ; get rid of text
_DisposHandle
; Following lines moved here from within "styled" section below.
Move.L teDispatchH(A3),A0 ; Added to (quasi-) support tabs <C971/RWW110387><PMAB387/DBG021088>
_DisposHandle ; <PMAB387/DBG021088>
Tst.W teSize(A3) ; record with style?
Bpl.S @0 ; more to dispose if so
Move.L teStylesH(A3),A2 ; get style handle
Move.L (A2),A2 ; dereference
Move.L styleTab(A2),A0 ; handle to distinct styles
_DisposHandle
Move.L lhTab(A2),A0 ; handle to line heights
_DisposHandle
Bsr.S DisposRsrved ; dispose of reserved handle
Move.L teStylesH(A3),A0 ; get rid of itself
_DisposHandle
@0 Move.L A4,A0 ; get rid of itself
_DisposHandle
MoveQ #4,D0
Bra Std2Exit
; ----------------------------------------------------------------------
; PROCEDURE DisposRsrved;
; ** <C851/14Apr87/MBK> **
; I changed teReserved to a handle to the following structure:
; Record
; newReserved : LONGINT;
; nullScrap : stScrpHandle;
; End;
; nullScrap is used to store a style which is set when the
; selection is NIL in iTESetStyle. I store it in the scrap
; format so that it can easily be inserted using PstStylGuts.
; This procedure is called to dispose of the nullStyle handle.
; ----------------------------------------------------------------------
DisposRsrved
Move.L teStylesH(A3),A0 ; get style handle
Move.L (A0),A0 ; deref
Move.L nullStyle(A0),A0 ; get reserved handle
Move.L A0,-(SP) ; save this handle
Move.L (A0),A0 ; deref
Move.L nullScrap(A0),A0 ; get handle to scrap for null selection
_DisposHandle ; get rid of null scrap handle
Move.L (SP)+,A0 ; get back nullStyle handle
_DisposHandle ; get rid of nullStyle handle
Rts
; ----------------------------------------------------------------------
; PROCEDURE TextBox( Text: Ptr; Length: LONGINT; r: Rect; style: INTEGER );
; 18 14 10 8
TBJust Equ 8
TBBox Equ 10
TBLength Equ 14
TBText Equ 18
; ----------------------------------------------------------------------
TextBox
Link A6,#0
MoveM.L D2-D7/A2-A4,-(SP) ; save StdRegs on stack
Tst.W TBJust(A6) ; “left” justified? <C971/RWW110987>
Bne.S @05 ; no => skip this <C971/RWW110987>
Move.W teSysJust,TBJust(A6) ; he meant, “default justification” <C971/RWW110987>
@05 Cmp.W #teForceLeft,TBJust(A6) ; _real_ left justification? <C971/RWW110987>
Bne.S @08 ; no => skip this <C971/RWW110987>
Clr.W TBJust(A6) ; clear justification <C971/RWW110987>
@08 ; <C971/RWW110987>
; here's Capp's code to make TextBox fast for drawing single lines
; Added EHB 25-Jan-85.
Move.L TBText(A6),A0 ; see if any CR's in text
Move.L TBLength(A6),D0 ; get length
Blt.S tbExit ; escape if illegal string <C971/RWW102887>NO
Beq.S NoZeroScan ; => don't scan NIL strings <EHB 31-Oct-85>
@0
Cmp.B #$0D,(A0)+
Beq.S useRealOne
SubQ.L #1,D0
Bne.S @0
; no carriage returns, try in rect
NoZeroScan SubQ #2,SP ; see how big it is?
Move.L TBText(A6),-(SP) ; pass text
Clr.W -(SP)
Move TBLength+2(A6),-(SP) ; pass length (low word)
_TextWidth
Move.W (SP)+,D3 ; save it
Move.L TBBox(A6),A0 ; point to rect
Move right(A0),D0
Sub left(A0),D0
SubQ #2,D0
Cmp D3,D0
Ble.S useRealOne
Move.L A0,-(SP) ; erase the rect
_EraseRect
SubQ #8,SP
Move.L SP,-(SP)
_GetFontInfo
Move (SP)+,D0 ; get ascent
AddQ #6,SP ; skip rest
Move.L TBBox(A6),A0 ; point to rect
Move.L (A0),-(SP) ; push topleft
Add D0,(SP) ; go down ascent
AddQ #1,2(SP) ; indent 1 for TE compatibility
_MoveTo
Tst.W TBJust(A6) ; look at justification
; leave high byte for others
Beq.S @2 ; if left go do it
; assume centered
Move.L TBBox(A6),A0 ; point to rect
Move right(A0),D0 ; calc width
Sub left(A0),D0
Sub D3,D0 ; subtract text width
SubQ #1,D0 ; caret space TE compatibility
Tst.W TBJust(A6) ; look at justification
Bmi.S @1 ; if right skip right shift
AsR #1,D0 ; divide by two
@1
Move D0,-(SP) ; move over
Clr -(SP) ; dv = 0
_Move
@2
Move.L TBText(A6),-(SP) ; pass text
Clr -(SP)
Move TBLength+2(A6),-(SP) ; pass length (low word)
_DrawText
tbExit
Bra.S Go14Exit ; go to standard exit
; end of TextBox patch <EHB 25-Jan-85>
UseRealOne
; watch out for wierd (SP) offsets
SubQ #4,SP ; make room for return handle
Move.L TBBox(A6),-(SP) ; pass rect to init code
Move.L (SP),-(SP) ; pass rect twice
Move.L (SP),-(SP) ; pass rect twice
_EraseRect
_TENew
Move.L (SP)+,A4 ; save handle
Move.L (A4),A0 ; dereference
Move.W TBJust(A6),teJust(A0) ; and set style
Move.L TBLength(A6),D0 ; get length
Beq.S noTextBox
Move.L TBText(A6),-(SP) ; pass text pointer
Move.L D0,-(SP) ; pass text length
Move.L A4,-(SP) ; pass tehandle
_TESetText
Move.L TBBox(A6),-(SP) ; pass rect to update
Move.L A4,-(SP) ; pass tehandle
_TEUpdate ; and draw it
noTextBox
Move.L A4,-(SP) ; pass tehandle
_TEDispose ; and dispose it
Go14Exit
MoveQ #14,D0
Bra Std2Exit
; ----------------------------------------------------------------------
; PROCEDURE TESetText( text: Ptr; l: Length; h: TEHandle );
; ** Modified 6/18/86 by MBK **
; Makes the text passed in the current text to edit
; ----------------------------------------------------------------------
TESetText
Bsr StdEntry
Move.L (A2)+,D0 ; get length passed
Move D0,teSelStart(A3) ; save as selection
Move D0,teSelEnd(A3)
Move D0,teLength(A3) ; save as length
Move.L teTextH(A3),A0 ; handle to stuff into
Move.L D0,-(SP)
_HUnlock ; and unlock it
Move.L (SP)+,D0
Move.L (A2)+,A0 ; set up ptr
Move.L teTextH(A3),A1 ; handle to stuff into
_PtrToXHand
Move.L teTextH(A3),A0 ; handle to stuff into
_HLock ; relock it
Bsr.S SetOneStyle ; set GrafPort's style <C971/RWW102887>NO
Bsr CalText ; go do it
noText
go12
Bra epilog12
; ----------------------------------------------------------------------
; PROCEDURE SetOneStyle
; ** Added 6/2/83 by MBK **
; Called by TESetText to set the entire body of the new text
; to a single style, which is taken from the GrafPort by
; default.
; ----------------------------------------------------------------------
SetOneStyle
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; quit if no style
; Set style handle to minimum size (i.e., 1 style for entire text)
Move.L teStylesH(A3),A0 ; get style handle
MoveQ #teStylSize,D0 ; size of record with 1 style
Bsr.S MySetHandleSize ; reset handle size <C971/RWW102887>NO
Move.L (A0),A0 ; dereference
; Reset StyleRec's handle size to just 1 StyleRec
Move.L styleTab(A0),A0 ; handle to StyleRec's
MoveQ #stRecSize,D0 ; size of 1 style record
Bsr.S MySetHandleSize ; reset handle size <C971/RWW102887>NO
Move.L teStylesH(A3),A0 ; get style handle
Move.L (A0),A0 ; dereference to A0
Move.W teLength(A3),D0 ; get length of text
Bsr.S GetDefStyle ; store default style in StyleRec <C971/RWW102887>NO
@0 Rts
; ----------------------------------------------------------------------
; PROCEDURE MySetHandleSize
; ** <C381/7nov86/MBK> **
; MySetHandleSize unlocks the TEHandle and the text handle, attempts
; to set the input handle size, calls system error if there is one,
; And otherwise relocks TEHandle and the text handle.
; Entry:
; D0: requested handle size
; A0: a handle
; A3: Ptr to TERec
; A4: Handle to TERec
; Exit:
; A3: Could have a different value if memory was shifted
; ----------------------------------------------------------------------
MySetHandleSize
MoveM.L D0/A0,-(SP) ; save input
Move.L teTextH(A3),A0 ; text handle
_HUnLock ; unlock it
MoveM.L (SP)+,D0/A0 ; restore input
_SetHandleSize ; do it
Bne.S badExit ; fly away if system error
MoveM.L D0/A0,-(SP) ; save input
Move.L teTextH(A3),A0 ; text handle
_HLock ; lock that too
MoveM.L (SP)+,D0/A0 ; restore input
Rts
badExit
Move.W #dsMemFullErr,D0 ; memory full error ** <C485/03dec86/MBK> **
_SysError ; go away and never come back
; ----------------------------------------------------------------------
; PROCEDURE GetDefStyle
; ** Added 6/2/86 by MBK **
; GetDefStyle gets the default style for this TERec (taken
; from its GrafPort) and stores it in the styleRec pointed
; to by A0.
; Entry:
; D0: length of text
; A0: dereferenced TEStylesH
; A3: Ptr to TERec
; ----------------------------------------------------------------------
GetDefStyle
Move.W #1,nRuns(A0) ; always 1 style to start
Move.W #1,nStyles(A0) ; # of styleRec's
Lea runs(A0),A1 ; point to start of style array
Clr.L (A1)+ ; start offset and index
Move.W D0,(A1)+ ; 1 beyond the end
Move.W #$FFFF,(A1) ; make it no style
Move.L styleTab(A0),A0 ; handle to StyleRec's
Move.L (A0),A0 ; dereference
Move.W #1,stCount(A0) ; so set count to 1
Bsr.S GetSize ; get ascent & hite <C971/RWW102887>NO
; Dereference the handle again. GetSize calls GetFontInfo, which could
; move memory around.
Move.L teStylesH(A3),A0 ; style handle
Move.L (A0),A0 ; dereference
Move.L styleTab(A0),A0 ; handle to StyleRec's
Move.L (A0),A0 ; dereference
Move.W D0,stAscent(A0) ; save in ascent ** <C207/10oct86/MBK> **
Move.W D1,stHeight(A0) ; save in line height ** <C207/10oct86/MBK> **
; Get the font, face, size and color and save away
Move.L teGrafPort(A3),A1 ; get this port
Move.W txFont(A1),stFont(A0) ; save the font
Move.W txFace(A1),stFace(A0) ; save the face
Move.W txSize(A1),stSize(A0) ; save the size
Pea stColor(A0) ; place to store color ** <C182/6oct86/MBK> **
;; If forRAM THEN
If (Not forROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; are we on a color system? (as per Jerome) <C971/RWW112487>
Bnz.S @1 ; Nope <C971/RWW112487>
_GetForeColor ; <C971/RWW112487>
Bra.S @2 ; <C971/RWW112487>
@1 Bsr GetForeColor ; <C971/RWW112487>
@2
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
_GetForeColor ; for Ikki ** <C182/6oct86/MBK> **
Else
Bsr GetForeColor ; for Alladin ** <C182/6oct86/MBK> **
EndIf
Rts
; ----------------------------------------------------------------------
; PROCEDURE GetSize
; ** <C207/10oct86/MBK> **
; Get ascent and line height from current font.
; Exit:
; D0: ascent
; D1: line height (= descent + leading!)
; ----------------------------------------------------------------------
GetSize
Move.L A0,-(SP) ; calling routines need this
; Get line height, etc. for font
SubQ #8,SP ; make room for font info stuff
Move.L SP,-(SP) ; push address
_GetFontInfo
Move (SP)+,D0 ; get ascent
Move D0,D1
Add (SP)+,D1 ; add descent
AddQ #2,SP ; skip max wid
Add (SP)+,D1 ; add leading
Move.L (SP)+,A0
Rts
; ----------------------------------------------------------------------
; PROCEDURE TECalText{ ( h: TEHandle ) };
; When the user installs his own text handle/rectangle in the record,
; this routine should be called to calibrate the line array to it
; ----------------------------------------------------------------------
CalText
Move.L teSelStart(A3),-(SP) ; save selStart/End
Clr teSelStart(A3) ; recall from beginning
; The delta must be 32,767 for the recalibration to work correctly when the insert length
; is 32,767 and the text length is 0. (an arbitrarily large negative number won't do).
Move #$8001,D7 ; fake delta(large - number)
Clr.L teLines(A3) ; insure total recal
Bsr ReCalLines ; redo the line stuff
Move.L (SP)+,teSelStart(A3) ; restore selStart/End
Rts
TECalText
Bsr StdEntry
Bsr.S CalText ; <C971/RWW102887>NO
epilog4
MoveQ #4,D0
; fall into std exit
; ----------------------------------------------------------------------
; Std Exit assumes original argument is good
StdExit
Move.L inHandle(A6),A4 ; Place handle into A4
Bra.S RealExit
; ** <C105/29aug86/MBK> ** For style routines, which also have a routine
; selector on the top of the stack
StdExit2 Move.L inHandle+2(A6),A4 ; Place handle into A4
RealExit Move.L (A4),A3 ; re-dereference it
Move D0,D4 ; save strip amount
Move.L teTextH(A3),A0 ; get text handle
Move.B saveTH(A6),D0 ; get the text handle flags
_HSetState ; set up the handle
Move.L saveClip(A6),-(SP)
Move.L (SP),-(SP)
_SetClip ; restore caller's clip
_DisposRgn ; and dispose of our copy
Move.L A4,A0 ; get the handle
Move.B saveHandle(A6),D0 ; get the handle's flags
_HSetState ; restore the handle
Pea saveColor(A6) ; set foreground color ** <C182/6oct86/MBK> **
;; If forRAM THEN
If (not forROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; are we on a color system? (as per Jerome) <C971/RWW112487>
Bnz.S @1 ; Nope <C971/RWW112487>
_RGBForeColor ; <C971/RWW112487>
Move.L (A4),A3 ; <C971/RWW112487>
Bra.S @2 ; <C971/RWW112487>
@1 Bsr RGBForeColor ; <C971/RWW112487>
@2
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
_RGBForeColor ; for Ikki ** <C182/6oct86/MBK> **
Move.L (A4),A3 ; restore ptr just in case ** <C597/06jan87/MBK> **
Else
Bsr RGBForeColor ; for Alladin ** <C182/6oct86/MBK> **
EndIf
Move.L teGrafPort(A3),A0 ; restore GrafPort stuff
Move.W saveSize(A6),txSize(A0) ; restore Grafport's size
Move.W saveFace(A6),txFace(A0) ; restore Grafport's face
Move.W saveFont(A6),txFont(A0) ; restore Grafport's font
Move.L savePort(A6),-(SP) ; restore port to user's passed
_SetPort
Move D4,D0 ; restore strip amount
Std2Exit
MoveM.L (SP)+,D2-D7/A2-A4 ; restore regs
Unlk A6
Move.L (SP)+,A0 ; remove return add
Add D0,SP ; strip parameters
Jmp (A0)
; ----------------------------------------------------------------------
; PROCEDURE TESetSelect{ ( selStart, selEnd: LONGINT; h: TEHandle ) };
; Sets the current select range
; ----------------------------------------------------------------------
TESetSelect
Bsr StdEntry
Bsr ClearRsrved ; clear out reserved style
Bsr HideCaret
Bsr HiLite
Move 14(A6),teSelEnd(A3) ; Jam the selection end
Move 18(A6),teSelStart(A3) ; jam selStart
Bsr CleanUpSel ; sort and clean up selection
Bsr ShowCaret
Bsr HiLite
Bsr SelView ; insure selection is visible
Bra go12
; ----------------------------------------------------------------------
; FUNCTION TENew{ ( destRect, viewRect: Rect ): TEHandle };
; ----------------------------------------------------------------------
TENew
Link A6,#0
MoveM.L D2-D7/A2-A4,-(SP) ; Save regs
Clr.L 16(A6) ; return NIL
MoveQ #TERecSize,D0 ; Allocate a record
_NewHandle ,CLEAR
Bne badExit ; escape if error <C971/RWW102887>NO
Move.L A0,A4 ; save handle
_HLock ; get object handle and lock it
Move.L (A4),A3 ; dereference it
MoveQ #0,D0 ; get text handle
_NewHandle
Bne badExit ; escape if error <C971/RWW102887>NO
Move.L A0,teTextH(A3)
; Dest and view rect must be together in record
Lea teDestRect(A3),A0 ; point to rects in beginning
Move.L 12(A6),A2 ; Get dest rectangle arg
Move.L (A2)+,(A0)+ ; save away in record
Move.L (A2)+,(A0)+
Move.L 8(A6),A2 ; Get view rectangle arg
Move.L (A2)+,(A0)+ ; save away in record
Move.L (A2)+,(A0)+
; Get line height, etc. for font
Bsr GetSize ; get ascent & hite ** <C207/10oct86/MBK> **
Move.W D0,teAscent(A3) ; save in ascent ** <C207/10oct86/MBK> **
Move.W D1,teLineHite(A3) ; save in line height ** <C207/10oct86/MBK> **
; Get the font and face and save away
Move.L grafGlobals(A5),A2 ; get lisagraf globals and then
Move.L thePort(A2),A2 ; thePort
Move.L A2,teGrafPort(A3) ; save this port
Move.L txFont(A2),teFontStuff(A3) ; save the font/face
Move.L txFont+4(A2),teFontStuff+4(A3) ; save the mode/size
Move.L teWdBreak,teWordBreak(A3) ; Set global word breaker
Lea DefClikProc,A0 ; setup default click proc
Move.L A0,TEClikProc(A3)
Bsr.S InstallIntDispatch ; install new internal dispatch tbl <C971/RWW110387>
Move.L teTextH(A3),A0 ; need to unlock text handle <S555/RWW080488>
_HUnlock ; MyNewHandle locked it <S555/RWW080488>
Move.L A4,A0 ; set up for HUnlock
_HUnlock
Move.L A4,16(A6) ; return handle
@0
MoveQ #8,D0
Bra Std2Exit ; <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE ClearRsrved;
; ** <C851/14Apr87/MBK> **
; I changed teReserved to a handle to the following structure:
; Record
; newReserved : LONGINT;
; nullScrap : stScrpHandle;
; End;
; nullScrap is used to store a style which is set when the
; selection is NIL in iTESetStyle. I store it in the scrap
; format so that it can easily be inserted using PstStylGuts.
; This procedure is called to set the style count to 0 whenever
; the selection is changed.
; ----------------------------------------------------------------------
ClearRsrved
Tst.W teSize(A3) ; record with style?
Bpl.S @0 ; this hdl isn't there if not
Move.L teStylesH(A3),A0 ; get style handle
Move.L (A0),A0 ; deref
Move.L nullStyle(A0),A0 ; get reserved handle
Move.L (A0),A0 ; deref
Move.L nullScrap(A0),A0 ; get handle to scrap for null selection
Move.L (A0),A0 ; deref
Move.W #0,scrpNStyles(A0) ; indicate no style
@0 Rts
; ----------------------------------------------------------------------
; InstallIntDispatch
; <C971/RWW110387>
; Added this code to (quasi-) support tabs
; ----------------------------------------------------------------------
InstallIntDispatch
MoveQ #intDispSize,D0
Bsr MyNewHandle ; Replaces next two lines <S508/RWW080288>
; _NewHandle ; <S508/RWW080288>
; Bne badExit ; <S508/RWW080288>
Move.L A0,teDispatchH(A3) ; install it in the record
Move.L (A0),A0
Lea xEOLHook,A1
Move.L A1,EOLHook(A0)
Lea xDRAWHook,A1
Move.L A1,DRAWHook(A0)
Lea Char2Pixel,A1
Move.L A1,WIDTHHook(A0)
Lea Pixel2Char,A1 ; <C971/RWW111887>
Move.L A1,HITTESTHook(A0) ; <C971/RWW111887>
Clr.L newTEFlags(A0) ; <PMAB381/RWW020488>
Rts
; ----------------------------------------------------------------------
; FUNCTION TEStylNew{ ( destRect, viewRect: Rect ): TEHandle };
; ** Added 5/23/86 by MBK **
; TEStyleNew sets txSize to -1 and stores a handle to the
; style information in txFont, txFace. The LineHeight and
; FontAscent fields are set to -1.
; ----------------------------------------------------------------------
TEStylNew
Link A6,#0
MoveM.L D2-D7/A2-A4,-(SP) ; Save regs
Clr.L 16(A6) ; return NIL
MoveQ #TERecSize,D0 ; Allocate a record
_NewHandle ,CLEAR
Bne badExit ; escape if error <C971/RWW102887>NO
Move.L A0,A4 ; save handle
_HLock ; get object handle and lock it
Move.L (A4),A3 ; dereference it
MoveQ #0,D0 ; get text handle
_NewHandle
Bne badExit ; escape if error <C971/RWW102887>NO
Move.L A0,teTextH(A3)
; Dest and view rect must be together in record
Lea teDestRect(A3),A0 ; point to rects in beginning
Move.L 12(A6),A2 ; Get dest rectangle arg
Move.L (A2)+,(A0)+ ; save away in record
Move.L (A2)+,(A0)+
Move.L 8(A6),A2 ; Get view rectangle arg
Move.L (A2)+,(A0)+ ; save away in record
Move.L (A2)+,(A0)+
; Set size to -1 to indicate this is a stylish record & allocate handle to style
Move.W #-1,teSize(A3) ; set style flag (Go style)
MoveQ #teStylSize,D0 ; min size is for 1 style descriptor
Bsr MyNewHandle ; get handle to style info ** <C381/7nov86/MBK> **
Move.L A0,teStylesH(A3) ; former txFont location
; Get Style Handle for storing font, face, size, and color
MoveQ #stRecSize,D0 ; size of style descriptor
Bsr MyNewHandle ; get StyleHandle <C971/RWW102887>NO
Move.L teStylesH(A3),A2 ; handle to style info
Move.L (A2),A2 ; dereference
Move.L A0,styleTab(A2) ; store handle to styles array
; Get handle to array of largest line height on each line
MoveQ #4,D0 ; Make room for one entry in line height array
Bsr MyNewHandle ; allocate handle to line hites <C971/RWW102887>NO
Move.L A0,A1 ; save handle
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; dereference
Move.L A1,lhTab(A0) ; store line hites handle
; Save the GrafPort and save default style from GrafPort
Move.L grafGlobals(A5),A1 ; get lisagraf globals and then
Move.L thePort(A1),A1 ; thePort
Move.L A1,teGrafPort(A3) ; save this port
Move.W txMode(A1),teMode(A3) ; save the mode
MoveQ #1,D0 ; length of text + 1
Bsr GetDefStyle ; save default style in StyleRec
; Store one entry in line height array
Move.L teStylesH(A3),A0 ; style handle
Move.L (A0),A0 ; dereference
Move.L lhTab(A0),A1 ; handle to line height table
Move.L (A1),A1 ; dereference
Move.L styleTab(A0),A0 ; handle to StyleRec's
Move.L (A0),A0 ; dereference
Move.W stAscent(A0),2(A1) ; save ascent
Move.W stHeight(A0),(A1) ; save line height
Move.W #$FFFF,teAscent(A3) ; won't be used unless somebody
Move.W #$FFFF,teLineHite(A3) ; sets the ascent and line height
Move.L teWdBreak,teWordBreak(A3) ; Set global word breaker
Lea DefClikProc,A0 ; setup default click proc
Move.L A0,TEClikProc(A3)
Bsr.S InitRsrved ; init reserved handle
Bsr InstallIntDispatch ; install new internal dispatch tbl <C971/RWW110387>
Move.L teTextH(A3),A0 ; need to unlock text handle ** <C381/7nov86/MBK> **
_HUnlock ; MyNewHandle locked it ** <C381/7nov86/MBK> **
Move.L A4,A0 ; set up for HUnlock
_HUnlock
Move.L A4,16(A6) ; return handle
@0
MoveQ #8,D0
Bra Std2Exit ; <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE InitRsrved;
; ** <C851/14Apr87/MBK> **
; I changed teReserved to a handle to the following structure:
; Record
; newReserved : LONGINT;
; nullScrap : stScrpHandle;
; End;
; nullScrap is used to store a style which is set when the
; selection is NIL in iTESetStyle. I store it in the scrap
; format so that it can easily be inserted using PstStylGuts.
; This procedure is called to create the nullStyle handle.
; ----------------------------------------------------------------------
InitRsrved
Move.L A2,-(SP) ; save reg
MoveQ #nullStSize,D0 ; size of reserved handle
Bsr.S MyNewHandle ; NewHandle with error checking
Move.L teStylesH(A3),A2 ; get style handle
Move.L (A2),A2 ; deref
Move.L A0,nullStyle(A2) ; store new handle
; <S508/RWW062388> MyNewHandle could thrash the heap. Gotta save this handle for later.
Move.L A0,-(SP) ; Save off the handle <S508/RWW062388>
MoveQ #scrpRecSize+2,D0 ; size of scrap handle
; what? AddQ #2,D0 ; include room for # of styles <C971/RWW102687>
Bsr.S MyNewHandle ; NewHandle with error checking
; <S508/RWW062388> This pulls off the nullStyle handle we saved a few lines ago.
; not needed. Move.L nullStyle(A2),A2 ; get reserved handle
Move.L (SP)+,A2 ; Retrieve nullStyle handle <S508/RWW062388>
Move.L (A2),A2 ; deref
Move.L A0,nullScrap(A2) ; store new scrap handle
; what? Move.L nullScrap(A2),A0 ; get handle to scrap for null selection <C971/RWW102687>
Move.L (A0),A0 ; deref
Move.W #0,scrpNStyles(A0) ; indicate no style
Move.L (SP)+,A2 ; restore reg
Rts
; ----------------------------------------------------------------------
; PROCEDURE MyNewHandle
; ** <C381/7nov86/MBK> **
; MyNewHandle unlocks the TEHandle and the text handle, attempts
; to allocate memory for a handle, calls system error if there is one,
; And otherwise relocks TEHandle and the text handle.
; Entry:
; D0: requested handle size
; A3: Ptr to TERec
; A4: Handle to TERec
; Exit:
; A0: the handle
; A3: Could have a different value if memory was shifted
; ----------------------------------------------------------------------
MyNewHandle
Move.L D0,-(SP) ; save input
Move.L teTextH(A3),A0 ; text handle
_HUnlock ; make it easy to get memory
Move.L A4,A0 ; TEHandle
_HUnlock ; make it easy to get memory
Move.L (SP)+,D0 ; get the input
_NewHandle ; do it
Bne badExit ; fly away if system error
Move.L A0,-(SP) ; save handle
Move.L A4,A0 ; get TEHandle
_HLock ; relock it
Move.L (A4),A3 ; reset TEPtr
Move.L teTextH(A3),A0 ; text handle
_HLock ; lock that too
Move.L (SP)+,A0 ; restore handle
Rts
; ----------------------------------------------------------------------
; PROCEDURE TEUpdate( r: Rect; h: TEHandle )
; Redraws the entire object sected by r
; ----------------------------------------------------------------------
TEUpdate
Bsr StdEntry
Move.L (A2)+,A0 ; get rect
Bsr Refresh
Bra epilog8
; ----------------------------------------------------------------------
; A local cover for do find called from TEClick
; This takes a character index in D6 and expands it into D0,D1
; For character select mode, it simply copies it into D0,D1, but
; for word select, it locates the surrounding word and returns
; D0,D1 pointing to the word start and end(Respectively)
; Long at D5 negative if word select
; ----------------------------------------------------------------------
ClickExpand
Move D6,D0 ; default for no-word select
Move D6,D1
Tst.L D5 ; see if word select (if negative)
Bpl.S byebye
Bsr FindWord ; find word @D0
byebye
Rts
; ----------------------------------------------------------------------
; PROCEDURE HiLite;
; A3 is dereferenced object
; Now this pins the selStart and selEnd to the viewRect lines
; ----------------------------------------------------------------------
HiLite
Tst.B teActive(A3) ; don't do if not active
Beq.S byebye
MoveM teSelStart(A3),D3-D4 ; disp start is D3, disp end is D4
MoveQ #teMark,D7 ; set mark mode
Bra DoText ; Remove old selection
; ----------------------------------------------------------------------
; PROCEDURE TEClick( pt: Point; extend: BOOLEAN; h: TEHandle );
; Uses:
; D6 as a character index corresponding to the current mouse point
; D5 a copy of the previous D6
; D5 long sign minus if word select
; A2 anchor left point for hilighting selection
; A4 anchor right for hilighting selection
; D0 for left of word at click spot
; D1 for right of word at click spot
; D3 split dispStarts for left and right piece of highlight
; D4 split dispEnds for left and right piece of highlight
; ----------------------------------------------------------------------
TEClick
Bsr StdEntry
Bsr ClearRsrved ; clear out reserved style
; Find the new point and get index of it in D6
Move.L 14(A6),teSelPoint(A3) ; pass selPoint
Bsr DoFind ; juggle dispStart/End and do find
Bsr HideCaret ; Remove caret
SubQ #4,SP ; make room for the tickCount
_TickCount
Move.L (SP)+,D0 ; Ticks in D0
Sub.L teClikTime(A3),D0 ; see if double click
Cmp.L doubleTime,D0 ; 1/2 second click time
Sle D5 ; D5 = 0 if single click
Cmp teClikLoc(A3),D6 ; see if same location
Seq D1
And.B D1,D5 ; D5 ST if double click
RoR.L #8,D5 ; get switch in high D5
Move D6,teClikLoc(A3) ; double click only if not moved
; D6 now contains the character location at which to look
; Find out if we want an extended selection or a normal one
; For an extended selection, fake out the loop below by fooling it into thinking
; we've already entered it "normally" but with the old selection already
; hilighted, etc.
Tst.B 12(A6) ; see if extend flag is on
Beq.S notExtended
MoveM teSelStart(A3),D0-D1 ; get old selection
Cmp D6,D0 ; chk side of new loc
Bhs.S useRight
Move D0,A2 ; save anchor left
Move D0,A4 ; and anchor right
Bra.S goToIt
useRight
Move D1,A2 ; save anchor left
Move D1,A4 ; and anchor right
goToIt
Move D6,D5
Bra.S goSelect
notExtended
Bsr.S HiLite ; Remove old selection
MoveQ #teWordSelect,D2 ; say "ClickExpand, word selection" <EHB 01Oct85>
Bsr.S ClickExpand ; <C971/RWW102887>NO
; D0/D1 now contain the "bounds" of this click
MoveM D0-D1,teSelStart(A3)
Move D0,A2 ; save anchor left
Move D1,A4 ; and anchor right
Move D6,D5 ; save "old" D6
; remember whether initial click was to left or right of character
Move.B teLftClick(A3),teLftCaret(A3)
Bsr ShowCaret ; feedback to user
Bsr HiLite
waitLoop
Move.L teClikProc(A3),D0 ; call the click proc
Beq.S noClikProc
Move.L D0,A0
Jsr (A0)
Beq.S done1 ; if returns zero abort drag
noClikProc
Clr -(SP) ; make room for result
_WaitMouseUp ; see if button still down
Tst (SP)+ ; pop result, check only the significant byte <3> - <4>
Beq.S done1
Pea teSelPoint(A3) ; pass address for point
_GetMouse
Bsr.S DoFind ; juggle dispStart/End and do find
Cmp D6,D5 ; see if change
Beq.S waitLoop
Bsr HideCaret
; There was a change so highlight only the new part. This is a really tricky part...
; The thing we're trying to do is is highlight only the part that changes of the
; selection which is being dragged out in this loop
goSelect
MoveQ #teWordDrag,D2 ; say "ClickExpand, word dragging"
Bsr ClickExpand ; Get new points
Lea teSelEnd(A3),A0 ; point between selStart/End
Cmp D6,A4 ; see if less than anchor right
Blo.S notToLeft ; skip if not to left of anchor
Move -(A0),D3 ; save previous left
Move D0,(A0)+ ; save new left
Move D0,D4 ; save dispEnd too
Swap D3
Swap D4
Move A4,D3 ; save other dispStart
Move (A0)+,D4 ; save other dispEnd
Move A4,-(A0)
Bra.S hiliteIt
notToLeft
Cmp D6,A2 ; see if greater than anchor left
Bhi.S keepWaiting ; skip if not to right of anchor
Move (A0)+,D3 ; save previous right
Move D1,-(A0) ; save new right
Move D1,D4 ; save dispEnd too
Swap D3
Swap D4
Move -(A0),D3 ; save other dispEnd
Move A2,D4 ; save other dispStart
Move A2,(A0)+
hiliteIt
MoveQ #teMark,D7 ; set mark mode
Bsr DoText ; do one half
Swap D3 ; get other dispStart/End
Swap D4 ; and hilight too
Bsr DoText ; and other half
keepWaiting
Move D6,D5 ; save new end
Bra.S waitLoop ; continue on
done1
Bsr ShowCaret ; redisplay caret
; ** <C139/23Sep86/MBK> ** Save tick count at the end of TEClick so that
; extra TextEdit computing time will not be counted between clicks
SubQ #4,SP ; make room for the tickCount
_TickCount
Move.L (SP)+,teClikTime(A3) ; remember click time
epilog10
MoveQ #10,D0
Bra StdExit
; ----------------------------------------------------------------------
; DoFind
; Take the teSelPoint(A3) and return D6 w/corresponding char index
; Exit
; D6 contains the selection index returned from DoText
; ----------------------------------------------------------------------
DoFind
; find out which text line it's on
Move teSelPoint+v(A3),D0 ; i:=(selPoint.v-destRect.top)
Bsr PtToLine ; line index in D0
Bge.S southPole ; below the last line
Add D0,D0 ; double D0
Bpl.S noPole ; default if i < 0 is D6 = 0
northPole
MoveQ #0,D6 ; if above point to beginning
Rts
southPole
Move teLength(A3),D6 ; return index(t):=length
Rts
noPole
MoveM teLines(A3,D0),D3-D4 ; dispStart := lines[i]
MoveQ #teFind,D7 ; set find mode
Bsr DoText ; return index(t) in D0
Move D0,D6 ; return in D6
Rts
; ----------------------------------------------------------------------
; Pixel2Char
; ** Added 6/18/86 MBK **
; Entry:
; D0.W: length of block
; D1.W: pixel width relative to start of block
; D2.W: slop
; A0: ptr to start of block
; Exit:
; D0 (low word) pixel width to last offset
; (high word) boolean = TRUE if offset corresponding to
; the given pixel width was found
; D1.W: character offset
; D2.W: flagged if hit on left of char
; ----------------------------------------------------------------------
Pixel2Char
Move.L jPixel2Char,-(SP) ; call the Pixel2Char Routine
Rts
vPixel2Char ; here's our Pixel2Char
MoveM.L D3-D4/A4,-(SP)
Move.W D1,D3 ; save pixel width
MoveQ #0,D4 ; clear whole register ** <C381/5nov86/MBK> **
Move.W D0,D4 ; save count
AddQ #1,D0 ; plus 1 for measure
Ext.L D0 ; should be long
Add.L D0,D0 ; double for words
Move.L D0,D1 ; save in D1 ** <C381/5nov86/MBK> **
; ** <C207/16oct86/MBK> ** try to get room on the stack; if not available,
; make a last ditch effort with NewPtr
_StackSpace ; get stack size ** <C381/5nov86/MBK> **
Sub.l d1,d0 ; stack, use newPtr ** <C381/5nov86/MBK> **
Cmp.l #1024,d0 ; ** <C381/5nov86/MBK> **
Blt.s tryHeap
Sub.l d1,sp ; push the array. ** <C381/5nov86/MBK> **
Move.l sp,a4 ; save the array pointer
Bra.S onStack
tryHeap
Move.L D1,D0 ; RESTORE size ** <C574/30dec86/MBK> **
Move.L A0,-(SP) ; save text ptr ** <C381/5nov86/MBK> **
_NewPtr ; for array of char widths
Move.L A0,A4 ; save ptr to array
Move.L (SP)+,A0 ; restore text ptr ** <C381/5nov86/MBK> **
; Must save ptr for the dispose, because A4 will be modified.
Move.L A4,-(SP) ; save ptr for dispose
MoveQ #0,D1 ; to say newPtr was used ** <C381/5nov86/MBK> **
Tst.W D0 ; check result code ** <C381/5nov86/MBK> **
Beq.S onStack ; continue if no error ** <C381/5nov86/MBK> **
Move.W #dsMemFullErr,D0 ; memory full error ** <C485/03dec86/MBK> **
_SysError ; else call _SysError ** <C381/5nov86/MBK> **
onStack Move.L D1,-(SP) ; save buffer size ** <C381/5nov86/MBK> **
Move.W D4,-(SP) ; length of block
Move.L A0,-(SP) ; ptr to text
Move.L A4,-(SP) ; ptr to charLocs
_MeasureText ; measure all at once
Move.W D4,D1 ; get count
Add.L D4,D4 ; mult count by 2
Add.L D4,A4 ; pt to 1 beyond last entry ** <C381/5nov86/MBK> **
Cmp.W (A4),D3 ; pt within width?
; This is to fix the following bug: if you clicked the mouse EXACTLY at
; the end of a line (ended by a CR), the selection was set to the character
; following the CR, instead of preceding it.
Bge.S @2 ; quit if not
@0 Cmp.W -(A4),D3 ; pt within width?
Bge.S @1 ; quit if so
SubQ #1,D1 ; dec the count
Bne.S @0 ; keep trying
AddQ #1,D1 ; adjust for later decrement
@1 Move.W 2(A4),D2 ; width to right of offset
Move.W (A4),D4 ; width to left of offset
Sub.W D4,D2 ; get difference
AsR.W #1,D2 ; divide by 2
Add.W D2,D4 ; width to middle of last char
MoveQ #1,D0 ; point was found
Swap D0 ; store flag in high byte
MoveQ #0,D2 ; assume right
Cmp.W D4,D3 ; compare to pixel width
Bge.S @3 ; left if pixel width is less
MoveQ #1,D2 ; else it's to the left
Bra.S @3
@2 MoveQ #0,D0 ; found flag is false
MoveQ #0,D2 ; right of offset
@3 Move.W (A4),D0 ; return pixel width
Move.L (SP)+,D3 ; stack or heap?
Beq.S @4 ; 0 means heap
Add.L D3,SP ; else fix the stack
Bra.S @5
@4
Move.L (SP)+,A4 ; restore ptr for dispose
MoveM.L D0-D2,-(SP) ; save stuff
Move.L A4,A0
_DisposPtr ; dispose of char widths array
MoveM.L (SP)+,D0-D2 ; restore stuff
@5 MoveM.L (SP)+,D3-D4/A4
Rts
; ----------------------------------------------------------------------
; DoSearch
; ** Rewritten 6/18/86 MBK **
; ----------------------------------------------------------------------
DoSearch
; ** <C139/10Sep86/MBK> ** Modified to call Preamble to get A2; the index
; is in D0, but don't use it since it's not
; documented in Inside Mac
Bsr Preamble ; get A2 from D3
Move (A2),D3 ; set left anchor <14Jan86>
Move D3,D4 ; init char counter
Bsr LineRect ; set rLine to A2 line
Move (A2),D7 ; set left anchor
Move.W teSelPoint+h(A3),D5 ; get h coord
Sub.W teSelRect+left(A3),D5 ; subtract justification
Move teSelRect+left(A3),teSelRect+right(A3) ; init right side to left
Move.W #$8002,teSelRect+left(A3) ; bogus left
Move.W 2(A2),D6 ; end of line
Tst.W teSize(A3) ; check style flag
Bmi.S @0
MoveQ #1,D2 ; just 1 style
Move.W D3,D1 ; start of line
Move.W D6,D0 ; whole line
Bra.S @3
@0 Move.W D3,D0 ; get selection start!!!
Move.W D6,D1 ; end of line
Bsr Get1stStyle ; get 1st style (depending on teSysJust)
Move.L A0,A2 ; preserve ptr to current style
Move.W D0,D2 ; preserve # of styles
Move.L teStylesH(A3),A0 ; handle to style info ** <C381/6nov86/MBK> **
_HLock ; lock it up ** <C381/6nov86/MBK> **
Move.L A2,A0 ; restore style ptr ** <C381/6nov86/MBK> **
@1 Move.L A0,A2 ; save ptr to style start
Bsr SetStyle ; set the style
Move.W startChar(A0),D1 ; get start of style
AddQ.L #stStartSize,A0 ; pt to next style
Move.W startChar(A0),D0 ; start of next style
Cmp.W D3,D1
Bhs.S @2 ; made this unsigned ** <C381/6nov86/MBK> **
Move.W D3,D1 ; reset if needed
@2 Move.W D1,D7
Cmp.W D0,D6 ; compare to end of line
Bhs.S @3 ; made this unsigned ** <C381/6nov86/MBK> **
Move.W D6,D0 ; set end of style to end of line
@3 Move.W D2,-(SP)
Sub.W D1,D0 ; length
Move.L teTextH(A3),A0 ; handle to text
Move.L (A0),A0 ; dereference
AddA.W D1,A0 ; add offset to start of line
Move.W D5,D1 ; get pixel offset
MoveQ #0,D2 ; slop ** <C139/22Sep86/MBK> **
; Bsr Pixel2Char ; measure all at once
Bsr.S TEHitTestHook ; call our hook instead <C971/RWW111887>
Add.W D0,teSelRect+right(A3) ; update selRect
Sub.W D0,D5 ; update pixel offset
Add.W D1,D7 ; update char offset
Swap D0 ; get flag
Tst.W D0 ; pixel to left of offset?
Bne.S HitIt ; point was found
Add.W D1,D4 ; current position
Cmp.W D4,D6 ; reached end of line?
Bls.S @4 ; made this unsigned ** <C381/6nov86/MBK> **
Move.L A2,A0 ; ptr to current style
Move.W (SP)+,D2 ; restore style count
Bsr GetNextStyle ; get next one based on teSysJust
SubQ #1,D2 ; dec # of styles
Bne.S @1 ; keep looping if more <C971/RWW102887>NO
MoveQ #1,D7 ; decremented below
Bra.S findLeft ; force to loc 0 on left
@4 Move.W #$7FFE,teSelRect+right(A3) ; else store bogus right
MoveQ #0,D2 ; assume right
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
; ** <C971/RWW110387> Added this code to support tabs
; Cmp.B #$0D,-1(A0,D7) ; get the last charleft
Move.B -1(A0,D7),D0 ; THESE TWO LINES REPLACE PREVIOUS <C971/RWW110387>
Bsr.S TEEolHook ; <C971/RWW110387>
Bne.S hitIt ; must be right
MoveQ #1,D2 ; else set left if CR
hitIt
AddQ.L #2,SP ; remove count from stack
SF teLftClick(A3) ; assume to right
Tst.W D2 ; left or right?
Beq.S findDone
findLeft SubQ #1,D7 ; adjust result to left half
ST teLftClick(A3) ; mark it to left
findDone
Tst.W teSize(A3) ; check style flag
Bpl.S @5
Move.L teStylesH(A3),A0 ; handle to style info
_HUnlock ; unlock it
@5 Move D7,D0 ; return in D0
Bra doBye
; ----------------------------------------------------------------------
; TEEolHook
; <C971/RWW110387>
; This vectored routine was added to make life simpler for those who
; wanted to add tabs to TextEdit. We won't officially support it,
; but it's here for people who need it.
; ----------------------------------------------------------------------
TEEolHook
Move.L teDispatchH(A3),A0
Move.L (A0),A0 ; get at table
Move.L EOLHook(A0),A0
Jmp (A0)
; ----------------------------------------------------------------------
; xEOLHook
; <C971/RWW110387>
; Actual routine that tests character as end-of-line character. Stock
; version only checks for CR. To support tabs you'd add a
; test for TAB here as well, and then determine if the TAB puts
; you over the length for “end of line”.
; ENTRY: D0.B = character to check
; ----------------------------------------------------------------------
XEOLHook Cmp.B #$0D,D0 ; is it a CR?
Rts ; return with telltale CCR
; ----------------------------------------------------------------------
; TEWidthHook
; <C971/RWW110387>
; Added hook for those needing to intercept the measurement of a line
; Stock version only calls Char2Pixel. To support tabs, you'd check
; the selection to be measured for tabs and add in the appropriate
; tab widths.
; ENTRY: A0.L => Text to measure
; D0.W = Length of text to be measured
; D1.W = Offset into text
; D2.L = Slop (low word)
; Hilite flag (high word)
; EXIT: D1.W = Width of measured text
; ----------------------------------------------------------------------
TEWidthHook
Move.L teDispatchH(A3),A1
Move.L (A1),A1
Move.L WIDTHHook(A1),A1
Jmp (A1)
; ----------------------------------------------------------------------
; TEHitTestHook
; <C971/RWW111887>
; Added hook for those needing to intercept hit testing on a line
; Stock version only calls Pixel2Char. To support tabs, you'd check
; the selection to be tested and add in the appropriate tab widths.
; ENTRY: A0.L => ptr to start of block
; D0.W = Length of block
; D1.W = Pixel width relative to start of block
; D2.L = Slop
; EXIT: D0.L = Pixel width to last offset (low word)
; BOOLEAN = TRUE if offset corresponding to
; the given pixel width was found (high word)
; D1.W = Character offset
; D2.W = Flagged if hit on left of char
; ----------------------------------------------------------------------
TEHitTestHook
Move.L teDispatchH(A3),A1
Move.L (A1),A1
Move.L HITTESTHook(A1),A1
Jmp (A1)
; ----------------------------------------------------------------------
; TEDrawHook
; <C971/RWW110387>
; Added hook for those needing to intercept the drawing of a line
; ----------------------------------------------------------------------
TEDrawHook
Move.L teDispatchH(A3),A1
Move.L (A1),A1 ; get at table
Move.L DRAWHook(A1),A1
Jmp (A1)
; ----------------------------------------------------------------------
; xDRAWHook
; <C971/RWW110387>
; Actual routine that does drawing. Stock version only does _DrawText.
; To support tabs, you'd check the selection to be drawn for tabs,
; and take appropriate action on the intervening pieces.
; ENTRY: A0.L => text to draw
; D0.W = starting character
; D1.W = length to draw
; ----------------------------------------------------------------------
xDRAWHook Move.L A0,-(SP)
Move.W D0,-(SP)
Move.W D1,-(SP)
_DrawText
Rts
; ----------------------------------------------------------------------
; DoDraw
; ** Rewritten 6/18/86 by MBK **
; Given display start and end in [D3..D4], this draws the text
; ----------------------------------------------------------------------
DoDraw
Bsr PinDisplay
Bsr Preamble ; set rLine to A2 line
; ** <C105/14aug86/MBK> Only call LineRect at start to avoid height search **
Bsr LineRect
@0 Bsr PrepLine ; pin D4 at line end
Bls doBye ; done...
Bsr ChkBounds ; extend bounds if necessary
Tst.W teSysJust ; reverse order?
Beq.S @05 ; no, normal
Move.W #$8002,teSelRect+left(A3) ; else, set unbound left
@05 Move.W D4,D6 ; selEnd
Bsr DoErase ; to fix italics problem** <C182/2oct86/MBK> **
Move.W saveLeft(A6),-(SP) ; saved true left value ** <C105/18aug86/MBK> Got rid of rTrue **
Move.W teSelRect+top(A3),-(SP) ; position pen
Move teAscent(A3),D0
Tst.W teSize(A3) ; check style flag
Bmi.S @1
; record has no style, so draw all at once (the old way)
Add D0,(SP) ; drop pen to baseline
_MoveTo
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
Add.L D3,A0 ; offset pointer
; ** <C971/RWW110387> Added code to support tabs
; Move.L A0,-(SP) ; pass pointer
; Clr -(SP) ; no offset
; Move D4,-(SP) ; range
; Sub D3,(SP) ; draw amt := range-i
; _DrawText ; draw it
Clr.W D0 ; D0-D1 aren't a concern, since… <C971/RWW110387>
Move.W D4,D1 ; …one would expect _DrawText… <C971/RWW110387>
Sub.W D3,D1 ; …to blow them away anyways <C971/RWW110387>
Bsr.S TEDrawHook ; go draw it <C971/RWW110387>
Bra.S @6 ; <C971/RWW102887>NO
; record has style, so draw one style at a time
@1 Tst.W D0 ; check default ascent
Bpl.S @2 ; use it if set
Bsr PtrToLine ; get line #
Ext.L D0 ; make it long just in case ** <C381/6nov86/MBK> **
LsL.L #2,D0 ; mult by 4 ** <C381/6nov86/MBK> **
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; deref
Move.L lhTab(A0),A0 ; array of max hite indeces
Move.L (A0),A0 ; deref
Move.W 2(A0,D0.L),D0 ; max ascent
@2 Add D0,(SP) ; drop pen to baseline
_MoveTo
Move.W D3,D0 ; start offset
Move.W D4,D1 ; end of selection
; ** <C105/13aug86/MBK> Changed to Get1stStyle for International **
Bsr Get1stStyle ; get its style
Move.W D0,D2 ; save style count
@3 Move.L A0,A4 ; ptr to style
Bsr SetStyle ; set style
Move.W startChar(A0),D0 ; get start of style
AddQ #stStartSize,A0 ; ptr to next style
Move.W D6,D4 ; init to end of line
Cmp.W startChar(A0),D6 ; compare to end of line
Blo.S @4
Move.W startChar(A0),D4 ; set to end of style
@4 Move.W D2,-(SP) ; save the count
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
Cmp.W D3,D0
Bhs.S @5 ; made this unsigned ** <C381/6nov86/MBK> **
Move.W D3,D0 ; reset if needed
@5 AddA.W D0,A0 ; offset pointer
; ** <C971/RWW110387> Added code to support tabs
; Move.L A0,-(SP) ; pass pointer
; Clr -(SP) ; no offset
; Move D4,-(SP) ; range
; Sub D0,(SP) ; draw amt := range-i
Move.L teStylesH(A3),A1 ; get style handle
Move.L (A1),A1
Sub.L A1,A4 ; save as an offset
; _DrawText ; draw it
Move.W D4,D1 ; amount := range - i <C971/RWW110387>
Sub.W D0,D1 ; <C971/RWW110387>
Clr.W D0 ; no offset <C971/RWW110387>
Bsr TEDrawHook ; go draw it <C971/RWW110387>
; Unlock the style handle when through with pointer.
Move.L teStylesH(A3),A1 ; get style handle
Move.L (A1),A1
Add.L A1,A4 ; restore as pointer
Move.L A4,A0 ; ptr to style
Move.W (SP)+,D2 ; restore the count
Bsr GetNextStyle ; get next based on teSysJust
SubQ #1,D2 ; dec the style counter
Bne.S @3 ; must be more than 1 line
; ** <C105/14aug86/MBK> NextLineRect will not search for height from start **
@6 Bsr PtrToLine ; convert A2 to line #
AddQ #1,D0 ; next line
Bsr NextLineRect ; set next line's rect
Move (A2),D3 ; get start
Bra @0 ; keep going
doBye
MoveM.L (SP)+,D2-D7/A2-A4 ; restore regs
Unlk A6 ; unlink DoText frame
Move.L grafGlobals(A5),A0 ; get the port in A0 for
Move.L thePort(A0),A0 ; compatibility
Rts
; ----------------------------------------------------------------------
; DoErase
; ** <C182/2oct86/MBK> **
; DoErase was added to solve the problem of half the previous
; character getting erased when an EraseRect is done before
; drawing the current character. (This is a problem for Italics
; And certain special fonts). In DoErase, if the offset is the
; same as the line start, I still erase the whole line, in case
; of a change in line height (and the offset must be the same as
; a line start if the line height has changed); otherwise, I
; don't erase the previous character since it's going to be
; drawn over anyway.
; Entry:
; D3: start offset
; A2: line start
; ------------------------------------------------------------------------
DoErase
Move.W teSelRect+left(A3),-(SP) ; save left side for draw
Cmp.W (A2),D3 ; at start of line?
Beq.S @2 ; don't worry if so
; If the mode is XOR, we must erase the previous character as well as redrawing it.
; Redrawing the character in XOR without erasing it first just erases it. This means
; the italics problem will not be fixed in this mode.
Cmp.W #srcXor,teMode(A3) ; is drawing mode XOR?
Beq.S @2 ; do it the old way if so
Tst.W teSize(A3) ; TERec with style?
Bpl.S @1 ; skip style setup if not
Move.W D3,D0 ; selection start
Move.W D0,D1 ; don't care about end
Bsr.S Get1stStyle ; 1st style on line <C971/RWW102887>NO
Bsr SetStyle ; set the port
@1 SubQ.L #2,SP ; room for result
Move.L teTextH(A3),A0 ; text handle
Move.L (A0),-(SP) ; ptr on stack
Move.W D3,-(SP) ; offset to current char
Move.W #1,-(SP) ; just one char
_TextWidth ; how wide is it?
Move.W (SP)+,D0 ; this wide
; Don't want to erase the prev character because that destroys part of the character
; before it (if it's italics or a kerned font). However, the last pixel should be erased
; in case the application leaves a caret drawn there (like Mac3D does).
Tst.W D0 ; nothing to do if no width ** <C485/04dec86/MBK> **
Beq.S @0 ; else subtract one from char width ** <C485/04dec86/MBK> **
SubQ.W #1,D0 ; to fix caret erase problem ** <C485/04dec86/MBK> **
@0
Add.W D0,teSelRect+Left(A3) ; adjust left
@2 Pea teSelRect(A3) ; erase the expanded rect
_EraseRect
Move.W (SP)+,teSelRect+left(A3) ; restore left side for draw
Rts
; ----------------------------------------------------------------------
; Get1stStyle
; ** <C105/13aug86/MBK> Added for International **
; This returns the 1st style block found on a line of text
; If teSysJust = 0, and the last style block on the line
; otherwise.
; Entry:
; D0: start offset
; D1: End offset
; Exit:
; A0: ptr to style block to be processed 1st
; D0: number of styles between the 2 offsets
; ----------------------------------------------------------------------
Get1stStyle
Bsr GetCurStyle ; get style at start offset
Bsr GetNumStyles ; get # of styles in string
Tst.W teSysJust ; is text left to right?
Beq.S @0 ; if so, that's it
MoveQ #0,D1 ; clear whole register ** <C381/6nov86/MBK> **
Move.W D0,D1 ; else, get # of styles
SubQ.W #1,D1
LsL.L #2,D1 ; * stStartSize ** <C381/6nov86/MBK> **
Add.L D1,A0 ; to pt to last style block ** <C381/6nov86/MBK> **
@0 Rts
; ----------------------------------------------------------------------
; GetNextStyle
; ** <C105/13aug86/MBK> Added for International **
; This returns the next style block found on a line of text.
; If teSysJust = 0, this is the following style block;
; If teSysJust <> 0, this is the preceding style block.
; Entry:
; A0: ptr to current style block
; Exit:
; A0: ptr to next style block
; ----------------------------------------------------------------------
GetNextStyle
Tst.W teSysJust ; is text left to right?
Beq.S @0
SubQ.L #stStartSize,A0 ; no, get preceding style
Bra.S @1
@0 AddQ.L #stStartSize,A0 ; yes, get following style
@1 Rts
; ----------------------------------------------------------------------
; PrepLine
; Given display start and end in [D3..D4], and a line start in
; (A2), this gets the line's rectangle in rLine(A6). Then pins
; D4 at the lineStart of the next line. Then gets the range's
; rectangle in rTrue. And, the expanded rect in teSelRect(A3).
; (It calls range rect to do this). Finally exits with CC's
; Set according to D3 and D5(the length).
; Exit:
; CC's set to relationship of D3 to dispEnd in D5
; ----------------------------------------------------------------------
PrepLine
Move D5,D4 ; get right
Cmp 2(A2),D4 ; pin to right
Blo.S @0
Move 2(A2),D4 ; set to line end
@0
Bsr RangeRect ; get rect from D3 to D4 in teSelRect
Cmp D3,D5 ; finished?
Rts
; ----------------------------------------------------------------------
; Preamble
; Given display start and end in [D3..D4], this first sorts the
; two, and copies D4 into D5. Then, it skips to the lineStart
; entry containing D3. It sets up A2 to point to that line.
; Exit:
; CC's set to relationship of D3 to the next line's start, 2(A2)
; D5 a copy of incoming D4
; ----------------------------------------------------------------------
Preamble
Move.L (SP)+,A0 ; get local RTS
MoveM.L D2-D7/A2-A4,-(SP)
Move.L A0,-(SP) ; replace RTS
Cmp D3,D4 ; sort range
Bhs.S @0
Exg D4,D3 ; swap regs
@0
Cmp teLength(A3),D4 ; pin disp end
Blo.S @1
Move teLength(A3),D4 ; pin disp end
@1
Lea teLines(A3),A2 ; point to line starts
And.L lo16,D4 ; longize D4
Move D4,D5 ; save D5 as limit
And.L lo16,D3 ; longize D3
Beq.S @2 ; skip out if 1st line(for empty rec.)
Move.W D3,D0
Bsr.S GetLine ; get its line ptr <C971/RWW102887>NO
@2
Rts
; ----------------------------------------------------------------------
; GetLine
; Given an offset, find the ptr to the line it's on.
; Entry: D0: offset
; A2: ptr to line from which to start search
; Exit: A2: ptr to line on which offset is found
; ----------------------------------------------------------------------
GetLine
@0 Cmp 2(A2),D0 ; D0 past or at next linestart?
Bls.S @1 ; if at next line start
AddQ #2,A2 ; next lineStart
Bra.S @0
@1
Bne.S @2 ; if AT next line start
AddQ #2,A2 ; next lineStart
@2
Rts
; ----------------------------------------------------------------------
; DoText funnel proc for compatibility
DoText
Move.L teDoText,-(SP)
Rts
XDoText
Link A6,#txtLink ; link frame for DoText procs
Tst D7 ; check dispatch code
Beq DoSearch
Bgt.S DoHilite
Cmp #-1,D7
Beq DoDraw ; fall into doCaret
; ----------------------------------------------------------------------
; DoCaret
; Given display start sets up the caret rect in teSelRect. Note
; all the weird shit it has to do because of caret positioning
; around the end of a line and at the end of the text.
; ----------------------------------------------------------------------
DoCaret
Bsr.S Preamble ; set rLine to A2 line
Tst D3 ; special case @ 1st character <03Nov85> SC
Beq.S @2 ; if so skip all these checks <03Nov85> SC
Cmp (A2),D3 ; right at line start?
Bne.S @2 ; skip if not next-line start
Move teLength(A3),D0 ; are we past last char?
Beq.S @2 ; (and is there a last char?)
Cmp D0,D3 ; are we past last char?
Blo.S @0 ; if not, skip special case
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
; ** <C971/RWW110387> Added this code to support tabs
; Cmp.B #$0D,-1(A0,D3) ; if last char <> CR then...
Move.B -1(A0,D3),D0 ; THESE TWO LINES REPLACE PREVIOUS <C971/RWW110387>
Bsr TEEolHook ; <C971/RWW110387>
Beq.S @2 ; skip the line
Bra.S @1
@0
Tst.B teLftCaret(A3) ; to left?
Bne.S @2 ; skip line pull back if so
@1
SubQ #2,A2 ; skip to previous line
@2
Bsr LineRect ; removed from Prep ** <C105/14aug86/MBK> **
Bsr PrepLine ; get selRect from D3..D4 <C971/RWW102887>NO
Move saveLeft(A6),D0 ; get caret loc
Move D0,teSelRect+right(A3) ; and set in teSelRect
SubQ #1,D0
Move D0,teSelRect+left(A3)
Bra doBye
; ----------------------------------------------------------------------
; DoHilite
; ----------------------------------------------------------------------
DoHilite
Bsr PinDisplay
Bsr Preamble ; set rLine to A2 line
Bsr LineRect ; get top, bottom and just
Bsr PrepLine ; pin D4 at line end
Bls.S @1 ; done... <C971/RWW102887>NO
Bsr.S ChkBounds ; check far left and right <C971/RWW102887>NO
Move.L teHiHook(A3),D0 ; do the inversion via hook if
Bsr InvertHook ; there
Cmp.W 2(A2),D5 ; only 1 line?
Bls.S @1 ; made this unsigned ** <C381/6nov86/MBK> **
Bsr PtrToLine ; get current line #
Move.W D0,D1 ; save it
Move.W D5,D0 ; offset to look for
Bsr GetLine ; get D5 line ptr
Bsr PtrToLine ; convert A2 ptr to line #
AddQ #1,D1
Cmp.W D0,D1 ; get the difference
Beq.S @0 ; no lines inbetween
Move.W D0,-(SP) ; save line #
Exg D0,D1
Move.W teSelRect+bottom(A3),teSelRect+top(A3)
Bsr GetLineHites ; hites from 2nd to last lines
Add.W D0,teSelRect+bottom(A3) ; hite to last line
Move.W #$8002,teSelRect+left(A3) ; far left
Move.W #$7FFE,teSelRect+right(A3) ; far right
Move.L teHiHook(A3),D0
Bsr InvertHook ; hilite it
Move.W (SP)+,D0 ; restore line #
; hilite last line
@0 Bsr.S NextLineRect ; get rectangle for last line <C971/RWW102887>NO
Move.W (A2),D3 ; for chkBounds
Bsr PrepLine ; get left and right
Bls.S @1 ; done...
Bsr.S ChkBounds ; check far left and right <C971/RWW102887>NO
Move.L teHiHook(A3),D0 ; do the inversion via hook if
Bsr InvertHook ; there
@1 Bra doBye
; ----------------------------------------------------------------------
; ChkBounds
; ** <C139/22Sep86/MBK> Added for International **
; The left and right sides of the selection rectangle are
; extended if the line start = the selection start and the
; line end = the selection end, respectively.
; Entry:
; A2 : Ptr to the current line
; ----------------------------------------------------------------------
ChkBounds
Move.W (A2),D0 ; start of line
Move.W 2(A2),D1 ; end of line
Tst.W teSize(A3) ; record with style?
Bpl.S @2 ; skip ahead if not
Tst.W teSysJust ; reverse order?
Beq.S @2 ; this is easy if not
Bsr Get1stStyle ; get actual 1st style
SubQ #1,D0 ; look for end of last style
Bne.S @0
; Reset start and end of line if only 1 style
Move.W (A2),D0 ; reset start of line
Move.W 2(A2),D1 ; end of line
Bra.S @2
; more than 1 style, so find actual start and end line offsets
@0 SubQ #1,D0 ; dec style count
LsL.W #2,D0 ; * stStartSize ** <C381/6nov86/MBK> **
Neg D0 ; negative for subtraction
Move.W startChar(A0,D0),D1 ; start of next-to-last style
Move.W (A2),D0 ; get start of line again
Cmp.W startChar(A0),D0 ; compare to start of style
Bhs.S @2 ; made this unsigned ** <C381/6nov86/MBK> **
Move.W startChar(A0),D0 ; else set to style start
; if block begins at start of line, make left a large negative number
@2 Cmp.W D0,D3
Bne.S @3
Move.W #$8002,teSelRect+left(A3)
; if block ends at end of line, make right a large positive number
@3 Cmp.W D1,D4
Bne.S @4
Move.W #$7FFE,teSelRect+right(A3)
@4 Rts
; ----------------------------------------------------------------------
; NextLineRect
; ** <C105/14aug86/MBK> Added to speed things up **
; LineRect was being called from the line drawing loop in
; DoDraw, and adding up line heights from the 1st line to the
; current one. That was fine for fixed line heights, but too
; slow for variable ones. Now I call NextLineRect from the
; loop to simply set the top of this line from the bottom of
; the previous one, and get the height of this line only to
; Set the bottom. NextLineRect also calls DoJust to set
; the justification.
; Entry:
; D0: Current line #
; Exit:
; A2: Ptr to current line #
; ----------------------------------------------------------------------
NextLineRect
Move.W teSelRect+bottom(A3),teSelRect+top(A3)
Bsr GetHite ; get height of this line
Add.W D1,teSelRect+bottom(A3) ; adjust bottom
; ** <C381/5nov86/MBK> ** Replaced call to LineToPtr with these 2 lines
; since noone else called it
Add.W D0,D0 ; double for word entries ** <C381/5nov86/MBK> **
Lea teLines(A3,D0),A2 ; pt to line starts array ** <C381/5nov86/MBK> **
Move.W teDestRect+left(A3),teSelRect+left(A3)
Bsr.S DoJust ; set the justification <C971/RWW102887>NO
Rts
; ----------------------------------------------------------------------
; PtrToLine
; ** <C105/14aug86/MBK> **
; Get the line # from the A2 value.
; Entry:
; A2: Ptr to current line #
; Exit:
; D0: Current line #
; ----------------------------------------------------------------------
PtrToLine
Lea teLines(A3),A0 ; pt to line starts array
Move.L A2,D0 ; current line ptr
Sub.L A0,D0 ; current line offset
AsR.L #1,D0 ; current line number
Rts
; ----------------------------------------------------------------------
; LineRect
; ** Modified 6/18/86 by MBK **
; Given the line start array in A2, this fills in the rLine(A6)
; With the rectangle for that line except that right = left.
; It adjusts the rect for the current format.
; ----------------------------------------------------------------------
LineRect
Bsr.S PtrToLine ; get line # from A2 <C971/RWW102887>NO
Move.W D0,D1
MoveQ #0,D0 ; from 0 to this line ** MBK 6/18/86 **
Bsr.S GetLineHites ; get height <C971/RWW102887>NO
Lea teDestRect+8(A3),A0 ; point past destRect
Lea teSelRect+8(A3),A1 ; and past stack rect
Move.L -(A0),-(A1)
Move.L -(A0),-(A1)
Add D0,(A1) ; add to top
Move top(A1),bottom(A1)
Move.W D1,D0 ; current line ** MBK 6/18/86 **
Bsr GetHite ; height of this line ** MBK 6/18/86 **
Add D1,bottom(A1) ; add line height to bottom
; now offset to right according to the format
; ** <C105/12aug86/MBK> ** Added the DoJust label for just doing justification
DoJust
; ** <C229/28oct86/MBK> ** Changed to save justification on stack instead of in D2
Move.W teJust(A3),-(SP) ; get justification ** <C105/12aug86/MBK> **
Bne.S @0 ; go process if not left** <C105/12aug86/MBK> **
Move.W teSysJust,(SP) ; check text direction ** <C105/12aug86/MBK> **
Beq.S @2 ; do nothing if left
@0
Cmp.W #teForceLeft,(SP)
Beq.S @2
Bsr LineWidth ; get width of (A2) line in D0
Move teDestRect+right(A3),D1
Sub teDestRect+left(A3),D1
Sub D0,D1
SubQ #1,D1 ; subtract one for caret
Tst.W (SP) ; see what format
Bmi.S @1
AsR #1,D1 ; div by 2 for centering
@1
Add D1,teSelRect+left(A3) ; bump rect over
@2
AddQ #1,teSelRect+left(A3) ; indent for caret
Move teSelRect+left(A3),teSelRect+right(A3)
Move.W teSelRect+left(A3),saveJust(A6) ; left just ** <C105/18aug86/MBK> **
AddQ.L #2,SP ; restore it ** <C105/12aug86/MBK> **
Rts
; ----------------------------------------------------------------------
; PROCEDURE GetLineHites
; ** Added 6/3/86 by MBK **
; Gets the line height of each line from start to end line and
; returns the total of all the line heights. If teLineHite
; has a non-zero value, a fixed line height is used
; for each line. Otherwise, GetLineHites gets the line height
; for each line from the MaxHites array.
; Entry:
; D0 starting line #
; D1 ending line # (Preserved)
; Exit:
; D0 total distance in pixels from top of start line to top of
; End line
; ----------------------------------------------------------------------
GetLineHites
MoveM.L D1-D2,-(SP) ; save stuff
; If this TERec has no style, just use the old teLineHite
Sub.W D0,D1 ; get # of lines
Beq.S @0 ; if none, skip this
Move.W teLineHite(A3),D2 ; get default line hite
; If lineHite is positive, use it no matter what type of TERec.
Bpl.S @0
Tst.W teSize(A3) ; check style flag
Bmi.S @1 ; if not, use TERec value
; somebody set the default, so use fixed line height for all lines
@0 MulU D1,D2 ; * fixed line height
Bra.S @3 ; that was easy! <C971/RWW102887>NO
; Get maximum height on this line from the array
@1 Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; dereference
Move.L lhTab(A0),A0 ; handle to max hites
Move.L (A0),A0 ; dereference
LsL.W #2,D0 ; multiply by 4
AddA.W D0,A0 ; starting line
MoveQ #0,D2 ; line height accumulator
@2 Move.W (A0),D0 ; get line height ** <C105/28aug86/MBK> **
And.W #$7FFF,D0 ; mask out high bit ** <C105/28aug86/MBK> **
Add.W D0,D2 ; accumulate heights
AddQ #4,A0 ; point to next
SubQ #1,D1 ; dec the counter
Bne.S @2 ; keep accumulating
@3 Move.L D2,D0 ; answer in D0
MoveM.L (SP)+,D1-D2 ; restore stuff
Rts
; ----------------------------------------------------------------------
; PROCEDURE GetHite
; ** Added 6/16/86 by MBK **
; Gets the line height of the given line.
; Entry:
; D0 line number
; Exit:
; D1 height of this line
; ----------------------------------------------------------------------
GetHite
; If this TERec has no style, just use the old teLineHite
Move.W teLineHite(A3),D1 ; get default line height
Bpl.S @0 ; use it if set ** <C381/5nov86/MBK> **
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; if not, use TERec value
; Get maximum height on this line from the array
Move.L teStylesH(A3),A0 ; handle to style info ** <C381/5nov86/MBK> **
Move.L (A0),A0 ; dereference ** <C381/5nov86/MBK> **
Move.L lhTab(A0),A0 ; handle to max hites ** <C381/5nov86/MBK> **
Move.L (A0),A0 ; dereference
Move.W D0,D1 ; preserve D0 ** <C381/5nov86/MBK> **
LsL.W #2,D1 ; for 2 word entries ** <C381/5nov86/MBK> **
Move.W 0(A0,D1),D1 ; get height ** <C381/5nov86/MBK> **
And.W #$7FFF,D1 ; mask out high bit ** <C105/28aug86/MBK> **
@0 Rts
; ----------------------------------------------------------------------
; LineWidth
; Measures the width of the line at (A2)..2(A2). Trims break chars
; from the right side
; Entry
; A3 = dereferenced handle to TE object
; Exit
; leaves the width in D0
; ----------------------------------------------------------------------
LineWidth
Move (A2),D6 ; get left anchor
Move 2(A2),D7 ; get right part
MeasD6D7
Move.L teTrimMeasure,-(SP) ; push trimMeasure routine <EHB 01Oct85>
Rts ; and call it <EHB 01Oct85>
XTrimMeasure
Cmp teLength(A3),D6 ; are we past last char?
Beq.S zeroExit ; escape quick <C971/RWW102887>NO
Cmp D6,D7 ; is line empty?
Bls.S zeroExit ; if so, skip trimming(fast exit)<C971/RWW102887>NO
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
@0 SubQ #1,D7 ; look to left
Cmp D6,D7
Beq.S @1 ; assume done if = to left
Cmp.B #$20,0(A0,D7) ; if last char <= space then...
Bls.S @0 ; it's a break
@1 AddQ #1,D7 ; use next char
; fall into MeasureIt ; get width in [D6 to D7)
; ----------------------------------------------------------------------
; MeasureIt
; ** Rewritten 6/20/86 by MBK **
; Entry
; A3 = dereferenced handle to TE object
; Does a TextWidth for teTextH(A3), [D6 to D7]
; Exit
; leaves the width in D0
; ----------------------------------------------------------------------
MeasureIt
Cmp D6,D7 ; nothing to measure?
Bls.S zeroExit ; <C971/RWW102887>NO
MoveM.L D2/D4/D6,-(SP) ; save stuff
And.L lo16,D6 ; longize it
; Skip all the new stuff if style is not set
Tst.W teSize(A3) ; record with style?
Bmi.S @0 ; if not, go do it the old way
Move.W D7,D0 ; end offset
Bsr.S GetWidth ; get string width <C971/RWW102887>NO
Move.W D1,D0 ; return width in D0
Bra.S @3
; Record does have style; get # of styles within selection
@0 MoveQ #0,D4 ; clear accumulator
Move.W D6,D0 ; start of selection
Bsr GetCurStyle ; get current style
Move.W D7,D1 ; end of selection
Bsr GetNumStyles ; # of styles in selection
Move.W D0,D2 ; save # of styles
; Set the GrafPort to the current style
@1 Bsr SetStyle ; set current style
AddQ #stStartSize,A0 ; pt to next style
Move.W startChar(A0),D0 ; start of next style
Cmp.W D0,D7 ; compare to end of selection
Bhs.S @2 ; ok if less
Move.W D7,D0 ; else set to end of selection
; Get the width of this selection
@2 Move.W D2,-(SP) ; save the count
Bsr.S GetWidth ; get string width <C971/RWW102887>NO
; Accumulate total width of the selection
Add.W D1,D4 ; accumulate width
Move.W (SP)+,D2 ; restore the count
Move.W startChar(A0),D6 ; start of next style
SubQ #1,D2 ; dec the style counter
Bne.S @1 ; more styles
Move.W D4,D0 ; return width in D0
@3 MoveM.L (SP)+,D2/D4/D6 ; restore stuff
Rts
zeroExit
MoveQ #0,D0 ; nothing to measure
Rts
GetWidth
Tst.W teSize(A3) ; record with style?
Bpl.S @0 ; if not, A0 is nothing
Move.L teStylesH(A3),A1 ; get style handle
Move.L (A1),A1 ; dereference
Sub.L A1,A0 ; save as offset
@0
Move.L A0,-(SP) ; save A0
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
Move.W D6,D1 ; offset into text
Sub.W D1,D0 ; length
MoveQ #0,D2 ; slop, hilite flag ** <C139/22Sep86/MBK> **
; Bsr.S Char2Pixel ; get width <C971/RWW102887>NO
Bsr TEWidthHook ; THIS LINE REPLACES PREVIOUS <C971/RWW110387>
Move.L (SP)+,A0 ; restore A0
Tst.W teSize(A3) ; record with style?
Bpl.S @1 ; if not, A0 is nothing
Move.L teStylesH(A3),A1 ; get style handle
Move.L (A1),A1 ; dereference
Add.L A1,A0 ; restore as pointer
@1
Rts
; ----------------------------------------------------------------------
; Char2Pixel
; ** <C105/8aug86/MBK> **
; Entry: A0: ptr to text
; D0.W length of text to be measured
; D1.W offset into text
; D2 slop (low word)
; hilite flag (high word)
; Exit: D1.W width of measured text
; ----------------------------------------------------------------------
Char2Pixel
Move.L jChar2Pixel,-(SP) ; call the Char2Pixel Routine <EHB 01Oct85>
Rts
vChar2Pixel ; here's our Char2Pixel
SubQ #2,SP ; room for result
Move.L A0,-(SP) ; pass pointer
Move.W D1,-(SP) ; offset
Move D0,-(SP) ; length
_TextWidth ; get width
Move.W (SP)+,D1 ; resulting width
Rts
; ----------------------------------------------------------------------
; RangeRect
; Given the line rect in rLine(A6), this sets teSelRect to the
; line rect with the left side at the given loc in D3 and the
; right side at D4. If D3 is the first char on the line, it
; ----------------------------------------------------------------------
RangeRect
Cmp.W (A2),D3 ; same as line start?
Bhi.S @0 ; made this unsigned ** <C381/6nov86/MBK> **
Cmp.W 2(A2),D4 ; same as line end?
Blo.S @0 ; made this unsigned ** <C381/6nov86/MBK> **
; Must set D6 in this case (DoMeasure sets it but MeasureIt doesn't)
Move.W (A2),D6 ; set D6 to beg of line ** <C454/21nov86/MBK> **
Move.W D4,D7 ; just need 2nd measure
Bsr MeasureIt ; measure whole line
Add.W D0,teSelRect+right(A3) ; save right side
Bra.S @1 ; done with measuring
@0 Move D3,D7 ; get measure right
Bsr.S DoMeasure ; measure from [D6..D7) <C971/RWW102887>NO
Add D0,teSelRect+left(A3) ; set left
Move D4,D7 ; get 2nd measure right
Bsr.S DoMeasure ; measure from [D6..D7) <C971/RWW102887>NO
Add D0,teSelRect+right(A3) ; save right side
@1 Lea teSelRect(A3),A1
Move.W left(A1),saveLeft(A6) ; just need to save left
Move left(A1),tempRect ; compatibility shit
Move.L botRight(A1),-(SP) ; push pen loc for compatibility
; In the pre-Mac+ version Capps used pnLoc throughout DoText. He added the
; MoveTo here to maintain compatibility with that, but unfortunately in the
; pre-Mac+ version the pnloc is less by line height minus ascent.
; This fixes bug LM-RM-107. Don't worry about new style records since this
; is only for maintaining compatibility with old apps.
;; If forRAM THEN
If (not forROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; are we on a color system? (as per Jerome) <C971/RWW112487>
Bnz.S @2 ; Nope <C971/RWW112487>
EndIf
;; <19Feb89smb> If onNuMac|onMvMac|forRAM THEN ; <C914/29Oct87> rwh
Tst.W teSize(A3) ; if it's a new style record
Bmi.S @2 ; don't have to worry about it
Move.W teLineHite(A3),D0 ; else, get hite - ascent
Sub.W teAscent(A3),D0
Sub.W D0,(SP) ; subtract from pnloc.v
@2
;; <19Feb89smb> EndIf
_MoveTo ; compatibility shit
Rts
; ----------------------------------------------------------------------
; DoMeasure
; ** <C139/22Sep/86> MBK **
; DoMeasure was added to handle reverse justification.
; DoMeasure measures from the actual start of the line
; to the given offset. MeasureIt is still called directly
; when the distance between 2 offsets is desired.
; ----------------------------------------------------------------------
DoMeasure
MoveM.L D3/D5-D6,-(SP)
MoveQ #0,D5 ; width accumulator
Move.W (A2),D6 ; line start
Cmp D6,D7 ; nothing to measure?
Blo.S @4 ; made this unsigned ** <C381/6nov86/MBK> **
Tst.W teSize(A3) ; style record?
Bpl.S @3 ; just do normal measure if not
Tst.W teSysJust ; reverse order?
Beq.S @3 ; just do normal measure if not
Move.W D6,D3 ; start offset
Move.W (A2),D0 ; start of line
Move.W 2(A2),D1 ; end of line
Bsr Get1stStyle ; get actual 1st style on line
Move.W D7,D0 ; end offset
@0 Move.W startChar(A0),D6 ; store actual start of line
Cmp.W D6,D3 ; should not be less than
Bls.S @1 ; made this unsigned ** <C381/6nov86/MBK> **
Move.W D3,D6 ; the selection start
@1 Cmp.W D6,D7 ; if greater than selection end
Blo.S @2 ; then end is not in this style
Move.W D7,D0 ; selection end
Cmp.W stStartSize(A0),D7 ; if less than next style start
Bls.S @3 ; made this unsigned ** <C381/6nov86/MBK> **
@2 Move.W stStartSize(A0),D0 ; else set end as next
Cmp.W 2(A2),D0 ; style start
Bls.S @25 ; made this unsigned ** <C381/6nov86/MBK> **
Move.W 2(A2),D0 ; line's end
@25 Move.W D0,-(SP) ; SetStyle destroys this ** <C229/28oct86/MBK> **
Bsr SetStyle ; set the style
Move.W (SP)+,D0 ; restore length to measure ** <C229/28oct86/MBK> **
Bsr GetWidth ; get string width
Add.W D1,D5 ; accumulate width
SubQ.L #stStartSize,A0 ; pt to prev style
Bra.S @0 ; keep measuring
@3 Bsr MeasureIt ; last measurement
Add.W D0,D5 ; final width
@4 Move.W D5,D0 ; return width in D0
MoveM.L (SP)+,D3/D5-D6
Rts
; ----------------------------------------------------------------------
; PinDisplay
; Pins D3 and D4 to the viewRect
; Expects A3 the usual TE record
; Alternate entry with rect already in A0
; Trashes D0, A0
PinDisplay
Lea teViewRect(A3),A0 ; use viewRect
PinA0Rect
Move top(A0),D0 ; load D0 w/top
Bsr.S PtToLine ; turn into a lineStart
Bge.S @4 ; escape if top gone
Add D0,D0 ; double for array ref.
Blt.S @1
Cmp teLines(A3,D0),D3 ; pin D3 to viewRect.top
Bhs.S @0
Move teLines(A3,D0),D3 ; dispStart = lines[i]
@0
Cmp teLines(A3,D0),D4 ; pin D4 to viewRect.top
Bhs.S @1
Move teLines(A3,D0),D4 ; dispEnd = lines[i]
@1
Move bottom(A0),D0 ; get bottom in D0
SubQ #1,D0
Bsr.S PtToLine
AddQ #1,D0 ; inc line # ** MBK 6/18/86 **
Cmp teNLines(A3),D0 ; compare to max ** MBK 6/18/86 **
Bhi.S @3 ; made this unsigned ** <C381/6nov86/MBK> **
Add D0,D0
Cmp teLines(A3,D0),D3 ; pin D3 to viewRect.bottom
Blo.S @2
Move teLines(A3,D0),D3 ; dispStart = lines[i]
@2
Cmp teLines(A3,D0),D4 ; pin D4 to viewRect.bottom
Blo.S @3
Move teLines(A3,D0),D4 ; dispEnd = lines[i]
@3
Rts
@4
Move D3,D4 ; nothing in range
Rts
; ----------------------------------------------------------------------
; PtToLine
; ** Rewritten 6/13/86 by MBK **
; Entry:
; D0 contains a V coordinate of a point of which we want to find the
; corresponding line index into lineStart array
; Exit:
; D0 contains line index(May be negative)
; CC's set according to D0 vs teNLines
; ----------------------------------------------------------------------
PtToLine
MoveM.L D2/D6-D7/A0,-(SP)
Sub teDestRect+top(A3),D0 ; origin to destRect
Ext.L D0 ; extend to long
Move.W teNLines(A3),D7 ; save total # of lines
Beq.S @4 ; if none, quit now
Move.W teLineHite(A3),D1 ; get default line height
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; if not, do it the old way
Tst.W D1 ; was line height set?
Bmi.S @1 ; wasn't set, so use array
@0 DivS D1,D0 ; else divide by line height
Bra.S @4 ; you're done
@1 Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; dereference
Move.L lhTab(A0),A0 ; max heights per line
Move.L (A0),A0 ; dereference
MoveQ #0,D1 ; init line hite accumulator
Move.W D7,D2 ; get # of lines
@2 Move.W (A0),D6
And.W #$7FFF,D6 ; mask out high bit ** <C105/28aug86/MBK> **
Add.W D6,D1 ; get the height
AddQ.W #4,A0
Cmp.W D1,D0 ; compare to point
Blt.S @3 ; found it
SubQ.W #1,D2 ; dec counter
Bne.S @2 ; more lines to point
@3 Move.W D7,D0 ; total # of lines
Sub.W D2,D0 ; get line index
@4 Cmp D7,D0 ; compare the max # lines
MoveM.L (SP)+,D2/D6-D7/A0
Rts
; ----------------------------------------------------------------------
; Invert Hook
; This calls the passed hook if there, but otherwise uses _InverRect
; Used for carets and selection. The hook passed must remove the
; rect from the stack
; Entry:
; D0 the hook proc in question
; selRect(A3) set up for rectangle in question
; ----------------------------------------------------------------------
InvertHook
; Clear HiliteMode bit to tell QuickDraw to use color highlighting.
; Only do this if a hook is not installed.
Pea teSelRect(A3) ; default selection method
;; If forRAM THEN
If (Not forROM) THEN ; <19Feb89smb>
; we have to do this test, so we have to explicitly check D0.L again rather
; than count on the SR flags coming in being right as in the ROM versions
BTst #14,ROM85 ; on a color system? <C971/RWW112487>
Bnz.S @1 ; <C971/RWW112487>
Tst.L D0 ; does a hook exist?
Bne.S @2 ; yes, go do it
Lea HiliteMode,A0 ; <C971/RWW112487>
BClr #7,(A0) ; <C971/RWW112487>
Bra.S defHilite ; <C971/RWW112487>
@1 Tst.L D0 ; does a hook exist? <C971/RWW112487>
Beq.S defHilite ; no <C971/RWW112487>
@2
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
Bne.S @0
Lea HiliteMode,A0 ; new memory location for hiliting
BClr #7,(A0) ; tell them we want color hiliting
Bra.S defHilite ; do the inversion
@0
Else
Beq.S defHilite ; there, otherwise just invert
EndIf
Move.L D0,A0
Jmp (A0)
defHilite
_InverRect
Rts
; Color highlighting is not to be used on the caret, so I created this separate
; procedure just for caret highlighting.
;; If onNuMac|onMvMac|forRAM THEN ; <C914/29Oct87> rwh
If hasCQD|(Not forROM) THEN ; <19Feb89smb>
CaretHook
Pea teSelRect(A3) ; default selection method
Tst.L D0 ; make absolutely sure! <S487/RWW050288>
Beq.S defHilite ; there, otherwise just invert
Move.L D0,A0
Jmp (A0)
EndIf
; ----------------------------------------------------------------------
; Standard Entry for procs, saves registers and pops handle arg into
; A4 and dereferences it into A3. Points A2 to first parameter
; AFTER the handle.
StdEntry
MoveQ #0,D0 ; not a style trap ** <C105/28aug86/MBK **
StdEntry2
Move.L (SP)+,A0 ; save return address
Link A6,#stdLink ; stack frame
MoveM.L D2-D7/A2-A4,-(SP)
Move.L A0,-(SP) ; push return address back on stack
Tst.W D0 ; is it a style trap? ** <C105/28aug86/MBK **
Beq.S @0 ; if not, skip this ** <C105/28aug86/MBK **
Move.W inHandle(A6),D0 ; get the selector ** <C105/28aug86/MBK **
Lea AddrTable,A0 ; table of addresses ** <C105/28aug86/MBK **
Add.W D0,D0 ; each entry is 2 bytes ** <C381/5nov86/MBK **
Move.W 0(A0,D0),D0 ; get offset to the trap** <C381/5nov86/MBK **
Lea 0(A0,D0),A0 ; get trap's addr ** <C381/5nov86/MBK **
Move.L A0,D3 ; save addr in D3 ** <C381/5nov86/MBK **
Move.L inHandle+2(A6),A4 ; get TEHandle ** <C105/28aug86/MBK **
Bra.S @1
@0 MoveQ #0,D3 ; use D3 as a flag ** <C105/28aug86/MBK **
Move.L inHandle(A6),A4 ; Pop handle into A4
; Modified to use _HGetState ** <C105/5sep86/MBK> **
@1 Move.L A4,A0 ; set up for GetState
_HGetState ; get handle flags
Move.B D0,saveHandle(A6) ; save handle flags
Pea savePort(A6) ; save incoming port
_GetPort
Move.L A4,A0 ; get the TEHandle
_HLock
Move.L (A4),A3 ; Dereference into A3 ** <C381/8nov86/MBK **
; Do all safety related entry stuff
Move.L teGrafPort(A3),A2 ; save "thePort" for below
Move.L A2,-(SP) ; set to our port
_SetPort
; Get clip from this port into rgn defined above
SubQ #4,SP ; make room for clip
_NewRgn
Move.L (SP),saveClip(A6) ; save user's clip in frame
Move.L (SP),-(SP) ; stay on stack for sectrgn below
_GetClip
Pea teViewRect(A3) ; clip to viewRect
_ClipRect
; First param on stack from above. Do not pass go. Do not collect $200
Move.L clipRgn(A2),-(SP)
Move.L (SP),-(SP) ; destination
_SectRgn
; Set up font, etc.
Move.L teGrafPort(A3),A0 ; pt to GrafPort
Tst.W teSize(A3) ; check style flag
Bmi.S DontSet ; don't set style ** MBK 6/20/86 **
Move.L teFontStuff(A3),txFont(A0) ; set the font/face
Move.L teFontStuff+4(A3),txFont+4(A0) ; set the mode/size
DontSet Move.W txFont(A0),saveFont(A6) ; save current font
Move.W txFace(A0),saveFace(A6) ; save current face
Move.W txSize(A0),saveSize(A6) ; save current size
Pea saveColor(A6) ; place to save color ** <C182/60ct86/MBK> **
;; If forRAM THEN
If (Not ForROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; color QD around? <C971/RWW112487>
Bnz.S @1 ; nope <C971/RWW112487>
Move.W teMode(A3),txMode(A0) ; <C971/RWW112487>
_GetForeColor ; <C971/RWW112487>
Bra.S @2 ; <C971/RWW112487>
@1 Bsr GetForeColor ; <C971/RWW112487>
@2
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
Move.W teMode(A3),txMode(A0) ; do set the mode ** <C815/13feb87/MBK **
_GetForeColor ; for Ikki ** <C182/6oct86/MBK> **
Else
Bsr GetForeColor ; for Alladin ** <C182/6oct86/MBK> **
EndIf
Move.L teTextH(A3),A0 ; get handle size
_HGetState ; get the text handle's tag
Move.B D0,saveTH(A6) ; and save the flags
_HLock ; and lock it
_GetHandleSize ; get its size
Move D0,teLength(A3) ; stuff its length
; Clean up the selection (This must be the last guy because of alternate entry)
CleanUpSel
Move teLength(A3),D0 ; get the text length
Move teSelEnd(A3),D1 ; make sure selEnd is cool
Sub D0,D1 ; selEnd-length
Bls.S okSelEnd ; if >0 then bad selend
Move D0,teSelEnd(A3) ; set to length if > length
okSelEnd
Move teSelStart(A3),D1 ; make sure selStart is cool
Sub teSelEnd(A3),D1 ; selStart-selend
Bls.S okSelStart ; if >0 then bad selStart
Sub D1,teSelStart(A3) ; set to selend if > selend
okSelStart
Bsr SelSort ; I wish i could fall into it
Tst.L D3 ; addr of style trap? ** <C105/28aug86/MBK **
Beq.S @2 ; if not, skip this ** <C105/28aug86/MBK **
Move.L D3,A0 ; return it in A0 ** <C381/5nov86/MBK **
Lea inHandle+6(A6),A2 ; pt to next param ** <C105/28aug86/MBK **
Bra.S endEntry ; that's it ** <C105/28aug86/MBK **
@2 Lea inHandle+4(A6),A2 ; Point to next to last param
; (1st on stack after handle)
endEntry
Rts
; ----------------------------------------------------------------------
; PROCEDURE TEDispatch (...; hTE: TEHandle; teStyl: INTEGER );
; ** <C105/28aug86/MBK> **
; All style procedure and function traps come here (except
; TEStylNew) due to a shortage of traps.
; ** <C207/13oct86/MBK> **
; Added special dispatch to StylTextBox. Have to special case
; it since it doesn't go through StdEntry.
; ----------------------------------------------------------------------
TEDispatch
MoveQ #1,D0 ; tells stdEntry it's a style trap
Bsr StdEntry2 ; get addr of procedure
Jmp (A0) ; go and never come back!
; ***************************************************************************
; ** <C971/RWW102387> So I can find routines more easily...
If &TYPE('&RWWDebug') <> 'UNDEFINED' Then
Macro
FindEntry &rout
DC.B '&SUBSTR(&CONCAT(&rout,'............'),1,12)'
DC.L &rout-DispLocTable
EndM
Export DispLocTable
DispLocTable
FindEntry vChar2Pixel
FindEntry vPixel2Char
FindEntry XTrimMeasure
FindEntry XFindWord
FindEntry XFindLine
FindEntry XEOLHook
FindEntry XDRAWHook
FindEntry iTEStylPaste
FindEntry iTESetStyle
FindEntry iTEReplaceStyle
FindEntry iTEGetStyle
FindEntry iGetStylHandle
FindEntry iSetStylHandle
FindEntry iGetStylScrap
FindEntry iTEStylInsert
FindEntry iTEGetPoint
FindEntry iTEGetHeight
FindEntry iSetStylScrap
FindEntry iTECustomHook
FindEntry iTEContinuousStyle
FindEntry iSetStylScrap
FindEntry iTENumStyles
DC.L -1
EndIf
; ***************************************************************************
; ----------------------------------------------------------------------
; Sorts the selStart and selEnd
; Entry:
; A3 must contain a dereferenced TE object
; Exit:
; D0 contains a sorted selStart/End as a long
; A2 contains a pointer to teSelStart
; ----------------------------------------------------------------------
SelSort
Lea teSelStart(A3),A2 ; Point to selstart
Move.L (A2),D0 ; load start and end
Cmp (A2),D0 ; see which is bigger
Bhs.S @0
Swap D0
Move.L D0,(A2) ; swap and store back
@0 Rts
; ----------------------------------------------------------------------
; PROCEDURE TECopy( h: TEHandle );
; ** Modified 6/20/86 by MBK **
; ----------------------------------------------------------------------
TECopy
Bsr StdEntry ; <C971/RWW102887>NO
Bsr.S SelSort ; D0 contains both (end in low order)
Sub (A2),D0 ; A2 points to selStart(A3)
Move D0,teScrpLength ; scraplength=selEnd-selStart
Move.L teTextH(A3),A0 ; source = text; already locked
Move.L (A0),A0 ; dereference
MoveQ #0,D0 ; clear whole long
Move (A2),D0
Add.L D0,A0 ; offset to selection(see above)
Move.L teScrpHandle,A1 ; destination
Move teScrpLength,D0 ; nBytes = scrapLength
_PtrToXHand
; ** <C207/15oct86/MBK> ** Don't wipe out desk scrap for old TERecs in case applications
; use it for Undo
Tst.W teSize(A3) ; check style flag
Bpl.S goEpilog4 ; no style, don't wipe out scrap
; Now copy directly to the desk scrap anyway
SubQ #4,SP ; room for result ** MBK 6/20/86 **
_ZeroScrap ; clear the scrap ** MBK 6/20/86 **
AddQ.L #4,SP ; ignore result ** MBK 6/20/86 **
Bsr.S SelSort ; D0 contains both (end in low order)
Bsr.S CopyStyle ; copy style info <C971/RWW102887>NO
Move.L teTextH(A3),A0 ; text handle ** MBK 6/20/86 **
Move.L (A0),A0 ; deref ** MBK 6/20/86 **
MoveQ #0,D0 ; clear long word ** MBK 6/20/86 **
; <16May89smb> Must set up A2 to point to selStart(a3) again, since it may be invalid if the
; teRecord moved during a MyNewHandle call in CopyGuts.
Lea teSelStart(A3),A2 ; <16May89smb> point to selStart
Move (A2),D0 ; start of selection ** MBK 6/20/86 **
AddA.W D0,A0 ; offset to selection ** MBK 6/20/86 **
SubQ #4,SP ; room for result ** MBK 6/20/86 **
Move.W teScrpLength,D0 ; length of selection ** MBK 6/20/86 **
Move.L D0,-(SP) ; push length ** MBK 6/20/86 **
Move.L #'TEXT',-(SP) ; type 'TEXT' ** <C381/5nov86/MBK> **
Move.L A0,-(SP) ; ptr to selection ** MBK 6/20/86 **
_PutScrap ; copy to desk scrap ** MBK 6/20/86 **
AddQ.L #4,SP ; ignore result ** MBK 6/20/86 **
goEpilog4
Bra epilog4
; ----------------------------------------------------------------------
; PROCEDURE CopyStyle
; ** Added 5/28/86 by MBK **
; CopyStyle saves the styles corresponding to the current text
; selection to the desk scrap.
; Entry:
; A3: Pointer to TERec
; D0: selStart, selEnd
; ----------------------------------------------------------------------
CopyStyle
MoveM.L D0/D2-D5/A2/A5,-(SP) ; save stuff
; get ptr to 1st style and # of styles
Move.W D0,D1 ; save end
Swap D0 ; selStart in low word
Cmp.W D0,D1 ; is it an insertion pt?
Beq.S @2 ; if so, no style to copy
Bsr.S CopyGuts ; do the copy
; Lock my scrap handle 'cause PutScrap might try to move it!
Move.L A4,A0 ; my scrap handle
_HLock ; lock it
; copy the styles to the desk scrap now
SubQ.L #4,SP ; room for result
Move.L D4,-(SP) ; size of scrap
Move.L #'styl',-(SP) ; scrap type ** <C381/5nov86/MBK> **
Move.L (A4),-(SP) ; scrap ptr
_PutScrap ; copy to desk scrap
AddQ.L #4,SP ; remove result code
; don't need this handle anymore
Move.L A4,A0 ; scrap handle
_DisposHandle ; get rid of it
@2 MoveM.L (SP)+,D0/D2-D5/A2/A5 ; save stuff
Rts
; ----------------------------------------------------------------------
; PROCEDURE CopyGuts
; ** Separated out from CopyStyle 1/22/87 by MBK **
; CopyGuts is called by CopyStyle and iGetStylScrap to save the
; styles corresponding to the current text selection.
; Entry:
; A3: Pointer to TERec
; D0: selStart
; D1: selEnd
; ----------------------------------------------------------------------
CopyGuts
Move.W D0,D5 ; save 1st offset
Bsr GetCurStyle ; get style at current selection
Bsr GetNumStyles ; find # of styles in selection
Move.W D0,D2 ; save # of styles
; get a temp handle to store the styles in before copying to desk scrap
MulU #scrpRecSize,D0 ; * size of a scrap style rec
AddQ.L #2,D0 ; total scrap size
Move.L D0,D4 ; preserve scrap size
Bsr MyNewHandle ; temp handle for style scrap ** <C381/7nov86/MBK> **
Move.L A0,A4 ; save scrap handle
Move.L (A0),A0 ; deref
Move.W D2,scrpNStyles(A0) ; store # of styles in scrap
Lea scrpStyleTab(A0),A1 ; pt to array of styles
; ** <C393/10nov86/MBK> ** style ptr may no longer be valid after memory allocation
Move.W D5,D0 ; get 1st offset ** <C393/10nov86/MBK> **
Bsr GetCurStyle ; get style at current selection** <C393/10nov86/MBK> **
Move.L A0,A2 ; store ptr to current style ** <C393/10nov86/MBK> **
; loop over styles in the selection, copying to temp location
@0 AddQ.L #4,A1 ; skip 1st entry ** <C207/13oct86/MBK> **
Move.W styleIndex(A2),D0 ; style index
Bsr GetStyle ; get the style ptr
AddQ.L #2,A0 ; skip 1st entry ** <C207/13oct86/MBK> **
MoveQ #stRecSize-2,D0 ; size of a style rec-2 ** <C381/6nov86/MBK> **
_BlockMove ; copy style to scrap
MoveQ #0,D0 ; it's a long word ** <C207/13oct86/MBK> **
Move.W startChar(A2),D0 ; get start offset of this style
Sub.W D5,D0 ; offset from start of text scrap
Bhs.S @1 ; made this unsigned ** <C381/6nov86/MBK> **
MoveQ #0,D0
@1 Move.L D0,-(A1) ; store scrap offset
Add.L #scrpRecSize,A1 ; next position in style array
AddQ.L #stStartSize,A2 ; next style
SubQ #1,D2 ; dec the style counter
Bne.S @0 ; loop if more styles
Rts
; ----------------------------------------------------------------------
; PROCEDURE TECut( h: TEHandle );
; ----------------------------------------------------------------------
TECut
Bsr StdEntry ; <C971/RWW102887>NO
Move.L A4,-(SP) ; duplicate handle twice
_TECopy ; copy it
Move.L A4,-(SP)
_TEDelete ; delete it (A3 no good after)
Bra goEpilog4 ; see you later <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE TEDelete( h: TEHandle );
; ----------------------------------------------------------------------
TEDelete
Bsr StdEntry ; <C971/RWW102887>NO
Bsr HideCaret
Bsr.S DelGuts ; delete the selection
Bsr RecalDraw ; recalibrate line starts
Bsr ShowCaret
Bsr SelView ; insure selection is visible
Bra goEpilog4 ; <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE DelGuts
; ** Modified 6/18/86 by MBK **
; Entry:
; A3 contains dereferenced handle
; Exit
; Selstart and selEnd will be fixed up to point to the old selStart
; D7 contains delta amount for delete portion
; ----------------------------------------------------------------------
DelGuts
Bsr SelSort ; sort selection <C971/RWW102887>NO
Move D0,D7 ; calc delta amount(selEnd in D0)
Sub (A2),D7 ; ...for ReCalLines (A2 ^selStart)
Beq.S outGuts ; skip if null selection
; ** <C971/RWW102987> Inserted test to change the way backspacing/deleting works.
; If you backspace to the beginning of a style, that style is saved to the null scrap.
; This allows you to type a selection, backspace over it, and retype without
; TextEdit reverting to the previous style.
Tst.W teSize(A3) ; is this a styled record? <C971/RWW102987>
Bpl.S @1 ; oops, never mind <C971/RWW102987>
MoveM.L D0/D7/A2,-(SP) ; we need D0 and A2 temporarily <C971/RWW102987>
Move.W teSelStart(A3),D0 ; find start of block to be yanked <C971/RWW102987>
Bsr GetCurStyle ; find the associated style run <C971/RWW102987>
Move.W teSelStart(A3),D0 ; get start of block again <C971/RWW102987>
Cmp.W startChar(A0),D0 ; is it the beginning of a style? <C971/RWW102987>
Beq.S @2 ; yes, so continue <C971/RWW102987>
Bsr ClearRsrved ; no null selection! <C971/RWW102987>
Bra.S @3 ; <C971/RWW102987>
@2 Move.W styleIndex(A0),D0 ; fetch index into style table <C971/RWW102987>
Bsr GetStyle ; find associated style table entry <C971/RWW102987>
Move.W #doAll,-(SP) ; build fake frame for SetRsrved <C971/RWW102987>
Pea stFont(A0) ; point at embedded textstyle <C971/RWW102987>
Clr.B -(SP) ; need another word, can't hurt <C971/RWW102987>
Move.L SP,A2 ; point A2 at stacked parameters <C971/RWW102987>
Bsr AltSetRsrved ; set null scrap style <C971/RWW102987>
AddQ.W #8,SP ; fix up stack <C971/RWW102987>
@3 MoveM.L (SP)+,D0/D7/A2 ; retrieve saved registers <C971/RWW102987>
@1 ; <C971/RWW102987>
Move.W D0,D1 ; selEnd ** MBK 6/18/86 **
Swap D0 ; selStart ** MBK 6/18/86 **
Bsr.S DeleteStyle ; del associated styles <C971/RWW102887>NO
Bsr MungeSetup ; set up params for delete
Move D7,-(SP) ; length for delete
Clr -(SP) ; fake long length
Clr.L -(SP) ; fake p2
Clr.L -(SP) ; fake l2
_Munger ; sloppy munger
AddQ.L #4,SP ; pop result
Move.L teTextH(A3),A0 ; RecalDraw expects text to be locked
_Hlock ; and relock it
Sub D7,teLength(A3) ; length:=length -(selEnd-selStart)
Move (A2)+,(A2) ; selEnd:=selStart
outGuts
Rts
; ----------------------------------------------------------------------
; PROCEDURE DeleteStyle
; ** Added 6/2/86 by MBK **
; DeleteStyle checks to see if the TERec has style (txSize = -1),
; And if so deletes the style(s) corresponding to the current text
; selection.
; Entry:
; A3: Ptr to TERec
; D0: selStart
; D1: selEnd
; ----------------------------------------------------------------------
DeleteStyle
MoveM.L D0/D2-D6/A2,-(SP) ; save stuff
Tst.W teSize(A3) ; check style flag
Bpl.S @2 ; no style so nothing to delete
Move.W D0,D5 ; store selStart
Sub.W D1,D5 ; neg length for delete
Beq.S @2 ; quit if nothing to delete
Move.W D0,D3 ; save selStart
SubQ #1,D0 ; pre-decrement
Bsr GetCurStyle ; get style at current selection
Move.L A0,A2 ; store ptr to current style
Move.W D0,D6 ; save index
AddQ #1,D1 ; include following style
Bsr GetNumStyles ; find # of styles in selection
SubQ #1,D0 ; don't delete current style
Move.W D0,D2 ; # of styles
Add.W D6,D0 ; add index
Move.W D0,D6 ; save index
MoveQ #0,D4 ; clear long word ** <C381/6nov86/MBK> **
Move.W D2,D4
LsL.L #2,D4 ; * stStartSize (4) ** <C381/6nov86/MBK> **
Add.L D4,A0 ; pt to last style to be deleted
Tst.W D2 ; see if any styles to delete
Bne.S @0 ; if nothing to delete
Bsr RecalStStarts ; reset following style starts
Bra.S @2 ; and go
@0 Move.W D3,startChar(A0) ; selStart is new start of last style
Bsr RecalStStarts ; reset following style starts
Cmp.W startChar(A2),D3 ; special case
Beq.S @1
Add.L #stStartSize,A2 ; point to next style
SubQ #stStartSize,D4 ; 1 less to delete
SubQ #1,D2 ; don't delete last style
Beq.S @2 ; nothing to delete
@1 Move.L A2,A0 ; ptr
Move.W D2,D0 ; count
Bsr.S DecStylCount ; decrement style count <C971/RWW102887>NO
; Delete the runs corresponding to deleted text
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; dereference
MoveQ #0,D0 ; clear long word ** <C381/6nov86/MBK> **
Move.W nRuns(A0),D0 ; current # of styles
AddQ #1,D0 ; plus 1
Sub D6,D0 ; minus index
LsL.L #2,D0 ; * stStartSize (4) ** <C381/6nov86/MBK> **
Sub.W D2,nRuns(A0) ; dec the # of styles
Move.L A2,A1 ; destination of move
Move.L A2,A0
Add.L D4,A0 ; source of move
_BlockMove
@2 MoveM.L (SP)+,D0/D2-D6/A2 ; restore stuff
Rts
; ----------------------------------------------------------------------
; PROCEDURE DecStylCount
; ** Added 6/2/86 by MBK **
; DecStylCount decrements the style count by one after an instance
; of the style has been deleted.
; Entry:
; D0: # of styles to check
; A0: Pointer to style from which to start
; A3: Ptr to TERec
; ----------------------------------------------------------------------
DecStylCount
Move.L A0,A1 ; save ptr to style start
Move.W D0,D1 ; store # styles to check
; get the styleRec corresponding to the index
@0 Move.W styleIndex(A1),D0 ; get index to style
Bsr GetStyle ; get pointer to that style
Tst.W stCount(A0) ; is the count already 0?
Beq.S @1
SubQ #1,stCount(A0) ; if not, decrement the count
; see if there are more styles to delete
@1 Add.L #stStartSize,A1 ; point to next style
SubQ #1,D1 ; dec the counter
Bne.S @0 ; more to decrement
Rts
; ----------------------------------------------------------------------
; PROCEDURE RecalDraw
; ** Modified 6/18/86 by MBK **
; Calls ReCalLines to recalibrates the line start array and then draws
; the "new" part according to selStart
; Entry
; A4 points to handle
; A3 points to dereferenced TE object
; D7 contains delta change = oldLength-newLength
; ** <C207/16oct86/MBK> ** Added code to reset redraw boundaries if the
; line height has changed on any line.
; ** <C381/8nov86/MBK> ** Moved code to decide where redraw must occur
; to the routine SetLineHite.
; ----------------------------------------------------------------------
RecalDraw
MoveQ #0,D0 ; 1st line ** MBK 6/18/86 **
Move.W teNLines(A3),D1 ; last line ** MBK 6/18/86 **
Bsr GetLineHites ; get total height ** MBK 6/18/86 **
Move.W D0,-(SP) ; save it ** MBK 6/18/86 **
Bsr ReCalLines ; D2/D4 returned w/dispStart
Move D2,D3 ; record dispStart
MoveQ #0,D0 ; 1st line ** MBK 6/18/86 **
Move.W teNLines(A3),D1 ; last line ** MBK 6/18/86 **
Bsr GetLineHites ; get new height ** MBK 6/18/86 **
Move.W (SP)+,D1 ; get old height
Cmp.W D0,D1 ; don't erase if same
Blo.S noErase ; nothing to erase
Lea teSelRect(A3),A0 ; pt to selection rect
Add teDestRect+top(A3),D1 ; new bottom
Move.W D1,bottom(A0)
Add teDestRect+top(A3),D0 ; new top
Move.W D0,top(A0)
Move.W #$8002,left(A0) ; large negative left
Move #$7FF0,right(A0) ; VERY large right(Erase to end)
Move.L A0,-(SP) ; point to rect
_EraseRect
noErase
MoveQ #teDraw,D7 ; Redraw changed part
Bra DoText ; see you later <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE FindWord
; Finds a word @ D0 and returns its start and end+1 index in D0,D1
; respectively. Note cannot return selStart itself - must look to left
; Entry
; A3 - dereferenced handle
; D0 - current position (i.e. selStart)
; D2 - identifier of routine that called FindWord
; Exit
; D0 - word start
; D1 - word end+1
; ----------------------------------------------------------------------
FindWord
Move.L teFindWord,-(SP) ; call the FindWord Routine <EHB 01Oct85>
Rts
XFindWord ; here's our FindWord <EHB 01Oct85>
Swap D2 ; get constant into high word <EHB 01Oct85>
Move.W D0,D2 ; save position in low word <EHB 01Oct85>
Move.W D0,D1
Beq.S RightScan
Bsr.S LeftScan ; do left scan 1st
; Right scan, given a char code in D1, this returns the next word break >= D1
RightScan
BClr #17,D2 ; clear bit 17 (right) <EHB 01Oct85>
RS1
Cmp teLength(A3),D1 ; see if @ right edge
Bhs.S @0 ; assume found if at right edge
Move D1,A1 ; pass index
Bsr.S CallBreak
Bne.S @0
AddQ #1,D1 ; try next char
Bra.S RS1 ; <EHB 01Oct85>
@0
Rts
; Given a char location in D0, this routine returns a new word break to left of D0
LeftScan
BSet #17,D2 ; set bit 1 (left) <EHB 01Oct85>
LS1
SubQ #1,D0 ; pre decrement
Move D0,A1 ; pass index
Bsr.S CallBreak ; was it a break?
Bne.S @0 ; if so, skip town
Tst D0 ; are we done?
Beq.S @1 ; if so, skip town
Bra.S LS1 ; keep looking
@0
AddQ #1,D0 ; try next char
@1
Rts
CallBreak
MoveM.L D0/A0-A1,-(SP) ; save regs
Move A1,D0 ; pass index in D0
Move.L teTextH(A3),A0 ; get handle
Move.L (A0),A0
Move.L teWordBreak(A3),A1 ; get routine
Jsr (A1) ; call routine which sets CC's
MoveM.L (SP)+,D0/A0-A1 ; restore regs
Rts
DefWordBrk
; lo16 is used by TE as a constant for clearing the high word of registers
lo16 Equ *+2
And.L #$0000FFFF,D0 ; longize it
Cmp.B #$20,0(A0,D0.L) ; see if <= $20
Sls D0 ; return if word break(SP)
Tst.B D0
Rts
; Measures the trimmed string in [D6..D7)
TrimMeasure
MoveM.L D6-D7,-(SP) ; save regs
Bsr MeasD6D7
MoveM.L (SP)+,D6-D7 ; restore regs
Rts
; ----------------------------------------------------------------------
; PROCEDURE StylMeasure
; ** Added 6/18/86 by MBK **
; Measures the word at offset D6-D7, taking the style into account
; If this record has style.
; Entry:
; D6 Start of word to be measured
; D7 End of word to be measured
; A3 dereferenced handle
; Exit:
; D0 Width of selection
; ----------------------------------------------------------------------
StylMeasure
MoveM.L D2-D3/D5/A2,-(SP)
; does this record have style?
Tst.W teSize(A3) ; check style flag
Bmi.S @2
; No, just measure the whole thing at once
Move.W D7,D0 ; end offset
Move.W D6,D1 ; start offset
Bsr.S SetUp ; measure whole word <C971/RWW102887>NO
Add.W D6,D1 ; offset at end of word
Bra.S @6 ; that's it <C971/RWW102887>NO
; Yes, so measure word 1 style at a time
@2 Move.W D6,D5 ; start offset
Move.W D6,D3 ; start offset
Move.W D3,D0 ; start
Bsr GetCurStyle ; get current style
Move.L A0,A2 ; save style start ptr
Move.W D7,D1 ; end
Bsr GetNumStyles ; # of styles in selection
Move.W D0,D2 ; save it
@3 Move.L A2,A0 ; style ptr
Bsr SetStyle ; set the style
Add.L #stStartSize,A2 ; pt to next style
Move.L A2,A0 ; style ptr
Move.W startChar(A0),D0 ; end of style
Cmp.W D0,D7 ; compare to end of selection
Bhs.S @4 ; okay if greater
Move.W D7,D0 ; else set to end of selection
@4 Move.W D3,D1 ; start offset
Move.W D0,D3 ; next time end becomes start
Move.L teStylesH(A3),A0 ; get handle to style record
Move.L (A0),A0 ; deref
Sub.L A0,A2 ; save as an offset
Bsr.S SetUp ; measure it <C971/RWW102887>NO
Move.L teStylesH(A3),A0 ; get handle to style record
Move.L (A0),A0 ; deref
Add.L A0,A2 ; restore style pointer
Add.W D1,D5 ; accumulate offset
Tst.W D0 ; pixel width found?
Bne.S @5 ; quit if so
SubQ #1,D2 ; dec the style counter
Bne.S @3 ; keep looping if more styles <C971/RWW102887>NO
@5 Move.W D5,D1 ; offset
@6 MoveM.L (SP)+,D2-D3/D5/A2
Rts
SetUp
Move.W D2,-(SP) ; save style count
Sub.W D1,D0 ; text length
Move.L teTextH(A3),A0 ; text handle
Move.L (A0),A0 ; deref
AddA.W D1,A0 ; text ptr
Move.W D4,D1 ; pixel width
MoveQ #0,D2 ; slop
; Bsr Pixel2Char ; measure it
Bsr TEHitTestHook ; measure it <S487/RWW050288>
Sub.W D0,D4 ; update width
Swap D0 ; get flag in low byte
Move.W (SP)+,D2 ; restore count
Rts
; ----------------------------------------------------------------------
; PROCEDURE FindLine
; ** Modified 6/18/86 by MBK **
; Finds a line starting at char location in D6.
; This first tries to measure the line in word chunks to save time,
; but if that fails it will do it character by character. IF teCROnly
; is set it won't measure anything(Assuming dest rect is huge to right)
; And just scans for the CR.
; Entry
; D6 start of line search assumed to be at 1st word?
; A3 - dereferenced handle
; Exits
; D0 with line end after D6
; ----------------------------------------------------------------------
FindLine Move.L teFindLine,-(SP) ; push current FindLine routine <EHB 01Oct85>
Rts ; and call it <EHB 01Oct85>
XFindLine ; our default FindLine routine <EHB 01Oct85>
MoveM.L D1-D7/A1-A2,-(SP) ; protect working registers
; Keep going until line width in D4 is used up
Move teDestRect+right(A3),D4 ; get right edge
Sub teDestRect+left(A3),D4 ; get extent
SubQ #1,D4 ; reduce for caret indent
Sub.L A2,A2 ; flag not found
Move D6,D7 ; use D7 for tail, D6 for head
MoveQ #0,D3 ; clear accumulator ** MBK 6/17/86 **
MoveQ #0,D5 ; init D5
wordLoop
Move D7,D0 ; set up start posn <EHB 01Oct85>
MoveQ #teFromFind,D2 ; say findLine is calling <EHB 01Oct85>
Bsr FindWord ; get word end in D1 <C971/RWW102887>NO
Move D1,D7 ; save end
Tst.B teCROnly(A3) ; see if only scan to CR
Bne.S @0 ; if so, skip the measure
Bsr StylMeasure ; measure with style ** MBK 6/17/86 **
Tst.W D0 ; end of line reached?
Bne.S Spilled
; It has yet to spill off the right, so continue on unless char = CR
@0
Move D7,D5 ; save lastBlank location
AddQ #1,A2 ; flag as found
Cmp teLength(A3),D7 ; see if < length for right
Beq.S foundLine
Move.L teTextH(A3),A0 ; see if char was a CR
Move.L (A0),A0
And.L lo16,D7 ; longize it
; ** <C971/RWW110387> Added this code to support tabs
; Cmp.B #$0D,0(A0,D7.L) ; well, is it?
Move.B 0(A0,D7.L),D0 ; THESE FOUR LINES REPLACE PREVIOUS <C971/RWW110387>
MoveM.L D1,-(SP) ; we need D1 intact <C971/RWW110387>
Bsr TEEolHook ; <C971/RWW110387>
MoveM.L (SP)+,D1 ; (MoveM doesn't affect CCR!!) <C971/RWW110387>
Bne.S @1 ; keep trying if not ** <C381/30oct86/MBK> **
AddQ #1,D5 ; point after break char ** <C381/30oct86/MBK> **
Bra.S foundLine ; and exit ** <C381/30oct86/MBK> **
@1 Move.W D7,D6
AddQ #1,D7 ; start with next word
Bra.S wordLoop ; get next one <C971/RWW102887>NO
; D5 contains the last break location so point to next character since break char
; is included on the line.
; If A2 = 0, then it never found a break char
spilled Move A2,D0 ; did we find something
Beq.S @1
Move.L teTextH(A3),A0 ; get text handle ** <C381/30oct86/MBK> **
Move.L (A0),A0 ; dereference ** <C381/30oct86/MBK> **
@0 AddQ #1,D5 ; use next char ** <C381/30oct86/MBK> **
Cmp.W teLength(A3),D5 ; check text length ** <C381/8nov86/MBK> **
Bhs.S foundLine ; exit if end of text ** <C381/8nov86/MBK> **
; A CR following non-wrapped blanks should be considered the line break.
; If not, the CR will go on the next line, and we'll get an empty line
; in-between. This fixes bug LM-RM-98.
; ** <C971/RWW110387> Added this code to support tabs
; Cmp.B #$0D,0(A0,D5) ; if last char = CR then...
Move.B 0(A0,D5),D0 ; THESE FOUR LINES REPLACE PREVIOUS <C971/RWW110387>
MoveM.L D1/A0,-(SP) ; (we need D1 AND A0) <C971/RWW110387>
Bsr TEEolHook ; <C971/RWW110387>
MoveM.L (SP)+,D1/A0 ; (MoveM doesn't affect CCR!!) <C971/RWW110387>
Bne.S @2 ; if CR, we actually want next char
AddQ #1,D5 ; use next char
Bra.S foundLine
@2
Cmp.B #$20,0(A0,D5) ; if last char = space then... ** <C381/30oct86/MBK> **
Beq.S @0 ; it's a break ** <C381/30oct86/MBK> **
Bra.S foundLine
@1 SubQ #1,D1 ; end of rect intersects this char
Move.W D1,D5
foundLine Move D5,D0 ; return in D0
MoveM.L (SP)+,D1-D7/A1-A2 ; restore working registers
Rts
; ----------------------------------------------------------------------
; PROCEDURE ReCalLines
; ** Modified 6/18/86 by MBK **
; Recalibrates the line start array and sets dispStart/dispEnd to
; correct redraw spot. Starting with the selection, it figures out
; which line the selection is on. Then it recalibrates the line starts
; from there until the delta in D7 is consumed (the word wrap has
; petered out). It returns D2 and D4 to the redraw start and end.
; (It should return D3 instead of D2, but for compatibility it uses
; D2).
; Entry
; A4 points to handle
; A3 points to dereferenced TE object
; D7 contains delta in change = oldLength-newLength
; Exit
; dispStart(D2) now set to redraw start
; dispEnd(D4) set to redraw end
; Uses
; D5 for handle size (changed by setlinearray)
; ----------------------------------------------------------------------
; ** <C105/3Sep86/MBK> ** Stages 2 and 3 of Recal were totally rewritten for
; speed. I decided the insert and delete cases were
; different enough to justify handling them separately.
ReCalLines
Move.L teRecal,-(SP)
Rts
XReCalLines
Link A6,#RecalLink
MoveM.L D3/D5-D6/A2,-(SP) ; save regs (SEE .EQU ABOVE)
Move.W teNLines(A3),oldNLines(A6) ; save old # of lines ** <C229/28oct86/MBK> **
Clr.W teNLines(A3) ; prime nLines:=0
Clr.W savedD2(A6) ; default redraw beginning
Move teLength(A3),savedD4(A6) ; default redraw end
Tst.W teLength(A3) ; any text?
Beq.S RecalDone ; if not, nothing to recal <C971/RWW102887>NO
; D3 contains the start point to recal from, so find the line containing D3
Lea teLines(A3),A2 ; point to line starts
MoveQ #teFromRecal,D2 ; say ReCalLines is calling <EHB 01Oct85>
Move teSelStart(A3),D0 ; put start position in D0 <EHB 01Oct85>
Bsr FindWord ; get word around selstart for...<C971/RWW102887>NO
Move D0,D3 ; comparison
stage1
Move (A2)+,D6 ; i(start):=lineStarts[line]
Move D6,savedD2(A6) ; save away as default redraw start
Cmp (A2),D3 ; while selWord<lineStarts[line+1]
Blo.S stage2x ; if inclusive
Beq.S stage2y ; if at next line start
AddQ #1,teNLines(A3) ; one more line, keep looking for
Bra.S stage1 ; line containing selStart(D3)
; Return the refresh start in savedD2
stage2x
Bsr FindLine ; get line after D6 <C971/RWW102887>NO
Cmp D0,D3 ; did the line break change?
Bhs.S stageBad ; if so, must redraw whole thing
stageGood ; <EHB 05-Nov-85>
Tst.B WordRedraw ; should we redraw the whole word? <EHB 31-Oct-85>
Bgt.S stageBad ; => yes, app wants whole word <EHB 31-Oct-85>
Blt.S stage2A ; => app wants whole line <EHB 01-Nov-85>
Move teSelStart(A3),D3 ; return selStart
stageBad
Tst.W teJust(A3) ; see what format, for right or
Bne.S stage2A ; centered, must use linestart
Tst.W teSysJust ; check text direction ** <C105/14aug86/MBK> **
Bne.S stage2A ; not left ** <C105/14aug86/MBK> **
; Special case: redraw line didn't work because stage2x jumped here w/o checking the redraw flag.
Tst.B WordRedraw ; should we redraw the whole word? ** <C454/21nov86/MBK> **
Blt.S stage2A ; => app wants whole line ** <C454/21nov86/MBK> **
Move D3,savedD2(A6) ; return word start-1
Beq.S stage2A
SubQ #1,savedD2(A6)
Bra.S stage2A
stage2y
Bsr FindLine ; get line after D6 <C971/RWW102887>NO
Cmp D0,D3 ; did the line break change?
Bne.S stageBad ; if so, must redraw whole thing<C971/RWW102887>NO
Move D3,savedD2(A6) ; "next" line OK if at beginning
Bra.S stageGood ; <C971/RWW102887>NO
; 2 new routines for handling stages 2 and 3 of Recal
stage2A Move.W D0,D3 ; save line start in D3
If &TYPE('&RWWDebug') <> 'UNDEFINED' Then
Tst.W D7 ; insertion or deletion?
Ble.S @0
; If some characters on a line are replaced by (a fewer number of) CRs
; the deletion algorithm does not work correctly because it is not
; prepared to add new lines. So now I just call the insertion algorithm
; except for this special case, when character(s) at the beginning of
; the line are being deleted (the insertion algoritm doesn't work
; in this case). Maybe someday this whole recalibration thing will
; get rewritten!
; Changed this once again. Selstart will equal selEnd whenever TEDelete was called.
; Only call InsertRecal if this was an insertion that was shorter than the selection.
Move.W teSelStart(A3),D0
Cmp.W teSelEnd(A3),D0
Bne.S @0
Bsr.S DeleteRecal ; recal for deletions
Bra.S reCalDone
EndIf ; <PMAB381/RWW020488>
@0 Bsr InsertRecal ; recal for insertions
reCalDone Bsr SetLineHite ; reset line heights ** <C229/28oct86/MBK> **
Move.W savedD4(A6),D4 ; return start and end ** MBK 6/18/86 **
Move.W savedD2(A6),D2 ; ** MBK 6/18/86 **
; ** <C971/RWW102287> Rudy D. memorial lineStarts hack.
; Force TERecord to be proper length.
cutBackSlop Equ 8
Move.L A4,A0 ; How fat is TERecord now? <C971/RWW102987>
_GetHandleSize ; <C971/RWW102987>
Tst.L D0 ; check for error <C971/RWW102987>
Bpl.S @2
_SysError ; fly away if system error <C971/RWW102987>
@2 Sub.L #teRecSize,D0 ; lose header <C971/RWW102987>
LsR.L #1,D0 ; account for word sized table <C971/RWW102987>
And.L #$7FFF,D0 ; gotta be fewer than 32K lines <C971/RWW102987>
Sub.W teNLines(A3),D0 ; blow off cutback <C971/RWW102987>
Bz.S @1 ; didn't change at all <C971/RWW102987>
Bmi.S @1 ; got larger. Munger handled it <C971/RWW102987>
Cmp.W #cutBackSlop,D0 ; is difference less than slop <C971/RWW102987>
Blo.S @1 ; Yes, so don't bother memory mgr <C971/RWW102987>
MoveQ #0,D0 ; Gotta talk longs, here <PMAB345/C990/RWW121687>
Move.W teNLines(A3),D0 ; Fetch number of lines <PMAB345/C990/RWW121687>
LsL.L #1,D0 ; account for word offset <C971/RWW102287>
Add.L #teRecSize,D0 ; Add in rest of record <C971/RWW102287>
Move.L A4,A0 ; TEHandle is what we're resizing <C971/RWW102287>
Bsr MySetHandleSize ; Go do it <C971/RWW102287>
@1 ; <C971/RWW102287>
MoveM.L (SP)+,D3/D5-D6/A2 ; restore regs
Unlk A6
Rts ; see you later
If &TYPE('&RWWDebug') <> 'UNDEFINED' Then
; ** <C105/3Sep86/MBK> ** Stages 2 and 3 for deletion only
DeleteRecal
Move.L teTextH(A3),A0 ; text handle
Move.L (A0),A1 ; deref into A1
dStage2
; If the width of a single character > the width of the window, Recal keeps
; finding the same line (line 1) forever. If this happens, don't keep trying
; to wrap, just advance to the next character.
Cmp.W D6,D3 ; same as old value? ** <C440/18nov86/MBK> **
Bne.S @0 ; ok if not ** <C440/18nov86/MBK> **
AddQ #1,D3 ; else advance to next char ** <C440/18nov86/MBK> **
@0
Cmp teSelEnd(A3),D3 ; not ready for stage 3 if not yet
Bls.S dSkip3 ; past selEnd
Move.L A2,savePtr(A6) ; save ptr for move up
Move.W (A2),D0 ; old line start
Sub D3,D0 ; oldStart - newStart
Cmp D0,D7 ; compare to delta
Beq.S dStage3
; ** <C971/RWW110387> Added this code to support tabs
; Cmp.B #$0D,-1(A1,D3) ; get the last char
Move.B -1(A1,D3),D0 ; THESE TWO LINES REPLACE PREVIOUS <C971/RWW110387>
Bsr TEEolHook ; <C971/RWW110387>
Bne.S dSkip3 ; if CR stage 2 is over
; look for the old value of this line
Move.L A2,A0
Move.W D3,D0 ; line start + delta
Add.W D7,D0
@1 Cmp.W (A0)+,D0 ; must be a match
Bhi.S @1 ; made this unsigned ** <C381/6nov86/MBK> **
SubQ #2,A0 ; got over-incremented
Move.L A0,savePtr(A6) ; save ptr for move up
Bra.S dStage3
dSkip3
; update the table with new start
AddQ #1,teNLines(A3) ; inc # of lines
Move D3,(A2)+ ; lines[nLines]:=i
Move D3,D6 ; now start with the next line
Cmp teLength(A3),D6 ; while i < length do
Bhs.S endDRecal
Bsr FindLine ; get line after D6 <C971/RWW102887>NO
Move D0,D3 ; findline returns in D0
Bra.S dStage2 ; if so, never do background
; Fill out following line offsets with delta and return in D4 the redraw end
dStage3
Move.L A2,A0
Move.L savePtr(A6),A0 ; source ptr
Cmp.L A2,A0 ; same as dest ptr?
Beq.S @3 ; if so, no lines deleted
Move.W teLength(A3),D3 ; else, redraw everything
@3 Move D3,savedD4(A6) ; found it, record in dispEnd
dStage3A
; update the table with new start
AddQ #1,teNLines(A3) ; increment # lines
Move.W (A0)+,D0
Sub D7,D0 ; lines[nLines]:=lines[nLines]-delta
Move.W D0,(A2)
Move (A2)+,D6 ; see if done
Cmp teLength(A3),D6 ; while i < length do
Blo.S dStage3A
endDRecal Rts
EndIf ; <PMAB381/RWW020488>
; ** <C105/3Sep86/MBK> ** Stages 2 and 3 for insertion only
defBufSize Equ 256 ; initial size of temp line start buffer
InsertRecal
MoveM.L D2/D4,-(SP) ; save stuff
MoveQ #0,D5 ; line start counter
Move.W teSelEnd(A3),D4
If &TYPE('&RWWDebug') = 'UNDEFINED' Then
Tst.W D7 ; Only do "subtraction" if negative <PMAB381/RWW020488>
Bpl.S @05 ; <PMAB381/RWW020488>
EndIf
Sub.W D7,D4 ; selEnd + delta
@05
; ** <C393/10nov86/MBK> ** MyNewHandle unlocks the TEHandle for memory allocation and resets
; the A3 ptr, so the A2 ptr must also be reset
Sub.L A3,A2 ; save A2 as an offset ** <C393/10nov86/MBK> **
Move.L #defBufSize,D0 ; don't want to reset too often ** <C381/6nov86/MBK> **
Move.L D0,D2 ; save initial handle size
Bsr MyNewHandle ; temp handle for line starts ** <C381/7nov86/MBK> **
_HLock ; play it safe
Move.L (A0),A1 ; save ptr
Move.L A0,startHndl(A6) ; save handle
Add.L A3,A2 ; restore A2 as a ptr ** <C393/10nov86/MBK> **
Move.L A2,savePtr(A6) ; current line start ptr
iStage2
; If the width of a single character > the width of the window, Recal keeps
; finding the same line (line 1) forever. If this happens, don't keep trying
; to wrap, just advance to the next character.
Cmp.W D6,D3 ; same as old value? ** <C440/18nov86/MBK> **
Bne.S @0 ; ok if not ** <C440/18nov86/MBK> **
AddQ #1,D3 ; else advance to next char ** <C440/18nov86/MBK> **
@0
Cmp D4,D3 ; not ready for stage 3 if not yet
Bls.S iSkip3 ; past selEnd
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; deref
; ** <C971/RWW110387> Added code to support tabs
; Cmp.B #$0D,-1(A0,D3) ; get the last char
Move.B -1(A0,D3),D0 ; THESE TWO LINES REPLACE PREVIOUS <C971/RWW110387>
Bsr TEEolHook ; <C971/RWW110387>
Bne.S @3 ; keep going if not CR
Move.L A2,A0 ; set current ptr
Move.W D3,D0 ; get line start
Add.W D7,D0 ; minus delta (D7 is neg)
; find the old value of this line start for moving down remaining line starts
@1 Cmp.W (A0)+,D0
Bhi.S @1 ; made this unsigned ** <C381/6nov86/MBK> **
SubQ #2,A0 ; got over-incremented
Move.L A0,savePtr(A6) ; save it
Bra.S iStage3 ; on to stage 3
@3
; D5 may be greater than the old number of lines, so skip the
; delta check if so. This was a really obscure bug which only
; hurt us when D0 happened to be equal to D7.
MoveQ #0,D0 ; clear entire register
Move.W oldNLines(A6),D0 ; get old # of lines
Add.W D0,D0 ; double for word entries
Cmp.L D0,D5 ; have we exceeded the length of the array?
Bhs.S iSkip3 ; skip delta check if so
Move.W 0(A2,D5.L),D0 ; get old start
Sub D3,D0 ; oldStart - newStart
Cmp D0,D7 ; compare to delta
Bne.S iSkip3 ; keep trying if not same
Add.L D5,savePtr(A6) ; set old start for move down
Bra.S iStage3
iSkip3
; increase sizes of temporary arrays if needed
Cmp.L D5,D2 ; time to increase sizes?
Bgt.S @0
Move.L startHndl(A6),A0 ; temp line starts handle
_HUnlock
Add.L #defBufSize,D2 ; inc size for line starts ** <C381/6nov86/MBK> **
Move.L D2,D0
Sub.L (A0),A1 ; make ptr an offset
Bsr MySetHandleSize ; reset handle size ** <C381/7nov86/MBK> **
_HLock
Add.L (A0),A1 ; make the offset a ptr again
@0 Move D3,(A1)+ ; lines[nLines]:=i
Move D3,D6 ; now start with the next line
AddQ #1,teNLines(A3) ; increment # lines
AddQ.L #2,D5
Cmp teLength(A3),D6 ; while i < length do
Blo.S @1 ; keep finding lines ** <C229/28oct86/MBK> **
Move.W oldNLines(A6),D0 ; get old # of lines ** <C229/28oct86/MBK> **
AddQ.W #1,D0 ; plus 1 to pt to end ** <C229/28oct86/MBK> **
Add.W D0,D0 ; double for word entries ** <C229/28oct86/MBK> **
Lea teLines(A3,D0),A0 ; plus base address ** <C229/28oct86/MBK> **
Move.L A0,savePtr(A6) ; save it for replace ** <C229/28oct86/MBK> **
Bra.S iStage3A ; go munge ** <C229/28oct86/MBK> **
@1 Bsr FindLine ; get line after D6 <C971/RWW102887>NO
Move D0,D3 ; findline returns in D0
Bra iStage2 ; if so, never do background <C971/RWW102887>NO
; Fill out following line offsets with delta and return in D4 the redraw end
iStage3
Move D3,savedD4(A6) ; found it, record in dispEnd
; Still need to munge if D5 is 0, in case something was inserted over a CR.
; Line which skipped munging if D5 = 0 was deleted.
Move.L savePtr(A6),D0
Sub.L A2,D0 ; change in # of lines?
Sub.L D5,D0
Beq.S iStage3A
Move.W teLength(A3),D3 ; if so, must display all
iStage3A Move D3,savedD4(A6) ; found it, record in dispEnd
Move.L A4,A0
_HUnLock ; unlock TEHandle
SubQ.L #4,SP ; room for ret value
Move.L A4,-(SP) ; TEHandle
Move.L A2,D0
Sub.L A3,D0 ; offset to line preceding insert
Move.L D0,-(SP)
Move.L #0,-(SP) ; Nil ptr
Move.L savePtr(A6),D0 ; end of insertion
Sub.L A2,D0 ; - beg of insertion
Move.L D0,-(SP)
Move.L startHndl(A6),A0
Move.L (A0),-(SP) ; ptr to new line starts
Move.L D5,-(SP) ; length of insertion
Sub.L A3,A2 ; save as offset
_Munger ; (TEHandle, preInsertPoint, NIL, selectionLen, newLineStarts, insertLen);
AddQ.L #4,SP ; don't care
Move.L A4,A0
_HLock ; relock TEHandle
Move.L (A4),A3 ; deref
Add.L A3,A2 ; restore as ptr
Add.L D5,A2 ; adjust ptr for move down
sameLine Move.L startHndl(A6),A0 ; get rid of line starts handle
_DisposHandle
Cmp teLength(A3),D6 ; if i >= length quit
Bhs.S endIRecal
iStage3B
; update the table with new start
AddQ #1,teNLines(A3) ; increment # lines
Sub D7,(A2) ; lines[nLines]:=lines[nLines]-delta
Move (A2)+,D6 ; see if done
Cmp teLength(A3),D6 ; while i < length do
Blo.S iStage3B
endIRecal MoveM.L (SP)+,D2/D4 ; other stuff
Rts
; ----------------------------------------------------------------------
; PROCEDURE SetLineHite
; ** Added 6/18/86 by MBK **
; SetLineHite takes the maximum height for the current line
; (which was determined in FindLine) and stores it in the
; array of maximum line heights.
; ** <C229/28oct86/MBK> ** Changed to reset all heights at end of recal
; Entry:
; A4 is pointing into array in which to insert line heights and
; ascents
; ----------------------------------------------------------------------
SetLineHite
MoveM.L D2-D5/A2/A4,-(SP) ; save registers
Tst.W teSize(A3) ; record with style?
Bpl endSetLH ; quit if not
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; deref
Move.L lhTab(A0),A0 ; line heights array
_GetHandleSize ; get current size
Move.W D0,D3 ; save size in D3
AsR.W #2,D3 ; get # of lines
MoveQ #0,D0 ; clear whole reg
Move.W teNLines(A3),D0 ; get # of lines
AddQ.L #1,D0 ; + 1 for last entry
LsL.L #2,D0 ; for 2 integers
Bsr MySetHandleSize ; reset handle size ** <C381/7nov86/MBK> **
Move.L teStylesH(A3),A1 ; handle to style info ** <C381/6nov86/MBK> **
Move.L (A1),A1 ; deref ** <C381/6nov86/MBK> **
Move.L lhTab(A1),A4 ; line heights array
Move.L (A4),A4 ; deref
Tst.W teLength(A3) ; any text?
Bne.S @0 ; no default needed if so ** <C381/6nov86/MBK> **
; If all text was deleted, set line height according to only remaining style.
Move.W runs+2(A1),D0 ; index to 1st style ** <C440/19nov86/MBK> **
Bsr GetStyle ; get ptr to 1st style ** <C440/19nov86/MBK> **
Move.W stHeight(A0),(A4)+ ; store line height ** <C440/19nov86/MBK> **
Move.W stAscent(A0),(A4) ; store the ascent ** <C440/19nov86/MBK> **
Bra endSetLH ; and quit ** <C440/19nov86/MBK> **
@0 Move.L styleTab(A1),A0 ; styles array
Move.L (A0),A0 ; deref
Lea runs(A1),A1 ; pt to style runs
Lea teLines(A3),A2 ; pt to line starts
MoveQ #0,D1 ; set max
MoveQ #0,D2 ; set starting line #
Move.L #-1,D4 ; starting redraw line ** <C381/8nov86/MBK> **
Move.W (A4),D5 ; save old value ** <C381/8nov86/MBK> **
setLoop Move.W styleIndex(A1),D0 ; index to current style
MulU #stRecSize,D0 ; multiply index by size of record
Cmp.W stHeight(A0,D0.L),D1 ; compare to current max ** <C381/6nov86/MBK> ** made D0 long
Bge.S @1 ; already have max
Move.W stHeight(A0,D0.L),D1 ; else save as new max ** <C381/6nov86/MBK> ** made D0 long
Cmp.W D2,D3 ; is this a new entry?
Ble.S @0 ; just set it if so
Tst.W (A4) ; else, see if it should be set
Bmi.S @1 ; if neg don't reset
@0 Move.W D1,(A4) ; else set height
Move.W stAscent(A0,D0.L),2(A4) ; set ascent ** <C381/6nov86/MBK> ** made D0 long
@1 Move.W 2(A2),D0 ; get next line start
Cmp.W stStartSize(A1),D0 ; cmp to style start
Blo.S @3 ; made this unsigned ** <C381/6nov86/MBK> **
Beq.S @2 ; next style
AddQ.L #stStartSize,A1 ; pt to next style
Bra.S setLoop ; keep checking this line
@2 AddQ.L #stStartSize,A1 ; pt to next style
@3 AddQ.L #2,A2 ; pt to next line
Tst.L D4 ; line to start redraw from ** <C381/8nov86/MBK> **
Bpl.S @4 ; don't reset it ** <C381/8nov86/MBK> **
Cmp.W (A4),D5 ; compare to old max ** <C381/8nov86/MBK> **
Beq.S @4 ; ok if same ** <C381/8nov86/MBK> **
MoveQ #0,D4 ; clear neg value in hi word ** <C381/8nov86/MBK> **
Move.W D2,D4 ; store line # for redraw ** <C381/8nov86/MBK> **
@4 AddQ.L #4,A4 ; next line height entry
Move.W (A4),D5 ; save old value ** <C381/8nov86/MBK> **
MoveQ #0,D1 ; reset max
AddQ #1,D2 ; inc counter
Cmp.W teNLines(A3),D2 ; check counter
Blo.S setLoop ; loop if more lines ** <C381/6nov86/MBK> ** changed BNE to BCS
Move.L -4(A4),(A4) ; last dummy entry
Tst.L D4 ; change in heights? ** <C381/8nov86/MBK> **
Bmi.S endSetLH ; quit if not ** <C381/8nov86/MBK> **
Move.W teLength(A3),savedD4(A6) ; must redraw to bottom ** <C381/8nov86/MBK> **
Add.W D4,D4 ; double the line # ** <C381/8nov86/MBK> **
Move.W teLines(A3,D4),D0 ; get start of line ** <C381/8nov86/MBK> **
Cmp.W savedD2(A6),D0 ; don't reset if new start ** <C381/8nov86/MBK> **
Bhs.S endSetLH ; is greater than old start ** <C381/8nov86/MBK> **
Move.W D0,savedD2(A6) ; store as new display start ** <C381/8nov86/MBK> **
endSetLH MoveM.L (SP)+,D2-D5/A2/A4 ; restore registers
Rts
; ----------------------------------------------------------------------
; PROCEDURE ShowCaret
; PROCEDURE HideCaret
; PROCEDURE DrawCaret
; PROCEDURE EraseCaret
; Entry:
; A3 contains dereferenced handle
; ----------------------------------------------------------------------
ShowCaret
Tst.B teActive(A3) ; do nothing if not active
Beq.S noDrawIt ; <C971/RWW102887>NO
Move teSelStart(A3),D0 ; see if should be turned on
Cmp teSelEnd(A3),D0
Bne.S noDrawIt ; if selection <> 0 then escape
ST teCarAct(A3) ; activate caret
DrawCaret
Tst.B teCarOn(A3) ; see if caret is on
Bne.S noDrawIt ; don't draw it if so
ST teCarOn(A3) ; caret marked on
ForceCaret
Bra.S DrawIt ; force a redraw
HideCaret
Tst.B teActive(A3) ; do nothing if not active
Beq.S noDrawIt ; <C971/RWW102887>NO
SF teCarAct(A3) ; deactivate caret
EraseCaret
Tst.B teCarOn(A3) ; see if caret is on
Beq.S noDrawIt ; don't draw it if so
SF teCarOn(A3) ; caret marked on
; Must be called with sorted selStart and selEnd
DrawIt
MoveM.L D0-D7,-(SP)
Move teSelStart(A3),D3 ; dispStart:=selStart
Move D3,D4 ; dispEnd:=same
MoveQ #teLoc,D7 ; does nothing except moves pen
Bsr DoText ; draw the caret
Move.L teCarHook(A3),D0 ; do the inversion via hook if there
; Call new procedure for caret highlighting, so that color highlighting
; won't be used.
;; If forRAM THEN
If (NOT ForROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; color QD around? <C971/RWW112487>
Bnz.S @1 ; nope <C971/RWW112487>
Bsr CaretHook ; <C971/RWW112487>
Bra.S @2 ; <C971/RWW112487>
@1 Bsr InvertHook ; <C971/RWW112487>
@2
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
Bsr CaretHook ; <C971/RWW102887>NO
Else
Bsr InvertHook ; <C971/RWW102887>NO
EndIf
MoveM.L (SP)+,D0-D7
noDrawIt
Rts
; ----------------------------------------------------------------------
; PROCEDURE TEActivate( h: TEHandle )
; PROCEDURE TEDeActivate( h: TEHandle )
; ----------------------------------------------------------------------
TEActivate
Bsr StdEntry ; <C971/RWW102887>NO
Tst.B teActive(A3) ; see if already active
Bne.S goGoHome
Move teSelStart(A3),D0 ; Only enable the caret
Cmp teSelEnd(A3),D0
Bne.S @1
ST teCarAct(A3) ; activate caret/don't show yet
@1
ST teActive(A3) ; flag as active
Bsr Hilite
goGoHome
Bra.S goHome
TEDeactivate
Bsr StdEntry ; <C971/RWW102887>NO
Tst.B teActive(A3) ; see if already inactive
Beq.S goHome
Bsr.S HideCaret ; hide the caret
Bsr HiLite ; Remove old selection
SF teActive(A3) ; flag as inactive
Bra.S goHome
; ----------------------------------------------------------------------
; PROCEDURE TEIdle( h: TEHandle )
; ----------------------------------------------------------------------
TEIdle
Bsr StdEntry ; <C971/RWW102887>NO
Tst.B teCarAct(A3) ; see if active
Beq.S goHome
SubQ #4,SP ; make room for result
_TickCount ; Get current time
Move.L (SP)+,A0 ; use A0 for auto extend
Cmp.L teCarTime(A3),A0 ; see if done
Blo.S goHome
Add.L caretTime,A0 ; next time
Move.L A0,teCarTime(A3)
If &TYPE('&RWWDebug') <> 'UNDEFINED' Then
Bsr DrawIt ; flip the caret
Else
Bsr.S DrawIt ; flip the caret
EndIf
Not.B teCarOn(A3) ; flip the flag
goHome
Bra epilog4
; ----------------------------------------------------------------------
; PROCEDURE TEPaste( h: TEHandle );
; ----------------------------------------------------------------------
TEPaste
Bsr StdEntry
MoveQ #0,D7 ; flag says normal paste
Bsr.S DoPaste ; <C971/RWW102887>NO
Bra.S goHome ; {epilog4} <C971/RWW102887>NO
DoPaste
; ** <C207/15oct86/MBK> ** Don't wipe out desk scrap for old TERecs in case applications
; use it for Undo
Tst.W teSize(A3) ; record with style?
Bpl.S @2 ; paste from TEscrap if not
; allocate a new handle for the text scrap contents
MoveQ #0,D0 ; min size ** MBK 6/20/86 **
Bsr MyNewHandle ; get a temp handle ** <C381/7nov86/MBK> **
Move.L A0,D6 ; save the handle ** MBK 6/20/86 **
Move.L A0,-(SP) ; push it ** MBK 6/20/86 **
; copy desk scrap to my temp scrap
SubQ.L #4,SP ; room for VAR ** MBK 6/20/86 **
Move.L SP,A1 ; save this address ** MBK 6/20/86 **
SubQ.L #4,SP ; make room for result ** MBK 6/20/86 **
Move.L A0,-(SP) ; push new handle ** MBK 6/20/86 **
Move.L #'TEXT',-(SP) ; scrap type ** <C381/5nov86/MBK> **
Move.L A1,-(SP) ; push address ** MBK 6/20/86 **
_GetScrap ; get desk scrap ** MBK 6/20/86 **
Move.L (SP)+,D0 ; error code ** MBK 6/20/86 **
AddQ.L #4,SP ; don't care ** MBK 6/20/86 **
Tst.L D0 ; error? ** MBK 6/20/86 **
Ble.S @1 ; no text scrap ** MBK 6/20/86 **
Move.L D0,D5 ; length of scrap ** MBK 6/20/86 **
Move.L D6,A0 ; ** MBK 6/20/86 **
_HLock ; lock text scrap ** MBK 6/20/86 **
Move.L (A0),D6 ; ptr to scrap ** MBK 6/20/86 **
Bsr.S PasteGuts ; go paste the scrap <C971/RWW102887>NO
@1 Move.L (SP)+,A0 ; temp scrap handle ** MBK 6/20/86 **
_DisposHandle ; get rid of it ** MBK 6/20/86 **
Bra.S @3
; ** <C207/15oct86/MBK> ** paste from old TEScrp, for old TERecs only
@2 Move.L teScrpHandle,A0 ; insertion = scrap
_HLock ; lock it
Move.L (A0),D6 ; now dereference
MoveQ #0,D5 ; clear whole reg
Move teScrpLength,D5 ; insertion length
Bsr.S PasteGuts ; go paste the scrap
Move.L teScrpHandle,A0 ; insertion = scrap
_HUnLock ; unlock it
@3 Rts
; ----------------------------------------------------------------------
; PROCEDURE iTEStylPaste( h: TEHandle );
; ** Added 6/20/86 by MBK **
; TEStylePaste pastes the 'styl' scrap as well as the 'TEXT'
; scrap. TEPaste, on the other hand, simply extends the current
; style in the text to include the pasted text. Both work
; the old way for records without style.
; ----------------------------------------------------------------------
iTEStylPaste
MoveQ #1,D7 ; flag says normal paste
Bsr.S DoPaste ; <C971/RWW102887>NO
MoveQ #6,D0
Bra StdExit2
; ----------------------------------------------------------------------
; PROCEDURE PstRsrved;
; ** <C851/14Apr87/MBK> **
; I changed teReserved to a handle to the following structure:
; Record
; newReserved : LONGINT;
; nullScrap : stScrpHandle;
; End;
; nullScrap is used to store a style which is set when the
; selection is NIL in iTESetStyle. I store it in the scrap
; format so that it can easily be inserted using PstStylGuts.
; This procedure is called to paste the reserved style if there
; is one, and otherwise just to extend the current style.
; ----------------------------------------------------------------------
PstRsrved
Move.L teStylesH(A3),A0 ; get style handle
Move.L (A0),A0 ; deref
Move.L nullStyle(A0),A0 ; get reserved handle
Move.L (A0),A0 ; deref
Move.L nullScrap(A0),A1 ; get handle to scrap for null selection
Move.L A1,-(SP) ; save for unlocking later
Move.L (A1),A0 ; deref
Tst.W scrpNStyles(A0) ; is there a style?
Beq.S @0 ; do extend if not
MoveM.L D3/A4,-(SP)
Move.L A1,A4 ; put scrap handle in A4
; Gotta lock down null scrap!
Move.L A1,A0
_HLock
MoveQ #0,D3 ; clear whole register
Move.W teSelStart(A3),D3 ; PstStylGuts wants this
Bsr PstStylGuts ; go paste it
MoveM.L (SP)+,D3/A4
Bra.S @1
@0 Bsr ExtendStyle ; just extend
@1
; Unlock previously locked null scrap
Move.L (SP)+,A0
_HUnlock
Rts
; ----------------------------------------------------------------------
; PROCEDURE PasteGuts
; Entry:
; D7 = 0, if ExtendStyle should be used to update style table
; 1, if PasteStyle should be used to update style table
; D5 = insert length after the delete
; D6 = pointer to text to insert
; ----------------------------------------------------------------------
PasteGuts
; The following routines cannot trash D5/D6
Move.W D7,-(SP) ; save flag
Bsr HideCaret ; <C971/RWW102887>NO
Bsr HiLite ; remove selection <C971/RWW102887>NO
Tst.W teSize(A3) ; check style flag
Bpl.S @1 ; no, skip style paste
Tst.W (SP) ; paste or extend?
Beq.S @0
Bsr.S PasteStyle ; paste associated style <C971/RWW102887>NO
Bra.S @1 ; no, skip style paste
@0 Bsr.S PstRsrved ; get the style <C971/RWW102887>NO
@1 Bsr SelSort ; sort select (A2 ^selStart/End)<C971/RWW102887>NO
Move D0,D7 ; calc delta amount(selEnd in D0)
Sub (A2),D7 ; ...for ReCalLines (A2 ^selStart)
Bsr MungeSetup ; setup for the paste replace
Move D7,-(SP) ; length for delete
Clr -(SP) ; fake long length
Move.L D6,-(SP) ; pointer to insert = p2
Move.L D5,-(SP) ; length to insert = l2
_Munger ; use sloppy munger
AddQ.L #4,SP ; pop result
Move.L teTextH(A3),A0 ; get text handle
_Hlock ; and relock it
Sub D7,teLength(A3) ; length:=length -(selEnd-selStart)
Add D5,teLength(A3) ; adjust length by insert amount
Sub D5,D7 ; adjust delta amount for ReCalLines
Bsr RecalDraw ; redo the line stuff
Lea teSelStart(A3),A0 ; point to selStart
Add D5,(A0) ; selStart:=selstart + insert amount
Move (A0)+,(A0) ; selEnd:=selStart
Bsr ShowCaret ; <C971/RWW102887>NO
Bsr SelView ; insure selection is visible
AddQ.L #2,SP ; remove flag from stack
Rts
; ----------------------------------------------------------------------
; PROCEDURE PasteStyle
; ** Added 5/28/86 by MBK **
; PasteStyle inserts the style scrap into the TERec style array
; If txSize is set to -1 (otherwise this is considered a record
; without style).
; Entry:
; D5: length of pasted text
; A3: ptr to TERec
; ----------------------------------------------------------------------
PasteStyle
Tst.W teSize(A3) ; check style flag
Bpl.S EndPStyl ; only like stylish records <C971/RWW102887>NO
MoveM.L D2-D6/A2/A4,-(SP) ; save stuff
Bsr SelSort ; get selStart, selEnd
Move.W D0,D4 ; selEnd
Swap D0
MoveQ #0,D3 ; make sure all clear ** <C207/13oct86/MBK> **
Move.W D0,D3 ; selStart
; allocate a new handle for the styl scrap contents
MoveQ #0,D0 ; min size
Bsr MyNewHandle ; get a temp handle ** <C381/7nov86/MBK> **
Move.L A0,A4 ; store the handle
Move.L A0,-(SP) ; save the handle
; copy desk scrap to my temp scrap
SubQ.L #4,SP ; room for VAR
Move.L SP,A1 ; save this address
SubQ.L #4,SP ; make room for result
Move.L A0,-(SP) ; push new handle
Move.L #'styl',-(SP) ; scrap type ** <C381/5nov86/MBK> **
Move.L A1,-(SP) ; don't care what this is
_GetScrap ; get desk scrap
Move.L (SP)+,D0 ; error code
AddQ.L #4,SP ; don't care
Tst.L D0 ; style found?
Bpl.S @0 ; there was a style in scrap!
Bsr PstRsrved ; get the style
Bra.S @4 ; extend current style <C971/RWW102887>NO
; 'styl' scrap was found, delete styles formerly associated with the selection
@0 Move.L A4,A0
_HLock ; lock scrap handle while deleting
Move.W D3,D0 ; selStart
Move.W D4,D1 ; selEnd
Bsr DeleteStyle ; delete associated styles
Bsr.S PstStylGuts ; do the paste
; get rid of temp scrap handle
@4 Move.L (SP)+,A0 ; temp scrap handle
_DisposHandle ; get rid of it
MoveM.L (SP)+,D2-D6/A2/A4 ; restore stuff
EndPStyl Rts
; ----------------------------------------------------------------------
; PROCEDURE PstStylGuts
; ** Separated out from PasteStyle 23jan87 by MBK **
; PstStylGuts inserts the style info pointed at by the A4
; handle into the TERec style array.
; Entry:
; D3: selStart (high word must be clear!)
; D5: length of pasted text
; A3: ptr to TERec
; A4: handle to style info
; ----------------------------------------------------------------------
PstStylGuts
; set up ptr to where new styles will be inserted
Move.W D3,D0 ; get selStart
SubQ #1,D0 ; pre-decrement
Bsr GetCurStyle ; get current style
Move.W D0,D4 ; index to current style
Move.L (A4),A4 ; dereference
Move.W scrpNStyles(A4),D2 ; get # of styles in scrap
Lea scrpStyleTab(A4),A4 ; ptr to style array
Move.W D3,D0 ; selStart
Bne.S @0 ; dup if not 0
Tst.W D2 ; make sure num styles <> 0
Beq.S @05
SubQ #1,D4 ; adjust index for this style
Bra.S @05
@0 Bsr DupStyle ; make copy of style if needed
Add.L #stStartSize,A0 ; pt to next style
@05
Add.W D2,D4 ; save index to last style
Bsr.S MakeRoom ; make room in array <C971/RWW102887>NO
Move.L A0,A2 ; updated ptr
Move.L teStylesH(A3),A0 ; lock handle because
_HLock ; you'll be munging
; loop over styles in scrap, adding them to styles array if not there already
@1 Move.L scrpStartChar(A4),D1 ; get scrap start offset ** <C207/13oct86/MBK> **
Add.L D3,D1 ; plus current offset ** <C207/13oct86/MBK> **
Cmp.L #$FFFF,D1 ; offset cannot be > 64K ** <C381/6nov86/MBK> **
Bhi.S @3 ; if it is don't add it ** <C207/13oct86/MBK> **
Move.W D1,-(SP) ; save offset ** <C207/13oct86/MBK> **
Move.L A4,A0 ; ptr to stuff that counts
; The count is a longint in the scrap style table, so I should be adding
; 2 to point to where a regular style record would be pointing. Otherwise,
; FindStyle will not find this style in the table.
AddQ.L #2,A0
Bsr FindStyle ; look for it
Tst.L D0 ; do we have it already?
Bne.S @2 ; yes
Move.L A4,A0
AddQ.L #2,A0 ; skip high word ** <C207/13oct86/MBK> **
Bsr AddStyle ; else, add it
Move.W #1,stCount(A1) ; A1 is still pointing to style entry
; in either case insert new style descriptor in runs array
@2 Move.W (SP)+,D1 ; restore offset
Move.W D1,(A2)+ ; store style start
Move.W D0,(A2)+ ; store style index
@3 Add.L #scrpRecSize,A4 ; pt to next scrap style
SubQ.W #1,D2 ; dec style counter (make word len!) <PMAB381/RWW020488>
Bne.S @1 ; keep looping if more
SubQ #stStartSize,A2
; add size of pasted text to all following style starts
Move.L teStylesH(A3),A0 ; handle to style info
_HUnlock ; ok to unlock it now
Move.L A2,A0 ; ptr to last style
Move.W D4,D0 ; index to last style
Bsr RecalStStarts ; inc following style starts
Bsr ConcatStyles ; allow no duplications ** <C182/2oct86/MBK> **
Bsr ClearRsrved ; clear reserved handle
Rts
; ----------------------------------------------------------------------
; PROCEDURE MakeRoom
; ** Added 6/19/86 by MBK **
; MakeRoom moves down the contents of the runs array
; to make room for new entries.
; Entry:
; D2: # of new entries
; A0: ptr from which to move
; Exit:
; A0: new ptr value (after resizing)
; ----------------------------------------------------------------------
MakeRoom
MoveM.L D2-D3/A2,-(SP)
Move.L A0,A2 ; ptr from which to move
Move.L teStylesH(A3),A0 ; style runs
_HUnlock ; do this before setting D0
Move.L (A0),A1
MoveQ #1,D0 ; + 1 for dummy end ** <C381/6nov86/MBK> **
Add.W nRuns(A1),D0 ; current # of style runs ** <C381/6nov86/MBK> **
Add.W D2,nRuns(A1) ; new # of styles
LsL.L #2,D0 ; * stStartSize ** <C381/6nov86/MBK> **
Move.L D0,D3 ; preserve size for block move
Add.L #stBaseSize,D0 ; add rest of handle size ** <C381/7nov86/MBK> **
Lea runs(A1),A1 ; pt to start of style runs
Sub.L A1,A2 ; preserve ptr as an offset ** <C381/6nov86/MBK> **
Sub.L A2,D3 ; amount to be moved down
Ext.L D2 ; make it a long ** <C381/6nov86/MBK> **
LsL.L #2,D2 ; * stStartSize ** <C381/6nov86/MBK> **
Add.L D2,D0 ; new size of block
Bsr MySetHandleSize ; reset handle size ** <C381/7nov86/MBK> **
Move.L (A0),A1 ; dereference
Lea runs(A1),A1 ; pt to start of style runs
Add.L A2,A1 ; source ** <C381/6nov86/MBK> **
_HLock ; assume locked state ** <C381/7nov86/MBK> **
Move.L A1,A0
Add.L D2,A1 ; destination
Move.L D3,D0 ; length
_BlockMove ; make room
MoveM.L (SP)+,D2-D3/A2
Rts
; ----------------------------------------------------------------------
; PROCEDURE DupStyle
; ** Added 6/11/86 by MBK **
; DupStyle makes a duplicate copy of the current style ptr
; If no new style starts at the current cursor position.
; This is used when the style is about to be broken up by
; newly inserted styles (such as from TEStylePaste).
; Entry:
; D0: selStart
; A0: ptr to current style
; ----------------------------------------------------------------------
DupStyle
Move.L D2,-(SP)
Move.L A0,A1
Add.L #stStartSize,A0 ; pt to next
Cmp.W startChar(A0),D0 ; does a new style start here?
Beq.S @0 ; if so, no need to dup
Move.W D0,-(SP)
MoveQ #1,D2 ; one style to insert
Bsr.S MakeRoom ; make room for it <C971/RWW102887>NO
Move.L A0,A1 ; copy it
SubQ #stStartSize,A1 ; point to prev style
Move.W (SP)+,startChar(A0) ; get style start
Move.W styleIndex(A1),D0 ; get style's index ** <C381/7nov86/MBK> **
Move.W D0,styleIndex(A0) ; copy style index ** <C381/7nov86/MBK> **
; ** <C381/7nov86/MBK> ** obscure bug found by Andy H.; DupStyle should inc the stCount
Bsr GetStyle ; get the style ** <C381/7nov86/MBK> **
AddQ #1,stCount(A0) ; and inc the count
@0 Move.L (SP)+,D2
Move.L A1,A0
Rts
; ----------------------------------------------------------------------
; PROCEDURE FindStyle
; ** Added 5/29/86 by MBK **
; FindStyle looks for a style in the style array matching the
; style pointed at by A0.
; Entry:
; A0: ptr to style being sought
; A3: TEHandle
; Exit:
; D0(High): 1 if style was found, 0 otherwise
; D0(Low): style index if style is found, 0 otherwise
; A0: ptr to entry in style array if style is found,
; No change otherwise
; ----------------------------------------------------------------------
FindStyle
Move.L D2,-(SP) ; save stuff
; get ptr to 1st style in text
Move.L teStylesH(A3),A1 ; get style handle
Move.L (A1),A1 ; dereference
Move.W nStyles(A1),D2 ; get # of styles in text
Move.L styleTab(A1),A1 ; handle to styles array
Move.L (A1),A1 ; dereference
Lea stFont(A0),A0 ; set ptr to relevent data
Move.W D2,D1 ; init to # of styles
; loop over styles comparing to the one being sought
@0 Tst.W stCount(A1) ; is this style being used?
Beq.S @1 ; doesn't count if not
Bsr.S CompareStyles ; do the styles match? <C971/RWW102887>NO
; Tst.W D0 ; REDUNDANT! <PMAB381/RWW020488>
Beq.S @2 ; go if you have a match
@1 Add.L #stRecSize,A1 ; point to next style
SubQ #1,D1 ; dec counter
Bne.S @0 ; keep trying
MoveQ #0,D0 ; clear flag to indicate not found
Bra.S @3
; a matching style was found, set flag and style index
@2 MoveQ #1,D0 ; indicates style found ** <C381/6nov86/MBK> **
Swap D0 ; faster than MOVE.L #$10000,D0 ** <C381/6nov86/MBK> **
Sub.W D1,D2 ; get the difference
Move.W D2,D0 ; return index in D0(Low)
AddQ.W #1,stCount(A1) ; inc the count
Move.L A1,A0 ; return ptr in A0
@3 Move.L (SP)+,D2 ; restore stuff
Rts
; ----------------------------------------------------------------------
; PROCEDURE CompareStyles
; ** Added 5/29/86 by MBK **
; CompareStyles compares two styles byte by byte.
; Entry:
; A0: ptr to one style
; A1: ptr to another style
; Exit:
; D0: non-zero if styles don't match, 0 if they do
; ----------------------------------------------------------------------
CompareStyles
MoveM.L A0-A1,-(SP) ; save ptrs
Lea stFont(A1),A1 ; set ptr to relevent data
Move.L #styleSize,D0 ; get size of style descriptor
@0 CmpM.B (A0)+,(A1)+ ; compare a byte
Bne.S @1 ; quit if not equal
SubQ #1,D0 ; else dec the counter
Bne.S @0 ; keep comparing if not 0
@1 MoveM.L (SP)+,A0-A1 ; restore ptrs
Rts
; ----------------------------------------------------------------------
; PROCEDURE AddStyle
; ** Added 5/30/86 by MBK **
; AddStyle adds a new style to the styles array.
; Entry:
; A0: ptr to style to be added
; A3: TEHandle
; Exit:
; D0: style index
; ----------------------------------------------------------------------
AddStyle
MoveM.L D2-D3/A2,-(SP)
; Get # of styles and handle to them
Move.L teStylesH(A3),A1 ; get handle to style info
Move.L (A1),A2 ; dereference
Move.W nStyles(A2),D0 ; get # of styleRecs
Move.W D0,D3 ; save it
Move.L styleTab(A2),A1 ; handle to styleRecs
Move.L (A1),A1 ; dereference
; If a style has a count of 0, its location may be reused by the new style
@0 Tst.W stCount(A1) ; style being used?
Beq.S @1 ; if not, it can be reused
Add.L #stRecSize,A1 ; else, pt to next style rec
SubQ #1,D0 ; dec the counter
Bne.S @0 ; keep trying
; No empty slots found, so create room at the end
Move.L A0,-(SP) ; save ptr to new style
AddQ #1,nStyles(A2) ; inc # of styleRecs
Move.L styleTab(A2),A0 ; handle to styleRecs
_GetHandleSize ; how big is it?
Move.L D0,D2 ; save size
Add.L #stRecSize,D0 ; inc size by 1 record
; ** <C381/6nov86/MBK> ** didn't need to reset A0 again since GetHandleSize doesn't trash it
Move.L A0,A2 ; handle to styleRecs ** <C381/6nov86/MBK> **
Bsr MySetHandleSize ; reset handle size ** <C381/7nov86/MBK> **
Move.L (SP)+,A0 ; restore ptr to new style
Move.L (A2),A1 ; dereference
Add.L D2,A1 ; add record at end
MoveQ #0,D0 ; will be using last slot
@1 Sub.W D0,D3 ; get the index
Move.L #stRecSize,D0 ; size of record
_BlockMove ; copy it to styleRec array
Move.W D3,D0 ; return the index
MoveM.L (SP)+,D2-D3/A2
Rts
; A3 the standard record w/selstart for the offset
; trashes A1
; leaves stack setup to l1
MungeSetup
Move.L (SP)+,A1 ; get local RTS
Move.L teTextH(A3),A0 ; get text handle
_HUnlock
SubQ.L #4,SP ; room for result
Move.L A0,-(SP) ; push handle
Move teSelstart(A3),-(SP) ; start index for insert
Clr -(SP) ; fake long for index
Clr.L -(SP) ; fake p1
Jmp (A1)
; ----------------------------------------------------------------------
; PROCEDURE InsRsrved;
; ** <C851/14Apr87/MBK> **
; I changed teReserved to a handle to the following structure:
; Record
; newReserved : LONGINT;
; nullScrap : stScrpHandle;
; End;
; nullScrap is used to store a style which is set when the
; selection is NIL in iTESetStyle. I store it in the scrap
; format so that it can easily be inserted using PstStylGuts.
; This procedure is called to insert the reserved style if there
; is one, and otherwise just to extend the current style.
; ----------------------------------------------------------------------
InsRsrved
Tst.W D5 ; anything being inserted?
Beq.S @1 ; quit if not
Move.L teStylesH(A3),A0 ; get style handle
Move.L (A0),A0 ; deref
Move.L nullStyle(A0),A0 ; get reserved handle
Move.L (A0),A0 ; deref
Move.L nullScrap(A0),A1 ; get handle to scrap for null selection
Move.L (A1),A0 ; deref
Tst.W scrpNStyles(A0) ; is there a style?
Beq.S @0 ; do extend if not
MoveM.L D3/A4,-(SP)
Move.L A1,A4 ; put scrap handle in A4
MoveQ #0,D3 ; clear whole register
Move.W teSelStart(A3),D3 ; PstStylGuts wants this
Bsr PstStylGuts ; go paste it
MoveM.L (SP)+,D3/A4
Bsr ClearRsrved ; selection is different now
Bra.S @1
@0 Move.W teSelStart(A3),D0 ; get selStart
SubQ #1,D0 ; pre-decrement
Bsr GetCurStyle ; get current style
Bsr RecalStStarts ; adjust start points
@1 Rts
; ----------------------------------------------------------------------
; PROCEDURE InsGuts
; ** Modified 6/18/86 by MBK **
; Takes the text pointed to by D6 of length D5 and inserts it
; at selStart. It then adjusts teLength by the inserted length.
; It also adjusts D7, the delta accumulator for RecalLines.
; Entry:
; D5 length of text
; D6 pointer to text
; D7 pending delta amount for recalLines
; Exit:
; D7 Adjusted by insert amount
; ----------------------------------------------------------------------
InsGuts
Bsr.S MungeSetup ; setup for the insert <C971/RWW102887>NO
Clr.L -(SP) ; fake l1
Move.L D6,-(SP) ; pointer to insert = p2
Move.L D5,-(SP) ; length to insert = l2
_Munger ; use sloppy munger
AddQ.L #4,SP ; pop result
Move.L teTextH(A3),A0 ; get text handle
_Hlock ; and relock it
Add D5,teLength(A3) ; adjust length by insert amount
Sub D5,D7 ; adjust delta amount for ReCalLines
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; no, you're done ** MBK 6/18/86 **
Bsr.S InsRsrved ; insert the style <C971/RWW102887>NO
@0
Rts
; ----------------------------------------------------------------------
; PROCEDURE TEInsert( pText: PTR; l: LONGINT; h: TEHandle );
; This inserts the passed text/length just before the selection
; but doesn't touch the scrap. The selection too is "untouched"
; because it is offset by the inserted amount to point to the same
; range. Just after a TENew this can be used as a replacement for
; the old TESetText because the slection and length are all zero.
; ----------------------------------------------------------------------
TEInsert
Bsr StdEntry
Bsr HideCaret ; <C971/RWW102887>NO
Bsr HiLite ; remove selection <C971/RWW102887>NO
MoveQ #0,D7 ; delta = 0(No deletion)
MoveM.L (A2)+,D5-D6 ; A2 points to l param
Bsr.S insGuts ; go insert the scrap
Bsr RecalDraw ; redo the line stuff
Add D5,teSelStart(A3) ; selStart:=selstart + insert amount
Add D5,teSelEnd(A3) ; selEnd:=selEnd + insert amount
Bsr ShowCaret
Bsr HiLite ; restore selection <C971/RWW102887>NO
epilog12 MoveQ #12,D0
Bra StdExit
; ----------------------------------------------------------------------
; PROCEDURE TEKey( key: CHAR; h: TEHandle );
; ** Modified 6/18/86 by MBK **
; ----------------------------------------------------------------------
TEKey
Bsr StdEntry ; <C971/RWW102887>NO
ST teLftCaret(A3) ; jam caret to left
_ObscureCursor ; nice knowing you cursor
Move.W (A2),D1 ; store char away
Cmp.B #$08,D1 ; is it a backspace?
Beq.S backSpace
; Cursor Key support - Added from 'Lonely Hearts' patch 14Jan86
; left: If selStart isn't 0 it decrements it and places the caret there
; right: Increments selEnd and places caret there
; up: simulates a click one line above current selStart point
; down: simulates a click one line below current selStart point
MoveQ #1,D2 ; assume going down
MoveQ #$1F,D0 ; range $1C-$1F
Sub.B D1,D0 ; get key code
Blt.S @0
Beq.S downArrow ; is it a cursor key?
SubQ.B #1,D0
Beq.S upArrow
SubQ.B #1,D0
Beq.S rightArrow
SubQ.B #1,D0
Beq.S leftArrow
@0
Bra.S PasteChar ; => go paste in the character
upArrow
MoveQ #-1,D2 ; going up
downArrow
Move D2,-(SP) ; save D2
Move teSelStart(A3),D3 ; pass selStart=selEnd
Move D3,D4
MoveQ #-2,D7 ; position pen to caret
Bsr DoText ; the port ret. in A0
Move (SP)+,D2 ; restore D2
Bsr FindLineHite ; get current line hite ** MBK 6/18/86 **
MulS D1,D2 ; get delta -- a SIGNED 16-bit value<09Dec85 JTC>
Move.L teSelRect(A3),teSelPoint(A3) ; pass caret point
Add D2,teSelPoint(A3) ; adjust v value
Bsr DoFind ; the port ret. in A0
ST teLftCaret(A3) ; force clean clicks
Bra.S leftRight ; setselect'll force autoscroll
rightArrow
Move teSelEnd(A3),D6 ; get start
AddQ #1,D6 ; going down
Bra.S leftRight
leftArrow
Move teSelStart(A3),D6 ; get start
Beq.S leftRight
SubQ #1,D6 ; going to left
leftRight
Ext.L D6 ; D6 comes back char loc
Move.L D6,-(SP) ; pass start
Move.L D6,-(SP)
Move.L A4,-(SP)
_TESetSelect
Bsr DrawCaret ; force caret ON
Bra.S Epilog6
PasteChar
; Go paste the character
Move.L A2,D6 ; point to the character
AddQ #1,D6 ; character in lower half
MoveQ #1,D5 ; one long
MoveQ #0,D7 ; want to call ExtendStyle
Bsr PasteGuts
Bra.S epilog6
backSpace
Move teSelStart(A3),D0 ; see if null selection
Cmp teSelEnd(A3),D0
Bne.S cutit
; since there's no selection eat characters to the left.
Tst D0 ; see if at extreme left
Beq.S epilog6 ; skip if so
Bsr HideCaret ; remove the caret
SubQ #1,teSelStart(A3) ; adjust selection
cutit
Move.L A4,-(SP) ; pass the handle
_TEDelete ; and cut it (A3 no good after)
epilog6 MoveQ #6,D0
Bra StdExit
; ----------------------------------------------------------------------
; PROCEDURE ExtendStyle
; ** Added 6/6/86 by MBK **
; Handles deletion or extension of styles.
; Entry:
; D5 length of text being inserted (preserved)
; ----------------------------------------------------------------------
ExtendStyle
Move.W D5,-(SP) ; save length
Tst.W teSize(A3) ; check style flag
Bpl.S @1 ; quit if not
; get selStart, selEnd and see if it's an insertion pt
Bsr SelSort ; sorts selStart, selEnd
Move.W D0,D1 ; selEnd
Swap D0 ; selStart in low byte now
Cmp.W D0,D1 ; is it an insertion pt?
Beq.S @0 ; no styles to delete if so
; If insertion is replacing a selection, you want to use the style of the
; first character of the selection (whereas if it's an insertion pt, you
; use the previous character's style).
SubQ #1,D5 ; dec insertion length
AddQ #1,D0 ; pt to next char
Bsr DeleteStyle ; else, delete excess styles
@0 Tst.W D5 ; anything to insert?
Beq.S @1 ; you're done if not
SubQ #1,D0 ; pre-decrement
Bsr GetCurStyle ; else get current style
Bsr RecalStStarts ; update style starts
@1 Move.W (SP)+,D5 ; restore length
Rts
; ----------------------------------------------------------------------
; PROCEDURE FindLineHite
; ** Added 6/16/86 by MBK **
; Finds the given line and returns its line height.
; Entry:
; D3 selStart
; Exit:
; D1 height of this line
; ----------------------------------------------------------------------
FindLineHite
Move.L A2,-(SP) ; save A2
Lea teLines(A3),A2 ; pt to start of linestarts
Move.W D3,D0 ; offset
Bsr GetLine ; get line that it's on
Bsr PtrToLine ; get line # from A2
; Get maximum height on this line from the array
Bsr GetHite ; get height of this line
Move.L (SP)+,A2 ; restore A2
Rts
; ----------------------------------------------------------------------
; PROCEDURE TESetJust( just: INTEGER; h: TEHandle );
; Sets the justify mode. DOESN'T redraw. Lovely code...
; ----------------------------------------------------------------------
TESetJust
Bsr StdEntry
Move (A2),teJust(A3) ; set the style
Bra.S epilog6 ; <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE Refresh
; Redraws the lines intersected verticals top in D0, bottom in D1
; ----------------------------------------------------------------------
Refresh
MoveQ #0,D3 ; min/max redraw pins in DoDraw
MoveQ #-1,D4
Bsr PinA0Rect ; pass A0 rect to Pin code
MoveQ #teDraw,D7 ; drawit
Bsr DoText
Bsr HiLite ; reshow selection
Tst.B teCarOn(A3) ; force a redraw if caret is on
Beq.S handyReturn ; if off skip it
Bra ForceCaret ; implied return
; ----------------------------------------------------------------------
; PROCEDURE TEScroll( dh, dv: INTEGER; h: TEHandle )
; Scrolls the dest rect "under" the view rect to give the caller
; scrolling ability. A call of ( 0, -lineheight, h) would scroll up
; one line, because dest rect is offset by the passed (dh,dv). The
; resultant update region is redrawn
; ----------------------------------------------------------------------
TEScroll
Bsr StdEntry
Bsr HideCaret
Move.L (A2)+,D3 ; get dv,dh pair
Bsr.S Scroll
epilog8
MoveQ #8,D0
Bra StdExit
; Amount to scroll in D3
Scroll
Tst.L D3 ; escape if nothing there
Beq.S ActCaret ; fix errant HideCaret (and Rts…) <C971/RWW110587>
Pea teDestRect(A3) ; pass the dest rectangle
Move.L D3,-(SP) ; pass dh, dv
_OffsetRect
SubQ #4,SP ; make room for temp region
_NewRgn ; get it
Move.L (SP)+,A2 ; save its handle
Pea teViewRect(A3) ; pass rect to scroll
Move.L D3,-(SP) ; pass dh, dv
Move.L A2,-(SP) ; pass the temp region
_ScrollRect
Bsr.S ActCaret ; just activate, don't draw <C971/RWW102887>NO
Move.L A2,-(SP) ; clip to it update rgn
_SetClip
Move.L (A2),A0 ; point to region
Lea rgnBBox(A0),A0
Bsr.S Refresh ; and redraw those lines
Move.L A2,-(SP) ; get rid of temp region
_DisposRgn
@0
handyReturn
Rts
; ** <C207/14oct86/MBK> ** Don't draw caret yet, just activate it
ActCaret Tst.B teActive(A3) ; do nothing if not active
Beq.S @0 ; <C971/RWW102887>NO
Move teSelStart(A3),D0 ; see if should be turned on
Cmp teSelEnd(A3),D0
Bne.S @0 ; if selection <> 0 then escape
ST teCarAct(A3) ; replaced ShowCaret
@0 Rts
; ----------------------------------------------------------------------
; PROCEDURE TEPinScroll( dh, dv: INTEGER; h: TEHandle )
; ** Modified 6/18/86 by MBK **
; Scrolls the dest rect "under" the view rect to give the caller
; scrolling ability. A call of ( 0, -lineheight, h) would scroll up
; one line, because dest rect is offset by the passed (dh,dv). The
; resultant update region is redrawn. This version pins the scroll
; amount to the destRect/nLines
; ----------------------------------------------------------------------
TEPinScroll
Bsr StdEntry
Bsr HideCaret
Move (A2),D0 ; get dV
Bpl.S @1 ; pin top
Move.W teNLines(A3),D1 ; last line ** MBK 6/18/86 **
Move.W teLength(A3),D0 ; last char **<C207/14oct86/MBK> **
Tst.W D0 ; anything in file? **<C207/14oct86/MBK> **
Beq.S @0 ; skip test if not **<C207/14oct86/MBK> **
Move.L teTextH(A3),A0 ; text handle **<C207/14oct86/MBK> **
Move.L (A0),A0 ; dereference **<C207/14oct86/MBK> **
Cmp.B #$0D,-1(A0,D0) ; file end with CR? **<C207/14oct86/MBK> **
Bne.S @0 ; end of file if not **<C207/14oct86/MBK> **
AddQ #1,D1 ; else 1 more line **<C207/14oct86/MBK> **
@0 MoveQ #0,D0 ; 1st line ** MBK 6/18/86 **
Bsr GetLineHites ; compile max hites ** MBK 6/18/86 **
Move.W D0,D1 ; hite from 1st to last ** MBK 6/18/86 **
Move.W (A2),D0 ; restore D0 ** MBK 6/18/86 **
Add teDestRect+top(A3),D1 ; get destRect.top
Sub teViewRect+bottom(A3),D1 ; a diff. viewRect.bottom
Ble.S @2 ; dest already gone...
Add D1,D0 ; see what delta does
Bpl.S pinH
Bra.S @2 ; should be subtracted because it's negative
@1
Move teDestRect+top(A3),D1 ; add destRect.top
Sub teViewRect+top(A3),D1 ; diff. viewRect.top
Bpl.S @2 ; already bad
Add D1,D0
Bmi.S pinH
@2
Sub D0,(A2) ; adjust scroll
pinH
Move 2(A2),D0 ; get dH
Bpl.S @1 ; pin top
Move teDestRect+right(A3),D1 ; add destrect.right
Sub teViewRect+right(A3),D1 ; a diff. viewRect.right
Ble.S @2 ; already past, cancel scroll
Add D1,D0
Bpl.S pinDone
Add D0,2(A2) ; adjust scroll
Bra.S pinDone
@1
Move teDestRect+left(A3),D1 ; add destRect.left
Sub teViewRect+left(A3),D1 ; diff. viewRect.left
Bpl.S @2 ; already past, cancel scroll
Add D1,D0
Bmi.S pinDone
@2
Sub D0,2(A2) ; adjust scroll
pinDone
Move.L (A2)+,D3 ; get dv,dh pair
Bsr Scroll ; and go scroll it
Bsr ActCaret ; just activate, don't draw ** <C207/14oct86/MBK> **
Bra epilog8
; ----------------------------------------------------------------------
; PROCEDURE TESelView( hTe: TEHandle );
; ** Modified 6/18/86 by MBK **
; Insures the selection is in view rect. SelView is a local
; copy of it
; ----------------------------------------------------------------------
TESelView
Bsr StdEntry ; doo dah...
Bsr.S SelView ; go do it
Bra epilog4
; local cover (A4/A3 pointing to usual record)
SelView
; <PMAB381/RWW020488>
; Changed from teFlags to new whizzy position in TEDispatchRec
; BTst #tefAutoPos,teFlags(A3) ; scrolling allowed?
Move.L teDispatchH(A3),A0
Move.L (A0),A0
Move.L newTEFlags(A0),D0
BTst #0,D0
Beq.S @0 ; if not, must skip
Bsr SelSort ; sort selection
Move teSelStart(A3),D3 ; dispStart:=selStart
Move D3,D4 ; dispEnd:=same
MoveQ #teLoc,D7 ; does nothing except moves pen
Bsr DoText ; position for the caret
Move.L teSelRect+topLeft(A3),D7 ; save penloc in D7
Lea tempRect+8,A2 ; place for working rect
Lea teViewRect+8(A3),A0 ; source
Move.L -(A0),-(A2)
Move.L -(A0),-(A2)
Move teSelStart(A3),D3 ; dispStart:=selStart ** <C95/4aug86/MBK> **
Bsr FindLineHite ; get height of line ** <C95/4aug86/MBK> **
Sub D1,bottom(A2)
SubQ #1,right(A2) ; room for caret
SubQ #2,SP
Move.L D7,-(SP) ; pass selStart location
Move.L A2,-(SP) ; pass adjust viewRect
_PtInRect
Tst.B (SP)+
Bne.S @0 ; if visible, then OK
Move.L (A2)+,-(SP) ; get adjusted viewRect.topLeft
Move.L (A2),-(SP) ; get adjusted viewRect.botRight
Move.L -(A2),-(SP) ; subtract adjusted topLeft
Pea 4(SP)
_SubPt
Pea 4(SP) ; add top to delta
_AddPt
Move.L D7,-(SP) ; subtract penloc
Pea 4(SP) ; to "center" pen if possible
_SubPt
Move.L A4,-(SP)
_TEPinScroll ; s/b a trap ** <C381/6nov86/MBK> **
@0
Rts ; adios
; ----------------------------------------------------------------------
; PROCEDURE TEAutoView( auto: BOOLEAN; hTe: TEHandle );
; Sets the autoview bit according to the boolean
; ----------------------------------------------------------------------
TEAutoView
Bsr StdEntry ; doo dah...
Move.L teDispatchH(A3),A0 ; <PMAB381/RWW020488>
Move.L (A0),A0 ; <PMAB381/RWW020488>
Move.L newTEFlags(A0),D0 ; <PMAB381/RWW020488>
Tst.B (A2)+ ; was it true
Beq.S @0
; BSet #tefAutoPos,teFlags(A3) ; allow scrolling
BSet #0,D0 ; <PMAB381/RWW020488>
Bra.S @1
@0
; BClr #tefAutoPos,teFlags(A3) ; allow scrolling
BClr #0,D0
@1
Move.L D0,newTEFlags(A0)
Bra epilog6
; ----------------------------------------------------------------------
; PROCEDURE DefClikProc
; Default click proc for scrolling - does a pinned autoscroll of
; the destRect to match the viewrect.
; Entry:
; A3 pointing to the dereferenced text edit record
; A6 pointing to the standard stack frame
; thePort set, etc.
; Exits:
; CC's set <> 0
; ----------------------------------------------------------------------
DefClikProc
MoveM.L D0-D7/A0-A4,-(SP) ; save ALL regs
; BTst #tefAutoPos,teFlags(A3) ; scrolling allowed?
Move.L teDispatchH(A3),A0 ; <PMAB381/RWW020488>
Move.L (A0),A0 ; <PMAB381/RWW020488>
Move.L newTEFlags(A0),D0 ; <PMAB381/RWW020488>
BTst #0,D0 ; <PMAB381/RWW020488>
Beq.S doneAuto ; if not, must skip
Lea teViewRect+8(A3),A0 ; point to view rect
Lea tempRect+8,A2 ; copy into tempRect
Move.L -(A0),-(A2)
Move.L -(A0),-(A2)
SubQ #4,SP ; room for pt
Move.L SP,-(SP)
_GetMouse
Move (SP)+,D6 ; get V coordinate
Move (SP)+,D7 ; get H coordinate
MoveQ #0,D4 ; horz scroll amt
Move teLineHite(A3),D1 ; vert scroll amt
Bpl.S @1 ; use if not negative ** <C207/13oct86/MBK> **
Move.W D6,D0 ; find D6 line ** <C207/13oct86/MBK> **
Cmp.W teDestRect+bottom(A3),D0 ; pt below the rect? ** <C207/13oct86/MBK> **
Ble.S @0 ; okay if less or same ** <C207/13oct86/MBK> **
Move.W teDestRect+bottom(A3),D0 ; else reset to bottom ** <C207/13oct86/MBK> **
@0 Bsr PtToLine ; try to find its line # ** <C207/13oct86/MBK> **
Bge.S doneAuto ; no scroll if line doesn't exist ** <C207/13oct86/MBK> **
Bsr GetHite ; else get its height
@1 Cmp (A2)+,D6 ; subtract top of viewRect
Blt.S scrollUp ; scroll up
Cmp (A2)+,D7 ; subtract left of viewRect
Blt.S scrollLeft ; scroll left
Cmp (A2)+,D6 ; subtract bottom of viewRect
Bgt.S scrollDown ; scroll down
Cmp (A2)+,D7 ; subtract right of viewRect
Bgt.S scrollRight ; scroll right
doneAuto
MoveQ #1,D0 ; cc's <> 0
MoveM.L (SP)+,D0-D7/A0-A4 ; restore ALL regs
Rts
scrollDown
Neg D1 ; flip direction
scrollUp
Bra.S scrollEm
scrollRight
Neg D1 ; flip direction
scrollLeft
Exg D4,D1 ; switch axes
scrollEm
; Finally do the scroll
Move D4,-(SP) ; pass dh
Move D1,-(SP) ; pass dv
Move.L 8(A6),-(SP) ; tehandle
_TEPinScroll ; _TEPinScroll ** <C381/6nov86/MBK> **
Bra.S doneAuto ; <C971/RWW102887>NO
; ----------------------------------------------------------------------
; PROCEDURE GetCurStyle
; ** Added 6/5/86 by MBK **
; Gets the current style; in other words, it finds the 1st style
; descriptor preceding the current selection.
; Entry:
; D0 selection start (whose style we wish to find)
; Exit:
; D0 index into runs array of current style
; A0 ptr into runs array to current style
; ----------------------------------------------------------------------
GetCurStyle
MoveM.L D1-D4,-(SP)
; get low and high indeces, and ptr to array for binary search
AddQ #1,D0 ; don't get preceding style
Move.W D0,D2 ; save the key (sel start)
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; deref
Move.W nRuns(A0),D1 ; high index
Lea runs(A0),A0 ; pt to runs array
MoveQ #0,D0 ; low index
; start of binary search loop
@0 Cmp.W D0,D1 ; are indeces the same?
Beq.S @3 ; we're done if so
Move.W D1,D3
Add.W D0,D3 ; low + high
LsR.W #1,D3 ; divide by 2
MoveQ #0,D4 ; clear the long word ** <C381/6nov86/MBK> **
Move.W D3,D4 ; middle
LsL.L #2,D4 ; mult by stStartSize ** <C381/6nov86/MBK> **
Cmp.W 0(A0,D4),D2 ; do we have a match?
Beq.S @2 ; we're done if so
Bls.S @1 ; range is low to mid
; no change in high; low gets middle + 1
Move.W D3,D0 ; low := middle + 1
AddQ #1,D0
Bra.S @0 ; try again
; no change in low; high gets middle
@1 Move.W D3,D1 ; else high := middle
Bra.S @0 ; try again
@2 Move.W D3,D0 ; store answer in D0
; return ptr into runs array and index to the styleRec
@3 Tst.W D0
Beq.S @4 ; special case of 1st style
SubQ #1,D0 ; point to prev style
@4 MoveQ #0,D1 ; clear the long word ** <C381/6nov86/MBK> **
Move.W D0,D1
LsL.L #2,D1 ; mult by stStartSize ** <C381/6nov86/MBK> **
Add.L D1,A0 ; ptr to style start
MoveM.L (SP)+,D1-D4
Rts
; ----------------------------------------------------------------------
; PROCEDURE GetNumStyles
; ** Added 5/28/86 by MBK **
; GetNumStyles counts the number of styles in the current
; selection range in the text.
; Entry:
; D1: selEnd
; A0: ptr to current style in runs array
; Exit:
; D0: # of styles within current selection
; ----------------------------------------------------------------------
GetNumStyles
Move.L A0,-(SP) ; save ptr
Move.L teStylesH(A3),A1 ; handle to style info
Move.L (A1),A1 ; dereference
MoveQ #0,D0 ; clear whole register ** <C381/6nov86/MBK> **
Move.W nRuns(A1),D0 ; # of style starts
Lea runs(A1),A1 ; pt to style starts
LsL.L #2,D0 ; * stStartSize ** <C381/6nov86/MBK> **
Add.L D0,A1 ; pt to last style start
MoveQ #0,D0 ; init the counter
; keep checking style starts till one is >= selEnd (eventually it MUST be)
@0 Add.L #stStartSize,A0 ; point to next style record
AddQ #1,D0 ; at least 1 style
Cmp.L A0,A1 ; reached the end?
Beq.S @1 ; quit if so
Cmp.W startChar(A0),D1 ; is style within selection?
Bhi.S @0 ; made this unsigned ** <C381/6nov86/MBK> **
@1 Move.L (SP)+,A0
Rts
; ----------------------------------------------------------------------
; PROCEDURE GetStyle
; ** Added 5/29/86 by MBK **
; GetStyle returns a pointer to the style found at the given
; index into the style array.
; Entry:
; D0: style index
; A3: Ptr to TERec
; Exit:
; A0: style pointer
; ----------------------------------------------------------------------
GetStyle
MulU #stRecSize,D0 ; multiply index by size of record
Move.L teStylesH(A3),A0 ; get style handle
Move.L (A0),A0 ; dereference
Move.L styleTab(A0),A0 ; handle to styles array
Move.L (A0),A0 ; dereference
Add.L D0,A0 ; point to style descriptor
Rts
; ----------------------------------------------------------------------
; PROCEDURE RecalStStarts
; ** Added 5/23/86 by MBK **
; Recomputes the starting offsets of each style in the text
; following the current one. It adds the length of the newly
; inserted text to each offset following the insertion point.
; Entry:
; D0 index to current style in runs array
; D5 length of inserted text
; A0 pointer to the current style in runs array
; ----------------------------------------------------------------------
RecalStStarts
Move.L teStylesH(A3),A1 ; get handle to style info
Move.L (A1),A1 ; deref
Move.W nRuns(A1),D1 ; get # of style starts
Sub.W D0,D1 ; subtract current index
Bls.S @1 ; made this unsigned ** <C381/6nov86/MBK> **
; add length of inserted text to all following style starts
@0 Add.L #stStartSize,A0 ; point to next style record
Add.W D5,startChar(A0) ; add length to starting offset
SubQ #1,D1 ; dec the counter
Bne.S @0
@1
Rts
; ----------------------------------------------------------------------
; PROCEDURE SetRsrved;
; ** <C851/14Apr87/MBK> **
; I changed teReserved to a handle to the following structure:
; Record
; newReserved : LONGINT;
; nullScrap : stScrpHandle;
; End;
; nullScrap is used to store a style which is set when the
; selection is NIL in iTESetStyle. I store it in the scrap
; format so that it can easily be inserted using PstStylGuts.
; This procedure is called to set the style to whatever the user
; has input to iTESetStyle.
; On entry, SetRsrved expects A2 to be pointing to something
; that looks like this:
; flag.B TextStylePtr.L mode.W
; The flag is not accessed and can just be a hole if desired.
; ----------------------------------------------------------------------
SetRsrved
Move.W teSelStart(A3),D0 ; get selection start
Cmp.W teSelEnd(A3),D0 ; same as selEnd?
Bne lvSetRsrved ; quit if not
AltSetRsrved ; <C971/RWW102987>
Move.L teStylesH(A3),A1 ; get style handle
Move.L (A1),A1 ; deref
Move.L nullStyle(A1),A1 ; get reserved handle
Move.L (A1),A1 ; deref
Move.L nullScrap(A1),A1 ; get handle to scrap for null selection
Move.L A1,-(SP) ; save handle for later
Move.L (A1),A1 ; deref
Tst.W scrpNStyles(A1) ; stored already?
Beq.S @0 ; reset if not
Lea scrpStyleTab(A1),A1 ; point to start of tableev style if so
Bra.S @1 ; go use new settings
; First get current style settings
@0 SubQ #1,D0 ; in case sel is on a run boundary
Bsr GetCurStyle ; get current style run
Move.W styleIndex(A0),D0 ; get style index
Bsr.S GetStyle ; get the style in A0 <C971/RWW102887>NO
Move.W #1,scrpNStyles(A1) ; indicate 1 style
Lea scrpStyleTab(A1),A1 ; point to start of table
Move.L #0,scrpStartChar(A1) ; store start offset
Lea stFont(A0),A0
Move.L (A0)+,scrpFont(A1) ; font, face
Move.L (A0)+,scrpSize(A1) ; size, color
Move.L (A0)+,scrpColor+2(A1) ; color
; now adjust according to new settings
@1 Move.W 6(A2),D2 ; get the mode
Move.L 2(A2),A0 ; get style ptr
BTst #fontBit,D2 ; set font?
Beq.S @2 ; no
Move.W tsFont(A0),scrpFont(A1) ; else, set it
@2 BTst #faceBit,D2 ; set face?
Beq.S @4 ; no
; ** <C971/RWW102987> Added code to support doToggle mode.
; An insertion point is by definition continuous, so all we have to do is
; calculate unique set elements
Move.B tsFace(A0),D0 ; fetch given face <C971/RWW102987>
BTst #toglBit,D2 ; toggling? <C971/RWW102987>
Bz.S @3 ; no, go set <C971/RWW102987>
Eor.B D0,scrpFace(A1) ; <C971/RWW111187>
Bra.S @4 ; <C971/RWW102987>
@3 Tst.B D0 ; if new face is plain… <C971/RWW102987>
Bnz.S @35 ; <C971/RWW102987>
Clr.B scrpFace(A1) ; …wipe out old attributes <C971/RWW102987>
@35 Or.B D0,scrpFace(A1) ; union in new attributes <C971/RWW102987>
@4 BTst #sizeBit,D2 ; set size only?
Beq.S @5 ; no
BTst #addSizeBit,D2 ; is addSize also set?
Bne.S @5 ; it has precedence
Move.W tsSize(A0),scrpSize(A1) ; else, get size
@5 BTst #clrBit,D2 ; set color only?
Beq.S @6 ; no
Move.L tsColor(A0),scrpColor(A1) ; store the new value there
Move.W tsColor+4(A0),scrpColor+4(A1) ; store color ,hi
@6 BTst #addSizeBit,D2 ; is it addSize?
Beq.S @9
Move.W scrpSize(A1),D0 ; get current size
Bne.S @7 ; => not 0
Move.B FmDefaultSize,D0 ; get default size as byte value** <C440/19nov86/MBK> **
@7 Add.W tsSize(A0),D0 ; add increment to size
Bgt.S @8 ; size <-1 if it's 0 or negative
Move.W #1,D0 ; minimum allowable
@8 Move.W D0,scrpSize(A1) ; now store it
@9 Move.L teGrafPort(A3),A0 ; the port
Move.W scrpFont(A1),txFont(A0) ; set font
Move.W scrpFace(A1),txFace(A0) ; set face
Move.W scrpSize(A1),txSize(A0) ; set size
Bsr GetSize ; get ascent & hite
Move.L (SP)+,A0 ; get back scrap handle
Move.L (A0),A0 ; deref
Lea scrpStyleTab(A0),A0 ; pt to start of scrap table
Move.W D0,scrpAscent(A0) ; save in ascent
Move.W D1,scrpHeight(A0) ; save in line height
lvSetRsrved
Rts
; ----------------------------------------------------------------------
; PROCEDURE iTESetStyle( SetMode: INTEGER; Styl: StylPtr; redraw: BOOLEAN;
; hTE: TEHandle );
; Sets the style of the selected text (replacing all other styles).
; Supports the following modes:
; 1 doFont: Set Font only
; 2 doFace: Set Face only
; 4 doSize: Set Size only
; 8 doColor: Set Color only
; 15 doAll: Set all modes
; 16 addSize: Add Size integer to each size in selection
; 32 doToggle: Set each face attribute if not continuous, reset otherwise <C971/RWW102987>
; ----------------------------------------------------------------------
iTESetStyle
Tst.W teSize(A3) ; check style flag
Bpl.S @1 ; if not, sorry, can't set it
Bsr SetRsrved ; save the style
; ** <C381/6nov86/MBK> ** boolean value is in bit 1 of high byte
Move.W (A2)+,D0 ; get redraw value ** <C381/6nov86/MBK> **
And #$FF00,D0 ; check redraw value ** <C381/6nov86/MBK> **
Bne.S @0 ; must redraw if set
Bsr.S SetGuts ; else just add styles
Bra.S @1
@0 Move.L A2,-(SP) ; save ptr to parameters
Bsr HideCaret
Bsr HiLite ; remove selection
Move.L (SP)+,A2 ; restore ptr to parameters
Bsr.S SetGuts ; do style munging
MoveQ #0,D7 ; length is 0
Bsr RecalDraw ; redo the line stuff
Bsr ShowCaret
Bsr Hilite ; restore selection
Bsr SelView ; ensure selection is visible
@1 MoveQ #14,D0
Bra stdExit2
; ----------------------------------------------------------------------
SetGuts
MoveM.L D2-D7/A2/A4/A6,-(SP) ; save registers
Move.L (A2)+,A4 ; style ptr
Move.W (A2)+,D7 ; save mode here
Sub.L A6,A6 ; not used by SetStyle
; ** <C971/RWW102987> Added code to support doToggle.
; I changed the next statement to a mask from the original, which punted if
; it saw bits it didn't like.
And.W #doAll3,D7 ; only lower 6 bits make sense <C971/RWW102987>
Move.W D7,D0 ; <C971/RWW102987>
And.W #doFace+doToggle,D0 ; are we toggling? <C971/RWW102987>
Cmp.W #doFace+doToggle,D0 ; (both bits have to be on, dummy!) <C971/RWW102987>
Bne.S @05 ; <C971/RWW102987>
SubQ.W #1,A6 ; -1 to signal toggle mode <C971/RWW102987>
Move.W #doFace,-(SP) ; prepare fake frame for call <C971/RWW102987>
; SP => doFace/2 <C971/RWW102987>
Sub.W #styleSize+2,SP ; make room for result & TextStyle <C971/RWW102987>
; SP => VAR/2 VAR/styleSize doFace/2 <C971/RWW102987>
Pea styleSize+2(SP) ; push pointer to doFace <C971/RWW102987>
; SP => ^doFace/4 VAR/2 VAR/styleSize doFace/2 <C971/RWW102987>
Pea 4+2(SP) ; push pointer to TextStyle hole <C971/RWW102987>
; SP => ^VAR/4 ^doFace/4 VAR/2 VAR/styleSize doFace/2 <C971/RWW102987>
Move.L SP,A2 ; point A2 at stacked parameters <C971/RWW102987>
Bsr ContGuts ; coalesce continuous styles <C971/RWW102987>
Add.W #10,SP ; pop stack back to TextStyle <C971/RWW102987>
Move.B tsFace(SP),D5 ; save continuous face attributes <C971/RWW102987>
Swap D5 ; we'll need low word later <C971/RWW102987>
Add.W #styleSize+2,SP ; now remove TextStyle & doFace <C971/RWW102987>
@05 ; <C971/RWW102987>
Bsr.S StyleGuts ; do style munging
@0 MoveM.L (SP)+,D2-D7/A2/A4/A6 ; restore registers
Rts
; ----------------------------------------------------------------------
StyleGuts
Tst.W D7 ; check mode
Beq EndStyle ; 0 is invalid mode
Bsr SelSort ; sort selStart, selEnd
Move.W D0,D1 ; save selEnd <C971/RWW102987>
Move.W D0,D4
Swap D0
Move.W D0,D3 ; save selStart
Sub.W D3,D1 ; save selection length <C971/RWW102987>
Beq EndStyle ; if len = 0, nothing to do
; store the input style information temporarily
Sub.L #stRecSize,SP ; make room on stack
Move.L SP,A2 ; save ptr in A2
; Move.W D3,D0 ; selStart REDUNDANT! <PMAB381/RWW020488>
Bsr GetCurStyle ; get current style
Move.W D4,D1 ; selEnd
Bsr GetNumStyles ; get # of styles within selection
Move.W D0,D2 ; preserve # of styles
Swap D3 ; selStart in upper word
Move.W D4,D3 ; selEnd in lower word
; ** <C971/RWW102787> Faces are byte length…
Move.B tsFace(A4),D4 ; save face <C971/RWW102787>
Swap D4 ; put face in upper word
Move.W tsFont(A4),D4 ; font in lower word
Move.W tsSize(A4),D5 ; save size
Move.L tsColor(A4),D6 ; save color
Swap D7 ; running out of reg's ** <C182/6oct86/MBK> **
Move.W tsColor+4(A4),D7 ; store color in D7,hi ** <C182/6oct86/MBK> **
Swap D7 ; keep mode in D7,low ** <C182/6oct86/MBK> **
Move.L A2,A4 ; temp style handle
Move.L A0,A2 ; preserve ptr
Move.L teStylesH(A3),A0 ; handle to style info ** <C381/6nov86/MBK> **
_HLock ; keep it locked ** <C381/6nov86/MBK> **
; By this point, the world looks like this:
; D2.W = number of styles in current selection (used as counter)
; D3.L = selStart/selEnd (high word/low word)
; D4.L = Face/Font
; D5.L = Toggle face info/Size
; D6.L = Color Red/Green
; D7.L = Color Blue/set mode
; A2.L => StyleRun array, first associated element
; A4.L => working STElement on stack
styleLoop Move.W styleIndex(A2),D0 ; else, index to style
Bsr GetStyle ; find it
Bsr CheckMatch ; must match for replacement
Tst.W D0 ; check return flag
Beq noMatch ; if false, don't replace
Move.L #stRecSize,D0 ; length of a styleRec
Move.L A4,A1 ; ptr to temp storage
_BlockMove ; copy to temp location for mod
Move.L A2,A0 ; current style
Move.L D3,D0 ; selStart, selEnd
Swap D0 ; selStart in low word
Cmp.W startChar(A2),D0 ; compare to style start
Bls.S @0 ; made this unsigned ** <C381/6nov86/MBK> **
Bsr DupStyle ; else dup it
AddQ #stStartSize,A0 ; new style replaces this
Move.L A0,A2
@0 Cmp.W #1,D2 ; last style?
Bne.S @1 ; not yet
AddQ #stStartSize,A0
Cmp.W startChar(A0),D3 ; compare to style end
Beq.S @1 ; ok if same as selEnd
Move.W D3,D0 ; selEnd
Move.L A2,A0 ; current style
Bsr DupStyle ; dup it
Move.L A0,A2 ; ptr updated in A0
; ** <C381/7nov86/MBK> ** dupstyle was fixed to inc the style count, so it's
; ok to dec it in all cases now
@1 MoveQ #1,D0 ; # of styles to (possibly) delete
Move.L A2,A0 ; ptr to style start
Bsr DecStylCount ; style used 1 less time
BTst #fontBit,D7 ; set font?
Beq.S @3 ; no
Move.W D4,stFont(A4) ; else, put in temp rec
@3 BTst #faceBit,D7 ; set face?
Beq.S @5 ; no
; ** <C971/RWW102987> This new code supports the doToggle mode
Move.L D4,D0 ; fetch face information <C971/RWW102987>
Swap D0 ; move face to low byte <C971/RWW102987>
Move.L A6,D1 ; are we just setting? <C971/RWW102987>
Bz.S @41 ; <C971/RWW102987>
AddQ.L #1,D1 ; are we toggling? (was it just -1?)<C971/RWW102987>
Beq.S @42 ; yes, go handle <C971/RWW102987>
; Replacing… <C971/RWW102987>
Move.B D0,stFace(A4) ; we must be replacing, then <C971/RWW102987>
Bra.S @5 ; <C971/RWW102987>
; Toggling… (algorithm also works for plain, so we don't have to special case) <C971/RWW102987>
@42 Move.L D5,D1 ; fetch toggle info <C971/RWW102987>
Swap D1 ; move continuous face to low byte <C971/RWW102987>
And.B D0,D1 ; intersect faces for XOR mask <C971/RWW102987>
Eor.B D1,D0 ; difference from desired is OR mask<C971/RWW102987>
Or.B D0,stFace(A4) ; union in new style attributes <C971/RWW102987>
Eor.B D1,stFace(A4) ; remove already set attributes <C971/RWW102987>
Bra.S @5 ; <C971/RWW102987>
; Merging… <C971/RWW102987>
@41 Tst.B D0 ; is it plain? <C971/RWW102987>
Bnz.S @43 ; no, merge in attributes <C971/RWW102987>
Clr.B stFace(A4) ; remove all styles if plain <C971/RWW102987>
@43 Or.B D0,stFace(A4) ; union sets <C971/RWW102987>
@5 BTst #sizeBit,D7 ; set size only?
Beq.S @6 ; no
BTst #addSizeBit,D7 ; is addSize also set? ** <C139/10Sep86/MBK> **
Bne.S @6 ; it has precedence ** <C139/10Sep86/MBK> **
Move.W D5,stSize(A4) ; else, get size
@6 BTst #clrBit,D7 ; set color only?
Beq.S @7 ; no
Move.L D6,stColor(A4) ; store the new value there
Swap D7 ; running out of reg's ** <C182/6oct86/MBK> **
Move.W D7,stColor+4(A4) ; store color in D7,hi ** <C182/6oct86/MBK> **
Swap D7 ; keep mode in D7,low ** <C182/6oct86/MBK> **
@7 BTst #addSizeBit,D7 ; is it addSize? ** <C139/10Sep86/MBK> **
Beq.S @9
Move.W stSize(A4),D0 ; get current size
Bne.S @8 ; => not 0
; I assumed FmDefaultSize was a word constant, but actually it points to a byte value.
Move.B FmDefaultSize,D0 ; get default size as byte value** <C440/19nov86/MBK> **
Move.W D0,stSize(A4) ; store as word value ** <C440/19nov86/MBK> **
@8
; Don't allow the size to become 0 or be negative.
Add.W D5,D0 ; add increment to size
Bgt.S @81 ; size <-1 if it's 0 or negative
Move.W #1,D0 ; minimum allowable
@81 Move.W D0,stSize(A4) ; now store it
@9 Move.L A4,A0 ; point to relevent stuff
Bsr FindStyle ; look for this style
Tst.L D0 ; do we have it already?
Bne.S @10 ; guess so
Move.L A4,A0 ; get ptr to new style
Bsr.S SetHiteAscent ; set line height and font ascent<C971/RWW102887>NO
Move.W #1,stCount(A0) ; will be used once to start
Bsr AddStyle ; and add it
@10 Move.W D0,styleIndex(A2) ; store new style index
NoMatch AddQ #stStartSize,A2 ; point to next style
SubQ.W #1,D2 ; dec style counter
Bne styleLoop ; keep looping if not 0
Move.L teStylesH(A3),A0 ; handle to style info
_HUnlock
Bsr ConcatStyles ; watch out for adjoining styles
Add.L #stRecSize,SP ; restore stack
EndStyle Rts
; ----------------------------------------------------------------------
; PROCEDURE SetHiteAscent
; Added 5/30/86 by MBK
; SetHiteAscent sets the line height and the font ascent based
; On the given style.
; Entry:
; A0: ptr to style (preserved)
; A3: TEHandle
; ----------------------------------------------------------------------
SetHiteAscent
Move.L D2,-(SP) ; save registers
; set my style just to get the info I need
Move.L teGrafPort(A3),A1 ; the port
Move.W stFont(A0),txFont(A1) ; set font
Move.W stFace(A0),txFace(A1) ; set face
Move.W stSize(A0),txSize(A1) ; set size
; get the line height and font ascent
Bsr GetSize ; get ascent & hite ** <C207/10oct86/MBK> **
Move.W D0,stAscent(A0) ; save in ascent ** <C207/10oct86/MBK> **
Move.W D1,stHeight(A0) ; save in line height ** <C207/10oct86/MBK> **
Move.L (SP)+,D2 ; restore registers
Rts
; ----------------------------------------------------------------------
; AnyNullStyle
; <C971/RWW102387>
; Returns TRUE if a null style exists
; ENTRY:
; A3.L = TEPtr
; EXIT:
; A0.L => null scrap record (hTE^^.nullStyle^^.nullScrap^)
; USES:
; A0.L
; ----------------------------------------------------------------------
AnyNullStyle
Move.L teStylesH(A3),A0 ; => style record
Move.L (A0),A0
Move.L nullStyle(A0),A0 ; => null style record
Move.L (A0),A0
Move.L nullScrap(A0),A0 ; => null scrap record
Move.L (A0),A0
Tst.W scrpNStyles(A0) ; Assure null style exists
Rts
; ----------------------------------------------------------------------
; GetTrueStyle
; <C971/RWW102387>
; Returns the style at the specified offset, whether from null style or
; inferred from current style. Made subroutine because I needed
; similar result for iGetStylScrap.
; ENTRY:
; D0.W = offset into text record
; A3.L = TEPtr
; EXIT:
; A0.L => STElement representing style
; USES:
; D0.W, A0.L
; ----------------------------------------------------------------------
GetTrueStyle
Cmp.W teSelStart(A3),D0 ; start = offset, and…
Bne.S GetOneStyle
Cmp.W teSelEnd(A3),D0 ; end = start?
Bne.S GetOneStyle
Bsr.S AnyNullStyle
Bz.S GetOneStyle ; None exists. Punt.
; Yeah, this looks strange. ScrpSTElements and STElements are _almost_
; the same, except that the first field of ScrpSTElement is a long instead
; of a word. Fake it as though A0 => STElement
Lea scrpStyleTab+2(A0),A0
Rts
; ----------------------------------------------------------------------
; GetOneStyle
; <C971/RWW102387>
; Returns the style at the specified offset
; ----------------------------------------------------------------------
GetOneStyle
Bsr GetCurStyle ; get current style
Move.W styleIndex(A0),D0 ; get style index
Bsr GetStyle ; now you have it
Rts
; ----------------------------------------------------------------------
; PROCEDURE iTEGetStyle( offset: INTEGER; VAR Styl: StylePtr;
; VAR lineHite:INTEGER; VAR fontAscent:INTEGER;
; hTE: TEHandle );
; Returns the style _OF_THE_CHARACTER_ at the specified offset
; ----------------------------------------------------------------------
iTEGetStyle
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; if not, sorry, can't get it
Move.L (A2)+,-(SP) ; save ptr to font ascent
Move.L (A2)+,-(SP) ; save ptr to line height
Move.L (A2)+,-(SP) ; save style ptr
Move.W (A2),D0 ; offset
Bsr.S GetOneStyle ; fetch inferred style <C971/RWW102687>
Move.L (SP)+,A1 ; point to styleRec
Move.W stFont(A0),(A1)+ ; copy font
Move.W stFace(A0),(A1)+ ; copy face
Move.W stSize(A0),(A1)+ ; copy size
Move.L A0,A2 ; save ptr ** <C182/6oct86/MBK> **
Lea stColor(A0),A0 ; pt to color ** <C182/6oct86/MBK> **
Move.W (A0)+,(A1)+ ; copy red ** <C182/6oct86/MBK> **
Move.W (A0)+,(A1)+ ; copy green ** <C182/6oct86/MBK> **
Move.W (A0),(A1) ; copy blue ** <C182/6oct86/MBK> **
Move.L (SP)+,A1 ; ptr to line height
Move.W stHeight(A2),(A1) ; store line height
Move.L (SP)+,A1 ; ptr to font ascent
Move.W stAscent(A2),(A1) ; store font ascent
Bra.S @1
; ** <C139/10Sep86/MBK> ** Added this code to return GrafPort info for records without style.
@0 Bsr GetSize ; get ascent & hite ** <C207/10oct86/MBK> **
Move.L (A2)+,A0 ; ptr to ascent ** <C207/10oct86/MBK> **
Move D0,(A0) ; save in ascent ** <C207/10oct86/MBK> **
Move.L (A2)+,A0 ; ptr to line height ** <C207/10oct86/MBK> **
Move D1,(A0) ; save in line height ** <C207/10oct86/MBK> **
Move.L (A2),A0 ; ptr to style record
Move.L teGrafPort(A3),A1
Move.W txFont(A1),(A0)+ ; copy font
Move.W txFace(A1),(A0)+
Move.W txSize(A1),(A0)+ ; copy size
Pea 0(A0) ; ptr to forecolor
;; If forRAM THEN
If (Not forROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; color QD around? <C971/RWW112487>
Bnz.S @05 ; nope <C971/RWW112487>
_GetForeColor ; <C971/RWW112487>
Bra.S @07 ; <C971/RWW112487>
@05 Bsr GetForeColor ; <C971/RWW112487>
@07
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
_GetForeColor ; for Ikki
Else
Bsr GetForeColor ; for Alladin
EndIf
@1 MoveQ #20,D0
Bra StdExit2
; ------------------------------------------------
; SetStyle - sets the style pointed to by A0
; Entry: A0 Pointer to styleStart (Preserved)
; ------------------------------------------------
SetStyle
Move.L A0,-(SP)
Move.W styleIndex(A0),D0 ; get index to styleRec
Bsr GetStyle ; get the styleRec
Move.L teGrafPort(A3),A1 ; get the Port
Move.W stFont(A0),txFont(A1) ; set font
Move.W stFace(A0),txFace(A1) ; set face
Move.W stSize(A0),txSize(A1) ; set size
;; If forRAM THEN
If (Not forROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; Becks or better? <C971/RWW112487>
Bnz.S @1 ; nope <C971/RWW112487>
EndIf
;; If onNuMac|onMvMac|forRAM THEN ; <C914/29Oct87> rwh
If hasCQD|(Not forROM) THEN ; <19Feb89smb>
; Save D2 because the RGBForeColor trap destroys it.
; Save the style ptr as an offset, since _RGBForeColor may shift memory.
Move.L teStylesH(A3),A1 ; style handle ** <C717/28jan87/MBK> **
Move.L (A1),D0 ; dereference ** <C717/28jan87/MBK> **
Sub.L D0,(SP) ; save as offset ** <C717/28jan87/MBK> **
Move.W D2,-(SP) ; save D2 for everybody ** <C574/30dec86/MBK> **
EndIf
@1
Pea stColor(A0) ; point to fgColor ** <C182/6oct86/MBK> **
;; If forRAM THEN
If (Not forROM) THEN ; <19Feb89smb>
BTst #14,ROM85 ; Becks or better? <C971/RWW112487>
Bnz.S @2 ; nope <C971/RWW112487>
_RGBForeColor ; <C971/RWW112487>
Move.W (SP)+,D2 ; <C971/RWW112487>
Move.L teStylesH(A3),A1 ; <C971/RWW112487>
Move.L (A1),D0 ; <C971/RWW112487>
Add.L D0,(SP) ; <C971/RWW112487>
Bra.S @3 ; <C971/RWW112487>
@2 Bsr RGBForeColor ; <C971/RWW112487>
@3
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; <19Feb89smb>
_RGBForeColor ; for Ikki ** <C182/06oct86/MBK> **
Move.W (SP)+,D2 ; restore D2 ** <C574/30dec86/MBK> **
Move.L teStylesH(A3),A1 ; style handle ** <C717/28jan87/MBK> **
Move.L (A1),D0 ; dereference ** <C717/28jan87/MBK> **
Add.L D0,(SP) ; restore as ptr ** <C717/28jan87/MBK> **
Else
Bsr RGBForeColor ; for Alladin ** <C182/6oct86/MBK> **
EndIf
Move.L (SP)+,A0
Rts
; ----------------------------------------------------------------------
; PROCEDURE ConcatStyles
; Added 6/12/86 by MBK
; ConcatStyles checks the entire runs array for adjoining
; identical styles, and concatenates any it finds.
; ----------------------------------------------------------------------
ConcatStyles
MoveM.L D2/A2,-(SP) ; save registers ** <C381/7nov86/MBK> **
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A0 ; dereference
Move.L styleTab(A0),A2 ; handle to distinct styles ** <C381/7nov86/MBK> **
Move.L (A2),A2 ; dereference ** <C381/7nov86/MBK> **
Move.W nRuns(A0),D0 ; get # of style starts
AddQ #1,D0 ; + dummy end index
Lea runs(A0),A0 ; ptr to stStarts array
Move.L A0,A1 ; copy it
MoveQ #0,D2 ; repetition counter ** <C381/7nov86/MBK> **
Move.W styleIndex(A0),D1 ; current index ** <C381/7nov86/MBK> **
; loop thru styles removing repetitious ones
@0 SubQ.W #1,D0 ; dec the count
Beq.S @2 ; done, get out
AddQ #1,D2 ; inc repetition counter ** <C381/7nov86/MBK> **
AddQ.L #stStartSize,A1 ; point to next style
Cmp.W styleIndex(A1),D1 ; are they the same?
Beq.S @0 ; don't change ptrs if so
SubQ #1,D2 ; dec repetition counter ** <C381/7nov86/MBK> **
Beq.S @1 ; no repetitions ** <C381/7nov86/MBK> **
; ** <C381/7nov86/MBK> ** if any runs are merged, the stCount for that style must also be adjusted
MulU #stRecSize,D1 ; * size of record ** <C381/7nov86/MBK> **
Sub.W D2,stCount(A2,D1.L) ; dec count ** <C381/7nov86/MBK> **
MoveQ #0,D2 ; repetition counter ** <C381/7nov86/MBK> **
@1 AddQ.L #stStartSize,A0 ; now pt to next
Move.L startChar(A1),startChar(A0) ; move start and index
Move.W styleIndex(A0),D1 ; current index ** <C381/7nov86/MBK> **
Bra.S @0
; shrink the handle to the style info
@2 Sub.L A0,A1 ; get amount that's redundant
Move.L A1,D0
Move.L teStylesH(A3),A0 ; handle to style info
Move.L (A0),A1 ; dereference
AsR.L #2,D0 ; divide diff by 4
Sub.W D0,nRuns(A1) ; store new # of style starts
MoveM.L (SP)+,D2/A2 ; restore registers ** <C381/7nov86/MBK> **
Rts ; bye
; ----------------------------------------------------------------------
; PROCEDURE CheckMatch
; ** Added 7/19/86 by MBK **
; CheckMatch checks to see if the input style record matches
; the style being sought by iTEReplaceStyle. If so, a True flag
; is returned. If the call was from iTESetStyle, True is auto-
; matically returned since the record does not have to match
; anything.
; Entry:
; A0: ptr to style record
; A6: ptr to style being searched for (0 if from iTESetStyle)
; D7: replace mode
; Exit:
; D0: flag = 1 if this style may be replaced
; ----------------------------------------------------------------------
CheckMatch
MoveQ #1,D0 ; assume okay
Cmp.L #0,A6 ; call from iTESetStyle?
Beq.S @5 ; quit with true if so
; ** <C971/RWW102987> Added code to support doToggle mode
; Specifically, A6 = -1 is used as a flag in iTESetStyle
Cmp.L #-1,A6 ; ignore toggle mode, too <C971/RWW102987>
Beq.S @5 ; <C971/RWW102987>
BTst #fontBit,D7 ; find font?
Beq.S @1
Move.W tsFont(A6),D1
Cmp.W stFont(A0),D1 ; same as this style?
Bne.S @4 ; stop comparing if not
@1 BTst #faceBit,D7 ; find face?
Beq.S @2
; ** <C971/RWW102787> Faces are byte length…
Move.B tsFace(A6),D1 ; <C971/RWW102787>
Cmp.B stFace(A0),D1 ; same as this style? <C971/RWW102787>
Bne.S @4 ; stop comparing if not
@2 BTst #sizeBit,D7 ; find size?
Beq.S @3
Move.W tsSize(A6),D1
Cmp.W stSize(A0),D1 ; same as this style?
Bne.S @4 ; stop comparing if not
@3 BTst #clrBit,D7 ; find color?
Beq.S @5 ; must have a match if still here
Move.L tsColor(A6),D1
Cmp.L stColor(A0),D1 ; same as this style?
Bne.S @4 ; red and green not same ** <C182/6oct86/MBK> **
Move.W tsColor+4(A6),D1 ; get blue ** <C182/6oct86/MBK> **
Cmp.W stColor+4(A0),D1 ; blues the same? ** <C182/6oct86/MBK> **
Beq.S @5
@4 MoveQ #0,D0 ; not a match
@5 Rts
; ----------------------------------------------------------------------
; PROCEDURE iTEReplaceStyle( ReplaceMode: INTEGER; Style1: STHandle;
; Style2: STHandle; redraw: BOOLEAN;
; hTE: TEHandle );
; ** <C94/29jul86/MBK> **
; Replaces Style1 by Style2. If the mode is not doAll, the given
; characteristic will be replaced within all styles in which it's found.
; Supports the following modes:
; 1 doFace: replace Face only
; 2 doSize: replace Size only
; 4 doFont: replace Font only
; 8 doColor: replace Color only
; 15 doAll: replace all modes
; ----------------------------------------------------------------------
iTEReplaceStyle
Tst.W teSize(A3) ; check style flag
Bpl.S @1 ; if not, sorry, can't set it
; ** <C381/6nov86/MBK> ** boolean value is in bit 1 of high byte
Move.W (A2)+,D0 ; get redraw value ** <C381/6nov86/MBK> **
And #$FF00,D0 ; check redraw value ** <C381/6nov86/MBK> **
Bne.S @0 ; must redraw if set
Bsr.S ReplaceGuts ; else just add styles
Bra.S @1
@0 Move.L A2,-(SP) ; save ptr to parameters
Bsr HideCaret
Bsr HiLite ; remove selection
Move.L (SP)+,A2 ; restore ptr to parameters
Bsr.S ReplaceGuts ; do style munging
MoveQ #0,D7 ; length is 0
Bsr RecalDraw ; redo the line stuff
Bsr ShowCaret
Bsr Hilite ; restore selection
Bsr SelView ; ensure selection is visible
@1 MoveQ #18,D0
Bra stdExit2
; ----------------------------------------------------------------------
ReplaceGuts
MoveM.L D2-D7/A2/A4/A6,-(SP) ; save registers
Move.L (A2)+,A4 ; replace style ptr
Move.L (A2)+,A6 ; find style ptr
Move.W (A2)+,D7 ; save mode here
And.W #doAll2,D7 ; only the lower 5 bits make sense <C971/RWW102987>
Bsr StyleGuts ; do style munging <C971/RWW102887>NO
@0 MoveM.L (SP)+,D2-D7/A2/A4/A6 ; restore registers
Rts
; ----------------------------------------------------------------------
; FUNCTION TEGetOffset( pt: Point; hTE: TEHandle): INTEGER;
; ** <C94/29jul86/MBK> **
; Returns the offset into the text corresponding to the given point.
; ----------------------------------------------------------------------
TEGetOffset
Bsr StdEntry
Move.L teSelPoint(A3),-(SP) ; save selPoint
; Find the point and get char index of it in D6
Move.L (A2)+,teSelPoint(A3) ; pass selPoint
Bsr DoFind ; juggle dispStart/End and do find
Move.W D6,(A2) ; dispStart
Move.L (SP)+,teSelPoint(A3) ; restore selPoint
Bra Epilog8
; ----------------------------------------------------------------------
; FUNCTION iGetStylHandle( hTE: TEHandle ): TEStylHandle;
; ** <C94/29jul86/MBK> **
; Returns the style handle.
; ----------------------------------------------------------------------
iGetStylHandle
Clr.L (A2) ; init value to Nil
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; if not, sorry, can't set it
Move.L teStylesH(A3),(A2) ; return the style handle
@0 MoveQ #6,D0
Bra StdExit2
; ----------------------------------------------------------------------
; PROCEDURE iSetStylHandle (hST: TEStylHandle; hTE: TEHandle);
; ** <C105/8aug86/MBK> **
; Sets the style handle.
; ----------------------------------------------------------------------
iSetStylHandle
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; if not, sorry, can't set it
; Dispose of old handle before replacing.
Move.L teStylesH(A3),A0 ; get old handle
_DisposHandle ; get rid of it
Move.L (A2),teStylesH(A3) ; set the style handle
@0 MoveQ #10,D0
Bra StdExit2
;; If onMacPP|onHcMac|forRAM THEN ; <C905/13oct87>
If (Not hasCQD)|(Not forROM) THEN ; <19Feb89smb>
; procedure RGBForeColor (Color : RGBColor);
; This routine takes an RGB triple and sets the current Graf- or CGrafPort
; fields so that drawing will take place with the best match of the
; requested color, using the current GDevice's color matching rules. The
; appropriate fields are set depending on portType
RGBForeColor
Move.L 4(SP),A1 ; point at the RGB color
; convert RGB to old-style index value
; use high bit of each component to select RGB off (0) or on (1)
MoveQ #0,D1 ; clear out D1
Move (A1)+,D1 ; get red
LsL.L #1,D1 ; get high bit
Move (A1)+,D1 ; get green
LsL.L #1,D1 ; get high bit
Move (A1)+,D1 ; get blue
LsL.L #1,D1 ; get high bit
Swap D1 ; get RGB index
Lea MapTbl,A0 ; get translate table
MoveQ #0,D0 ; clear out high word
LsL.W #1,D1 ; word index
Move 0(A0,D1),D0 ; convert to planar value
Move.L GrafGlobals(A5),A0 ; get the QuickDraw globals pointer
Move.L thePort(A0),A0 ; point at the port
Move.L D0,fgColor(A0) ; and set the index field
Move.L (SP)+,A0 ; get the return address
AddQ #4,SP ; get rid of the parameter
Jmp (A0) ; and return
; TABLE TO MAP FROM 3 BIT RGB TO OLD-STYLE COLOR INDICES
MapTBL DC.W $21 ; RBG = 0,0,0 -> black
DC.W $199 ; RBG = 0,0,1 -> blue
DC.W $155 ; RBG = 0,1,0 -> green
DC.W $111 ; RBG = 0,1,1 -> cyan
DC.W $CD ; RBG = 1,0,0 -> red
DC.W $89 ; RBG = 1,0,1 -> magenta
DC.W $45 ; RBG = 1,1,0 -> yellow
DC.W $1E ; RBG = 1,1,1 -> white
; PROCEDURE GetForeColor (VAR Color: RGBColor);
; Return the RGB components of the current foreground color
; Works for old and new ports.
GetForeColor
Move.L 4(SP),A1 ; point at the RGB color
Move.L GrafGlobals(A5),A0 ; get the QuickDraw globals pointer
Move.L thePort(A0),A0 ; point at the port
; Use CMYB bits in color to derive proper RGB components
Move.L fgColor(A0),D0 ; get planar color from port
BTst #5,D0 ; test black bit
Beq.S notBlack ; => color isn't not black
Or.W #$01C0,D0 ; else set CMY = 111 for black
notBlack LsR.W #1,D0 ; xxxC MYBR GBwb -> CMYx xxxx
MoveQ #2,D1 ; process 3 bits
nxtBit Clr.W (A1) ; assume component is 0
LsL.B #1,D0 ; check next component
Blo.S cmpOK ; => if bit set, component clear
Not.W (A1) ; else component = $FFFF
cmpOK AddQ #2,A1 ; advance to next component
DBra D1,nxtBit ; repeat for all components
Move.L (SP)+,A0 ; get the return address
AddQ #4,SP ; get rid of the parameter
Jmp (A0) ; and return
EndIf
; ----------------------------------------------------------------------
; FUNCTION iTEGetPoint( offset: INTEGER; hTE: TEHandle): Point;
; ** <23jan87/MBK> **
; Returns the point corresponding to the given offset into the text.
; ----------------------------------------------------------------------
iTEGetPoint
Move.W (A2)+,D0 ; get the offset
Move.L A2,-(SP) ; preserve parameter ptr
Move.W D0,-(SP) ; preserve offset
Cmp.W teLength(A3),D0 ; pin it to the length
Blo.S @0 ; ok if less or same
Move.W teLength(A3),D0 ; else pin to end
Move.W D0,(SP) ; replace offset
SubQ #1,D0 ; just for GetLine
@0 Lea teLines(A3),A2 ; pt to start of array
Bsr GetLine ; get ptr to line it's on
; LineRect expects to be called from RecalLines, which has its own frame. It saves
; a value off of A6, which in this case destroys the savePort value on the stdEntry frame.
; So save and restore the value that will be overwritten.
Move.W saveJust(A6),-(SP) ; LineRect will write something here
Bsr LineRect ; sets up selRect from destRect and justification
Move.W (SP)+,saveJust(A6) ; restore port
Move.W (A2),D6 ; start of line
Move.W (SP)+,D7 ; offset to measure to
; If the last char is a CR, the h coord should be at the beginning of the next line after the CR
; (the v coord was correct, but the h was at the point preceding the CR on the previous line).
Cmp.W teLength(A3),D7 ; is offset = text length?
Bne.S @2 ; skip CR test if not
Move.L teTextH(A3),A0
Move.L (A0),A0
Cmp.B #$0D,-1(A0,D7) ; if last char = CR then...
Bne.S @2
; assume left justification
Move.W teSelRect+left(A3),D0
Move.W teJust(A3),D1
Bne.S @1
Move.W teSysJust,D1
Beq.S @3
Cmp.W #teForceLeft,D1
Beq.S @3
@1
; right or center justification
Move.W teDestRect+right(A3),D0
SubQ #1,D0
Tst.W D1
Bmi.S @3
; center justification (divide width by 2)
Sub.W teDestRect+left(A3),D0
AsR #1,D0
Add.W teDestRect+left(A3),D0
Bra.S @3
@2
Bsr MeasureIt ; measure with style
Add.W teSelRect+left(A3),D0 ; add in justification
@3
Move.L (SP)+,A2 ; restore parameter ptr
Move.W teSelRect+bottom(A3),(A2)+ ; return v coord
Move.W D0,(A2) ; return h coord
MoveQ #8,D0
Bra StdExit2
; ----------------------------------------------------------------------
; FUNCTION iGetStylScrap( hTE: TEHandle): StScrpHandle;
; ** <23jan87/MBK> **
; Gets the style information corresponding to the current selection and
; returns a handle to it, stored in the same format as the 'styl' block.
; ----------------------------------------------------------------------
iGetStylScrap
Clr.L (A2) ; init value to Nil
Tst.W teSize(A3) ; is it a new TERec?
Bpl.S EndGet ; quit if not
Move.W teSelStart(A3),D0 ; get selstart, selEnd
Move.W teSelEnd(A3),D1 ; selEnd in D1
Cmp.W D0,D1 ; compare start to end
; Return true style at selection, whether inferred or stated in NullStRec
Bne.S @05 ; selection - get it <C971/RWW102387>
Move.L #scrpRecSize+2,D0 ; size of total scrap style rec <C971/RWW102387>
Bsr MyNewHandle ; temp handle for style scrap <C971/RWW102387>
Move.L A0,(A2) ; report back with scrap handle <C971/RWW102387>
Move.L (A0),A1 ; save as destptr <C971/RWW102387>
Move.W #1,(A1)+ ; one style total <C971/RWW102387>
Clr.L (A1)+ ; scrpStartChar := 0 <C971/RWW102387>
Move.W teSelStart(A3),D0 ; get offset <C971/RWW102387>
Bsr GetTrueStyle ; Get style record <C971/RWW102387>
Lea 2(A0),A0 ; skip over stCount to stHeight <C971/RWW102387>
Move.L #scrpRecSize-4,D0 ; amount to copy <C971/RWW102387>
_BlockMove ; from NullStRec to StScrpRec <C971/RWW102387>
Bra.S EndGet ; we're outta here <C971/RWW102387>
@05 ; <C971/RWW102387>
Bhs.S @0 ; ok if end >= start
Exg D0,D1 ; else swap start and end
@0 MoveM.L D2-D5/A2/A5,-(SP) ; save stuff
Bsr CopyGuts ; go to create 'styl' handle
MoveM.L (SP)+,D2-D5/A2/A5 ; restore stuff
Move.L A4,(A2) ; return 'styl' handle
EndGet MoveQ #6,D0
Bra StdExit2
; ----------------------------------------------------------------------
; PROCEDURE iSetStylScrap(rangeStart, rangeEnd: LONGINT; newStyles: StScrpHandle;
; redraw: BOOLEAN; hTE: TEHandle);
; ** <C971/RWW102887> **
; This procedure is the logical opposite of iGetStylScrap. It
; takes a handle to a style scrap record and applies it
; over the given range. iSetStylScrap does not affect the
; range of the current selection. If newStyles is NIL or
; if the edit record was not created with TEStylNew, this
; procedure has no effect.
; It is easily possible for the range to be out of sync with
; with the scrap record. In either case, as soon as a
; boundary is reached, this procedure is terminated without
; a specific error condition.
; ----------------------------------------------------------------------
iSetStylScrap
Tst.W teSize(A3) ; don't do anything if not styled
Bpl @xit
Move.W (A2)+,D5 ; get redraw byte <C971/RWW111787>
And.W #$FF00,D5 ; boolean is bit 1 of high byte <C971/RWW111787>
Sne D5 ; D5 non-zero if we want to redraw <C971/RWW111787>
Beq.S @03 ; we don't, so skip hiliting <C971/RWW111787>
Bsr HideCaret ; remove hiliting
Bsr Hilite
@03
Move.L (A2)+,A1 ; fetch scrap handle
; <17May89smb> must lock the handle before using it
move.l a1,-(sp) ; save for restoring flags <17May89smb>
Move.l a1,a0 ; handle to style scrap <17May89smb>
_HGetState
move.b d0,-(sp) ; save state flags for handle <17May89smb>
move.l a1,a0 ; get handle again for lock <17May89smb>
_HLock ; <17May89smb>
Move.L (A1),A1 ; point at scrap record proper
Move.L (A2)+,D7 ; fetch end
Move.L (A2),D6 ; fetch start
Cmp.L D6,D7 ; sort start/end
Bhs.S @05 ; end is higher or same, so okay
Exg D6,D7 ; we want start in D6
@05 MoveQ #0,D0 ; make long for comparisons
Move.W teLength(A3),D0
Cmp.L D0,D6 ; pin start to end of record
Bls.S @07
Move.L D0,D6
@07 Cmp.L D0,D7 ; pin end to end of record
Bls.S @09
Move.L D0,D7
@09 Move.L D6,D3 ; make a working copy
Move.L teSelStart(A3),-(SP) ; save original start/end
Move.W (A1)+,D4 ; number of styles to do
Bra.S @loop
@1 Cmp.L D3,D7 ; break out if start >= range end
Bls.S @done
Move.W D3,teSelStart(A3) ; save end as new start
Tst.W D4 ; is this the last scrap entry?
Bnz.S @2 ; no, calc end from table
Move.L D7,D0 ; ran off end of table, so force end
Bra.S @3
@2 Move.L D6,D0 ; calc end of selection
Add.L scrpRecSize+scrpStartChar(A1),D0
Cmp.L D7,D0 ; pin end to range end
Bls.S @4
@3 Move.L D7,D0
@4 Move.W D0,teSelEnd(A3) ; and save as new end
Move.L D0,D3 ; (save end as next new start)
MoveM.L D3-D7/A1/A4/A6,-(SP) ; <C971/RWW111787>
Move.W teSelStart(A3),D0 ; fetch start of style <C971/RWW111787>
Bsr GetOneStyle ; point at style to copy over <C971/RWW111787>
Lea stFont(A0),A6 ; iTEReplaceStyle expects it in A6 <C971/RWW111787>
Lea scrpFont(A1),A4 ; point at style to set <C971/RWW111787>
Move.W #doAll,D7 ; replace everything <C971/RWW111787>
Bsr StyleGuts ; go replace it <C971/RWW111787>
MoveM.L (SP)+,D3-D7/A1/A4/A6 ; <C971/RWW111787>
Add #scrpRecSize,A1 ; bump pointer to next scrap entry <C971/RWW111787>
@loop DBra D4,@1
@done
Move.L (SP)+,teSelStart(A3) ; restore previous select/end
move.b (sp)+,d0 ; state flags for style scrap handle <17May89smb>
move.l (sp)+,a0 ; handle to reset <17May89smb>
_HSetState ; <17May89smb>
Tst.B D5 ; are we redrawing? <C971/RWW111787>
Beq.S @xit ; nope, dump out <C971/RWW111787>
MoveQ #0,D7 ; no change in lineStarts array
Bsr RecalDraw
Bsr ShowCaret
Bsr Hilite
Bsr SelView ; ensure selection is visible <C971/RWW111787>
@xit MoveQ #20,D0
Bra StdExit2
; ----------------------------------------------------------------------
; PROCEDURE iTEStylInsert( pText: Ptr; l: LONGINT; hST: StScrpHandle;
; hTE: TEHandle );
; This inserts the passed text/length and the associated styles
; specified in the StScrpHandle just before the selection
; but doesn't touch the scrap. The selection too is "untouched"
; because it is offset by the inserted amount to point to the same
; range. Just after a TEStylNew this can be used as a replacement
; for the old TESetText because the selection and length are all zero.
; ** <C734/30jan87/MBK> ** Replaced PutStylScrap by iTEStylInsert.
; iTEStylInsert is exactly the same as TEInsert if the TERec is not
; a style record, or if a NIL style handle is passed in. Otherwise,
; iTEStylInsert inserts the input style information along with the
; text.
; ** <C788/11feb87/mbk> ** A2 points to the style handle when we
; 1st enter here. Before I was getting it after the text and length.
; ----------------------------------------------------------------------
iTEStylInsert
; ** <C766/10feb87/MBK> ** Removed call to StdEntry because TEDispatch does it.
Bsr HideCaret ; <C971/RWW102887>NO
Bsr HiLite ; remove selection <C971/RWW102887>NO
Move.L (A2)+,D0 ; get style handle ** <C788/11feb87/mbk> **
MoveQ #0,D7 ; delta = 0(No deletion)
MoveM.L (A2)+,D5-D6 ; A2 points to l param
; ** <C971/RWW101987> If length is 0, punt
Tst.L D5 ; length? <C971/RWW101987>
Bz.S @15 ; Nope, so leave <C971/RWW101987>
Tst.L D0 ; check if handle is NIL ** <C788/11feb87/mbk> **
Beq.S @0 ; can't insert styles if NIL
Move.L D0,A2 ; save style handle in A2 ** <C788/11feb87/mbk> **
Tst.W teSize(A3) ; check style flag
Bpl.S @0 ; just insert text if not a style record
Bsr MungeSetup ; setup for the insert
Clr.L -(SP) ; fake l1
Move.L D6,-(SP) ; pointer to insert = p2
Move.L D5,-(SP) ; length to insert = l2
_Munger ; use sloppy munger
AddQ.L #4,SP ; pop result
Add D5,teLength(A3) ; adjust length by insert amount
Move.L teTextH(A3),A0 ; get text handle
_Hlock ; and relock it
Move.L A2,A0 ; get style handle ** <C788/11feb87/mbk> **
_HGetState ; get the style handle's tag
Move.B D0,-(SP) ; and save the flags
_HLock ; and lock it
MoveM.L D2-D6/A2/A4,-(SP) ; save stuff
Move.L A2,A4 ; style handle in A4 ** <C788/11feb87/mbk> **
; ** <C851/23Apr87/MBK> ** High word of D3 must be clear for PstStylGuts
MoveQ #0,D3 ; clear whole register
Move.W teSelStart(A3),D3 ; selection start
Bsr PstStylGuts ; go do the style paste
MoveM.L (SP)+,D2-D6/A2/A4 ; restore stuff
Move.B (SP)+,D0 ; get the flags
Move.L A2,A0 ; get style handle ** <C788/11feb87/mbk> **
_HSetState ; set the style handle's tag
Sub D5,D7 ; adjust delta amount for ReCalLines
Bra.S @1 ; go recal
@0 Bsr insGuts ; go insert the text <C971/RWW102887>NO
@1 Bsr RecalDraw ; redo the line stuff
Add D5,teSelStart(A3) ; selStart:=selstart + insert amount
Add D5,teSelEnd(A3) ; selEnd:=selEnd + insert amount
@15 ; <C971/RWW101987>
Bsr ShowCaret
Bsr HiLite ; restore selection <C971/RWW102887>NO
MoveQ #18,D0 ; # of bytes on stack
Bra StdExit2 ; to be removed before exit
; ----------------------------------------------------------------------
; FUNCTION iTEGetHeight (endLine, startLine : LONGINT; hTE: TEHandle): LONGINT;
; ** Rewritten <C971/RWW102387> **
; Gets the total line height of the document.
; Now properly sorts endLine and startLine so doesn't need special glue.
; ----------------------------------------------------------------------
iTEGetHeight
MoveM.L (A2)+,D0-D1 ; 1st line
Cmp.L D0,D1 ; Which is larger?
Bhs.S @05 ; D1 is, so okay
Exg.L D0,D1 ; Assure endLine in D1
@05 Tst.L D0 ; is it 0?
Bnz.S @0
MoveQ #1,D0 ; minimum line #
@0 SubQ.L #1,D0 ; make it 0-based
Tst.L D1 ; is it 0?
Bnz.S @1
MoveQ #1,D1 ; minimum line #
@1 MoveQ #0,D2 ; clear D2 long
Move.W teNLines(A3),D2 ; last line
Bne.S @15 ; At least one line! <S443/RWW032588>
MoveQ #1,D2 ; <S443/RWW032588>
@15 ; <S443/RWW032588>
Cmp.L D2,D0 ; pin to last line
Bls.S @2 ; okay if less or same
Move.L D2,D0 ; else set to max line
@2 Cmp.L D2,D1 ; pin to last line
Bls.S @3 ; okay if less or same
Move.L D2,D1 ; else set to max line
@3 Bsr GetLineHites ; get total height
Move.L D0,(A2) ; return total height
MoveQ #14,D0 ; # of bytes on stack
Bra StdExit2 ; to be removed before exit
; ----------------------------------------------------------------------
; PROCEDURE iTECustomHook(which: TEHook; VAR addr: ProcPtr;
; hTE: TEHandle);
; ** <C971/RWW110487> **
; This procedure sets the various internal dispatch table
; addresses, returning the previous contents in addr.
; ----------------------------------------------------------------------
iTECustomHook
Move.L (A2)+,A1 ; fetch pointer to new address
Move.W (A2),D0 ; fetch selector
LsL.W #2,D0 ; * 4 for long offset
Move.L teDispatchH(A3),A0 ; get handle to hooks
Move.L (A0),A0 ; point at table
;; Add.L D0,A0 ; add in offset <16May89smb>
Add.w D0,A0 ; add in offset <16May89smb>: changed to word op.
Move.L (A0),D0 ; fetch old vector
Move.L (A1),(A0) ; and store away the new one
Move.L D0,(A1)
@xit MoveQ #12,D0 ; # of bytes on stack
Bra StdExit2 ; to be removed before exit
; ----------------------------------------------------------------------
; FUNCTION iTENumStyles(rangeStart, rangeEnd: LONGINT;
; hTE: TEHandle): LONGINT;
; ** <C971/RWW111887> **
; This function returns the number of style changes across
; a given range.
; ----------------------------------------------------------------------
iTENumStyles
Move.L (A2)+,D1 ; get end of range
Move.L (A2)+,D0 ; get start of range
Cmp.L D0,D1 ; Which is larger?
Bhi.S @1 ; D1 is, so okay
Beq.S @3 ; (special case when both same)
Exg.L D0,D1 ; Assure endLine in D1
@1 Tst.W teSize(A3) ; if it is an old TERec
Bmi.S @2
@3 MoveQ #1,D0 ; signify one style exists
Bra.S @xit
@2 Clr.L D2 ; pin rangeEnd to selEnd <C971/RWW111987>
Move.W teSelEnd(A3),D2 ; <C971/RWW111987>
Cmp.L D2,D1 ; <C971/RWW111987>
Bls.S @4 ; <C971/RWW111987>
Move.L D2,D1 ; rangeEnd was larger, force selEnd <C971/RWW111987>
@4 Bsr GetCurStyle
Bsr GetNumStyles
@xit Move.L D0,(A2) ; store away result
MoveQ #14,D0
Bra StdExit2
; ----------------------------------------------------------------------
; FUNCTION iTEContinuousStyle(VAR mode: INTEGER; VAR aStyle: TextStyle;
; hTE: TEHandle): BOOLEAN;
; ** <C971/RWW102687> **
; This function gives you information about the continuity of
; various aspects of the current selection. The result
; returned is TRUE if the given style exists across the
; entire selection range. The style attributes to check
; are specified by the mode parameter, which takes the
; same values as in iTESetStyle. Attributes which are
; continuous across the current selection range are
; returned in aStyle, with the appropriate bits set in
; mode. If the selection range is an insertion point,
; this call duplicates iTEGetStyle, except that the returned
; style reflects the style of the _next_character_typed_.
; The attribute bits of aStyle.tsFace are individually
; checked across the selection range, and are returned set
; to 1 if that attribute is indeed continuous.
; ----------------------------------------------------------------------
iTEContinuousStyle
Tst.W teSize(A3) ; is it a new TERec?
Bmi.S @1 ; yes it is, continue
Move.L (A2),A0
Move.L teGrafPort(A3),A1
Move.L txFont(A1),(A0)+ ; copy font/face
Move.W txSize(A1),(A0)+ ; copy size
Pea 0(A0) ; ptr to forecolor
;; If forRAM THEN
If (Not forROM) THEN ; 19Feb89smb>
BTst #14,ROM85 ; Becks or better? <C971/RWW112487>
Bnz.S @2 ; nope <C971/RWW112487>
_GetForeColor ; <C971/RWW112487>
Bra.S @3 ; <C971/RWW112487>
@2 Bsr GetForeColor ; <C971/RWW112487>
@3
;; ElseIf onNuMac|onMvMac THEN ; <C914/29Oct87> rwh
ElseIf hasCQD THEN ; 19Feb89smb>
_GetForeColor ; for Mac II
Else
Bsr GetForeColor ; for all others
EndIf
ST 8(A2) ; only one style, so everything's continuous
Bra.S @xit
@1 Bsr.S ContGuts
@xit MoveQ #14,D0
Bra StdExit2
; ----------------------------------------------------------------------
; ContGuts
; <C971/RWW102687>
; <S425/RWW031688> Rewrote according to suggestions from DTS. Now no face information
; needs to be passed in. If ANY face information is continuous across
; the selection, doFace is returned TRUE if it was requested.
; Seems this is a more required case than the original allowed for,
; (and besides, it is a helluva lot easier case to code for)
; Does actual work of iTEContinuousStyle
; ----------------------------------------------------------------------
contArgs Record 0
contStyle Ds.L 1
contMode Ds.L 1
contResult Ds.B 1
EndR
ContGuts
With contArgs
MoveM.L D3-D7/A4,-(SP) ; save working registers
Move.W teSelStart(A3),D0 ; insertion point gets handled differently
Cmp.W teSelEnd(A3),D0
Seq D5 ; show as an insertion point
Bne.S @1
Bsr AnyNullStyle ; use null style if available
Bnz.S @1
Tst.W D0 ; otherwise, we want style of character…
Bz.S @1 ; …just _before_ insert point
SubQ.W #1,D0 ; (exception is top of record, obviously)
@1 Bsr GetTrueStyle
Move.L contStyle(A2),A1 ; point at receiving record
Move.L stFont(A0),tsFont(A1) ; move TextStyle
Move.L stSize(A0),tsSize(A1)
Move.L stColor+2(A0),tsColor+2(A1)
; aStyle is primed with the style of the selection start. Find the StyleRun that
; determines the selection start and walk through the style changes, noting differences
Move.B stFace(A0),D7 ; save start face for compare later <S425/RWW031688>
Move.B D7,D6 ; make a working copy
Move.L contMode(A2),A0 ; point at mode
Move.W (A0),D0 ; save mode for comparison later
And.W #$000F,D0 ; only low 4 bits make any sense
Move.W D0,D4 ; D4 = working register <S425/RWW031688>
Move.W D0,D3 ; D3 = original request <S425/RWW031688>
Tst.B D5 ; insertion point?
Bnz @goodxit ; yes, so no need to consult style entries <S425/RWW031688>
Move.W teSelStart(A3),D0 ; get selection start
Bsr GetCurStyle ; get the current StyleRun
Move.L A0,A4 ; (we don't need the TEHandle…)
@loop AddQ #stStartSize,A4 ; actually, we want the next one
Tst.W D4 ; if we've reset all bits…
Bz.S @2 ; …it's senseless to go on
Move.W startChar(A4),D0 ; if negative, we're off end of table
Bmi.S @2
Cmp.W teSelEnd(A3),D0 ; if past end of selection, we're done
Bhs.S @2
Move.W styleIndex(A4),D0 ; get index into style table
Bsr GetStyle ; go get it
; In order for this to work, neither GetCurStyle nor GetStyle can mess with A1!!!!!…
BTst #fontBit,D4 ; check font?
Bz.S @3
Move.W tsFont(A1),D0
Cmp.W stFont(A0),D0 ; do fonts match?
Beq.S @3 ; yes, go on
BClr #fontBit,D4 ; don't need to check it anymore
@3 BTst #sizeBit,D4 ; check size?
Bz.S @4
Move.W tsSize(A1),D0
Cmp.W stSize(A0),D0 ; do sizes match?
Beq.S @4 ; yes, go on
BClr #sizeBit,D4 ; don't need to check it anymore
@4 BTst #clrBit,D4 ; check color?
Bz.S @5
Move.L tsColor(A1),D0
Cmp.L stColor(A0),D0 ; do red/green match?
Bne.S @6 ; no, reset bit
Move.W tsColor+4(A1),D0
Cmp.W stColor+4(A0),D0 ; does blue match?
Beq.S @5
@6 BClr #clrBit,D4 ; don't need to check it anymore
; Comparing faces is a bit tricky. If we started out plain, merge in style bits.
; Otherwise, calculate intersection of bit sets
@5 BTst #faceBit,D4 ; check face?
Bz.S @loop
Tst.B D7 ; did we start out with plain style?
Bnz.S @8
Or.B stFace(A0),D6 ; Don't fall through anymore <S488/RWW050388>
Bra.S @loop ; <S488/RWW050388>
@8 And.B stFace(A0),D6
Bra.S @loop
; We come here when we're done perusing the selection range.
; Now, we have to resolve the doFace bit. This is all complicated by the fact that
; “plain” isn't a style attribute, but rather a lack of other styles.
@2 BTst #faceBit,D4 ; check face?
Bz.S @xit ; nope, skip resolution
; <S425/RWW031688> All this is new, for new handling of face information
Tst.B D7 ; did we start out with plain? <S425/RWW031688>
Bnz.S @notPlain ; nope, go on <S425/RWW031688>
Tst.B D6 ; if ended with plain, hunky dory <S425/RWW031688>
Bz.S @goodxit ; save result and exit <S425/RWW031688>
@badxit BClr #faceBit,D4 ; no good. reset bit <S425/RWW031688>
Bra.S @xit ; …and leave <S425/RWW031688>
@notPlain Tst.B D6 ; end with any intersection? <S425/RWW031688>
Bz.S @badxit ; nope, so nothing was continuous <S425/RWW031688>
@goodxit Move.B D6,tsFace(A1) ; save intersection to aStyle <S425/RWW031688>
@xit Move.L contMode(A2),A0 ; Point at mode
Move.W D4,(A0) ; save intersection back to mode
Cmp.W D4,D3 ; Was everything continuous? <S425/RWW031688>
Seq D0 ; TRUE if everything was equal <S425/RWW031688>
Neg.B D0 ; Blaise wants false=0 and true=1 <C971/RWW111687>
Move.B D0,contResult(A2) ; Blaise wants false=0 and true=1 <C971/RWW111687>
MoveM.L (SP)+,D3-D7/A4 ; Retrieve working registers
Rts
EndWith ; contArgs
; *************************************************************************************************
; *************************************************************************************************
; *************************************************************************************************
; TextEdit end