mac-rom/Toolbox/TextEdit/TextEdit.a
2017-12-26 09:52:54 +08:00

15516 lines
563 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: TextEdit.a (formerly te68k.a)
;
; Contains: TextEdit for ROM or (when included in TextEditPatch.a) 'ptch' 0
;
; Written by: SC Steve Capps
; EHB Ernie Beernink
; MBK Margie Kaptanoglu
; RWW Russ Wetmore
; SMB Sue Bartalo
; YS Yishai Steinhart (most recently)
;
; Copyright: © 1982-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM9> 10/12/93 RC Stop using A6 in the DefClikProc callback. Instead grad the
; teHandle from a RecoverHandle on the tePtr
; <SM8> 6/28/93 kc Init TEDoText,TERecal and TEWdBreak at TEGlobalInit time so work
; around a QuickTime bug. (Movies containing text as StartupItems)
; <SM7> 10/22/92 CSS Change some branch short instructions to word branches.
; <SM6> 10/6/92 PN # 1040150 Get rid of Sysvers conditionals and bring the code to
; the current state (7.1)
; <50> 8/11/92 SMB #1036481 <gbm>: #1036481 <gbm>: Removed font/keyboard
; synchronization for Roman-only systems. It's unnecessary and
; slows things down!
; <49> 7/15/92 SMB ## <ys>: Renamed DoText selectors: teMark is now teHighlight and
; teLoc is teCaret.
; <48> 7/8/92 PKE Fix up previous comment (I was too quick with the Return key).
; <47> 7/8/92 PKE #1035214 <csd>: Fix DoSearch so that it always exits by calling
; FreeFmtOrderArray at exit, which will dispose of any fmtOrdering
; handle and clear the ExpandMemRec.emFmtOrderHFlag flag which
; says that the handle is valid. This will prevent subsequent
; calls from thinking they have a valid handle before they
; actually allocate one.
; <46> 7/7/92 PKE #1030684 <yds>: TEGetPoint failed in multiline text if a R->L
; script was present because in this case DoMeasure measured from
; the beginning of the buffer, not the beginning of the current
; line. Fixed.
; <45> 6/23/92 SMB #1029263,<pke>: Now checking the script's 'itlb' flags to
; determine if the keyboard and font should be synchronized. Added
; new IM 2nd Ed. routine names to the file for easier searching of
; routines.
; <44> 4/27/92 DTY Get rid of hasSplineFonts conditionals.
; <43> 4/20/92 YS #1027783, a wrong label @1 instead of @3 caused the wrong jump,
; and the stack was not cleared, causing the registers not to be
; restored.<43-YDS-4/19/92>
; <42> 4/3/92 YS #1025998, in TextBox, when trying to find the right line highet
; in systems that use associated font (see <41>), saving and
; restoring of the font saves a LONG (instead of a word) creating
; the problem of loosing the port font. Another connected problem
; was the way Script Manager handeld those privete verb calls in
; the roman. This was fixed in the Script Manager. <42-YDS-4/2/92>
; <41> 2/6/92 YS #1014691, Cube-E, In the old days, the Hebrew/Arabic extention
; used to calculate the highet of a script font as Max(script font
; size, associated font size). The problem with that is that if
; you use style runs, like styled TE & WP's, you can't get the
; real size of of a script font, and you allways have the
; associated font size in it. The universal one byte init no
; longer handles it. TE will calculate it itself if it is: 1)
; unstyled text. 2) script font. 3) Has associated font (other
; then 0). <41-YDS-2/6/92>
; <40> 2/4/92 YS #1015382, Cube-E, don't redraw the whole line for a left 2 right
; system when justification is teForceLeft. <40-YDS-2/5/92>
; <39> 1/30/92 YS #1018683, Cube-E: TextBox should handle #teForceLeft correctly
; and not set it to #teJustLeft allways. <39-YDS-1/30/92>
; <38> 1/13/92 PKE #1019673, Bruges: Unstyled TE should not sync the keyboard at
; all for smEastEurRoman script.
; <37> 12/17/91 PKE #1017647: Fix keyboard synchronization in unstyled one-byte
; non-Roman text. For bidi scripts: don't synchronize control
; chars and L-R numbers, set keyboard to Roman for other L-R
; chars, and sync keyboard to font for R-L chars. For other
; scripts: sync keyboard to font for script letters, set keyboard
; to Roman for Roman letters, and don't sync anything else.
; <36> 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
; <35> 11/12/91 JL fixed the broken build. The previous change had a <34> after an
; EndIf with no comment marker - - ooops! The build was broken for
; a day and no one complained.
; <34> 11/12/91 SMB #1014705 - for CubeE and Bruges. Keyboard and font synch'ing
; isn't correct for punctuation and numbers: TE allows a Roman
; keyboard & a non-Roman font combination for ascii characters and
; european characters (or high ascii chars.) and it should also
; allow this for numbers and punctuation marks. This was reported
; against the Eastern European systems. Actually, this code will
; be optimized to only allow this unsynchronized state for a
; 2-byte fontScript and a Roman kbd. See ClickKeyboard2Font. Also
; fixed some bugs in the synchronization of the font & kbd for
; unstyled text in TEClick and TEKey.
; <33> 9/30/91 YS Used to syncronize the keyboard wrong for L->R scripts
; (unstyled) when was backspacing a selection (and not a single
; delete), d6 wasn't set up corectly. use teSelStart(a3) instead.
; (bug #1013159) <33-YDS-10/1/91>
; <32> 9/23/91 PKE For Cube-E (and Bruges): If non-Roman scripts are installed,
; TEInit should no longer set TESysJust to its idea of system
; default, since users can now set the default. Also: Define
; forLocalizability here if it is not defined in BBSStartup.
; <31> 9/13/91 YS Rolled in the fixes made for SS-6.1.
; <31p> Fix the wrong placment of the caret for one blinking cycle when
; changing a language and typing a char. (bug #1006971)
; <31p-YDS-8/27/91>
; <31n> when backspacing, sync the keyboard to the right language enen
; for unstyled (single byte only). (bug #1006972) <31n-YDS-8/27/91>
; <31m> Fix the Big cursor bug, this is NOT the old big applelink cursor
; bug (fix YSD <3.1>). In the case where the cursor is on a line
; start, we used to fall into the single caret code
; (but we didn't have any split caret !!!), so while switching
; the cursor rect's for a single caret, we used to garbage the
; selRect. so, we now test ExpandMemRec.emTwoCursorsFlag in this
; case to avoid it. (bug #1007065) <31m-YDS-8/27/91>
; <31l> Fix TEGetPoint for styled TE for R->L scripts, used to asume
; that if we are on a begining of a style run, the width is 0, and
; if we are on the end, we should TextWidth all of it, which is
; not true for R->L scripts. (bug #1007067) <31l-YDS-8/27/91>
; <31k> Added support for a single caret while handling an Arrow (left
; or right) key, for styled L->R text. have to change the Keyboard
; in a different way to support the corect display of a
; single caret. <31k-YDS-8/27/91>
; <31j> Fix in xStyleGuts, don't change font's when their are not from the same
; script, has a minor fix in SetGuts to.(commented) <31j-YDS-8/27/91>
; <31i> Fix DoMeasure for Right to left text in unstyled TE, in order to
; support fix <31h> for unstyled, use _Pixel2Char instead of
; MeasureIt. <31i-YDS-8/27/91>
; <31h> Fix TEGetPoint Bug for Right to left text, use DoMeasure
; instead of MeasureIt. <31h-YDS-8/27/91>
; <31g> Synch Keyboard to click even with an unstyled TE record,
; this is not only a nice thing to do, but very importent when
; handling a single cursor on a bi-direction script, if we
; would like your single-split carret to be displayed
; correctly. <31g-YDS-8/27/91>
; <31f> when click on script boundry, take care of the next cursor
; update, has to do with the split carret stuff. This was fixed
; in SetKeyboard2Font and ClickKeyboard2Font.<31f-YDS-8/27/91>
; <31e> find where the click was (to define the right script).<31e-YDS-8/27/91>
; <31d> Support for a single carret, this supports the styled
; TE part.<31d-YDS-8/27/91>
; <31c> Added support for a single carret, it will expand & shrink
; the the right part of a cursor to show only "one" cursor,
; depending on the language, so we will gwt a moving cursor
; (when switching scripts). this supports the unstyled TE part.<31c-YDS-8/27/91>
; <31b> using the byte after the TwoByteCharBuffer in teDispatchH for
; fixes <31c> and <31d> (lastScript), so change the place it clears
; so only a word will be cleared there (instead of a long).<31b-YDS-8/27/91>
; <31a> Fixing Hebrew/Arabic AppleLink bug that causes a big cursor:
; the right way! this fix is in four places.<31a-YDS-8/27/91>
; <30> 4/3/91 SMB jdr,#86089: (also, pke) Fixing appl-crashing bug in
; NewRomanFindLine - should be clearing the high word of d0 before
; doing a long operation. Shows up when applications use
; TEHitTestHook and have multiple styles on a line.
; <29> 2/14/91 SMB pke,#70628: Unfortunately, forced to remove support for Forward
; Delete that was added in <20>. Conditionalizing it out so it can
; be added again later. See <29>.
; <28> 2/14/91 SMB pke,#82817: After Dark and Chooser string clipping bug -
; NewRomanFindLine's dependency on _NPixel2Char takes into account
; the caret width when determining linebreaks. This 1 pixel
; difference caused strings that were 1 pixel too long to no
; longer completely display since the linebreak occured in a
; different place. The problem was that the measurement occured on
; the character boundary (after the final character of the string)
; and the leading edge value returned was F. TextEdit deals with
; these results by backing up one character to guarantee that all
; characters completely display when drawn. In the case of calling
; _NPixel2Char this is not necessary since it will still return
; the correct results and TextEdit will behave correctly based on
; these results. So, to fix this problem we no longer subtract one
; for the caret width before calling _(N)Pixel2Char.
; <27> 2/14/91 SMB pke,#DTS FT: Quit trashing a4 across Hook calls!
; <26> 2/11/91 SMB pke,#SMB-2/9/91-1: TextEdit didn't always erase characters when
; deleting them. Another symptom of this same bug is that TextEdit
; didn't line break at a CR. The problem was that when TE looked
; ahead for blanks at the end of a line in NewRomanFindLine, it
; skipped over blanks, CRs and any other character whose value was
; <=$20. Now it checks each breaking character for a CR and once
; found, forces a line break there.
; <25> 2/11/91 SMB jdt,#TEBug.ReCaLines: KanjiTalk bug fix in ReCalLines - need to
; back up 2 bytes for correct redrawing of double-byte text.
; <24> 2/11/91 SMB pke,#OYDBB002: Fixed the MathCad (application) bug in
; NewRomanFindLines by ckecking for a dummy style run at the end
; of the StyleRun array whose startChar = endChar.
; <23> 2/1/91 SMB pke,#HIG-JS-048,#81519,#82169: In NewRomanFindLine: testing for
; a blank at a line break before calling TE's FindWord routine.
; Fixed problem with styles in balloons: was comparing a final
; result to the linestart in d6, but it was modified for styles,
; so needed to compare to actual value saved in lineStart(a6).
; Fixed performance problem: change in algorithm caused unstyled
; TE to call TextWidth on the entire document (pinned to each
; lineStart) when determining line breaks. Major slowdown! Are now
; calling _NPixel2Char instead of _TextWidth & _Pixel2Char in TE's
; Pixel2Char routine (TEHitTestHook). Should make TE FAST(er)!
; Renamed leftSide to leadingEdge in P2CFrame and added
; WidthRemaining member (see TextEditPriv.a).
; <22> 1/22/91 SMB (pke) Re-fixing bug #68221. The previous fix required calling
; OutlineMetrics for the whole font in order to get an ascent &
; height in TextEdit. This wasn't acceptable due to reformatting
; problems. So, the code to support OutlineMetrics has been
; removed and we are now turning off PreserveGlyph before drawing
; in order to draw squished characters when their ascent or
; descent is larger than the font's metrics. GetFontInfo will
; still be used to get ascent & height, as in the past, and we
; will be backwards compatible although not pretty.
; <21> 1/18/91 SMB (pke) Fixed bug # 62963 - No longer preserving a3/a4 across
; DumpBuffer routine. Saving a3 caused a dangling ptr and it's not
; necessary to save a4. Also, added a call to DumpBuffer in
; TEDispose in case an app never calls TEIdle (which empties the
; buffer). Changed _NewHandle call in GetHandle to allocate the
; handle in the System heap in order to prevent orphaning the
; handle when an application quit without emptying the text
; buffer. ¥ Also fixed a linebreaking bug in Pixel2Char - wasn't
; calling DoubleByte with the correct offset (was using the offset
; for the line not the offset w/in the whole text buffer thus
; far.)
; <20> 1/14/91 SMB (jdt) ¥ Fixed bug #66732 & #57858: if the scrap handle parameter
; (newStyles) in SetStylScrap was NIL should do nothing and exit.
; ¥ Fixed bug #58512: Must lock scrap handle in InsRsrved before
; calling PstStylGuts since PstStylGuts expects to use the handle
; again after moving memory. Also fixes bug #65043. ¥ Fixed bug
; #77962: TE was determining line breaks by measuring words rather
; than style runs for a Roman-only system. This was causing
; drawing to be significantly different than the measuring when
; FractEnable was on or a scaled font was used. Rewrote code (now
; called NewRomanFindLine) to do the right thing! ¥ fjs fixed bug
; #70628: adding forwardDeleteChar support in TEKey so that this
; function key on the extended keyboard works. ¥ Fixed bug #67699:
; StdTxMeas did not detect overflow when measuring long lines, so
; the widths returned to TE in this case were small, causing TE to
; write all the text on one line. StdTxMeas was modified to keep
; the last count and width before the overflow. This info is used
; to call _Pixel2Char to get the correct character offset for line
; breaking. ¥ Fixed bug #66900: TextBox did not clip text
; correctly for long words due to the incorrect use of _P2C's
; LeadingEdge flag. See changes in TE's P2C and DoSearch. ¥ Fixed
; bug #68221: did not calculate the ascent & descent of an outline
; font correctly if preserveGlyph is true. Now calling
; OutlineMetrics for this. See routine GetOutlineMetrics and the
; routines calling it, TextBox & GetSize. ¥ Fixed Finder bugs
; #80728 & 75607: in StdEntry, for unstyled text, save the
; grafport's font info before setting the TERec's style info into
; the grafport.
; <19> 12/15/90 SMB (gbm) KT bug: Only draw line in ReCalLines when wordRedraw is <1.
; Added support for another gestalt selector, gestaltTE5, for the
; new TextWidthHook.
; <18> 10/30/90 SMB Fix text buffering bugs: must preserve register containing
; ExpandMem ptr around a call to another procedure. Also, moved
; code that dumps the buffer in SetFont2Keyboard after determing
; that synchronizing was necessary. Then, must test for an empty
; buffer in TEBufferText after the SetFont2Keyboard call and after
; a full buffer has been dumped. Using hasBufferingFix conditional
; for these changes. Added TextWidthHook to dispatch table and the
; internal interface which uses the hook, TETextWidthHook to hook
; out the TextWidth calls to keep our developers happi(er)!.
; Renamed nTEWidthHook to ScriptChar2Pixel. Using hasTextWidthHook
; conditional for these changes. Moved frame for TextBox into
; TextEditPriv.a Added teFUseTextServices to comment although TE
; doesn't use it. This allows an application to disable inline
; input. The teFInlineInput bit will be used to enable the
; features added for Inline Input. This bit is set by the inline
; input service and may also be set by a developer who desires
; these features even when inline input is inactive.
; <17> 9/13/90 BG Removed <15>. 040s are behaving more reliably now.
; <16> 9/11/90 SMB Fix teCROnly bug that crashes the system: pre-incrementing
; caused us to compare one too many in the text and then the +1 to
; point beyond the CR caused the line breaks to be one off. Moved
; InlineInput test into TESetSelect instead of ClickKeyboard,
; since never want to call KeyScript while doing inline. If in
; Inline, then not hilighting to the EOLs anymore, only to edge of
; text (see InvrtRectangle). Modified highlighting code to modify
; the middle rectangle line by line in order to call highHook for
; Inline. Moved HiliteFrame into TextEditPriv.a.
; <15> 7/25/90 BG Added some EclipseNOPs for flakey 040s.
; <14> 7/25/90 SMB NEEDED for SS-6.0.5, SIXPACK & 7.0: Fixed Hebrew/Arabic
; scrolling down bug - caused selRect's top & bottom values to be
; negative which caused a BIG caret to be drawn. Fixed in
; CaretInsideRun.
; <13> 7/10/90 SMB NEEDED for 7.0 & SIXPACK: Must export GestaltTEVersion.
; <12> 7/10/90 SMB NEEDED for 7.0 & SIXPACK: Oops! Moved GestaltTEVersion back into
; here for SIXPACK+ builds from TextEditInit.a.
; <11> 6/22/90 SMB NEEDED for 7.0 & SIXPACK: Moved TEGlobalInit, GestaltTEVersion
; and its vectors to TextEditInit.a. Exported routine labels for
; TextEditInit.a. NEEDED for SS-6.0.5, SIXPACK & 7.0: fixed Arabic
; line end bug for unstyled text, where the system slowed down
; because was reading off the end of the line starts.
; <10> 6/11/90 SMB NEEDED FOR SIXPACK & 7.0: Added Inline Input bit to
; TEFeatureFlag and support for it in ClickKeyboard2Font.
; <9> 5/29/90 DDG NEEDED FOR SIXPACK: Changed all the sixpack conditionals from
; six-point-oh-seven to six-point-oh-six.
; <8> 4/27/90 SMB NEEDED for SIXPACK - Fixed old bug for old FindWord: when using an
; application's teWordBreak routine must save d1!
;*********** End of SS-6.0.4 f4 (for KanjiTalk 6.0.4 only!) changes ******************************************************
; <7> 3/20/90 SMB NEEDED for 6.0.5 and SS-6.0.4 - Added call to SetKeyboard2Font
; in TEKey (rather than DelGuts, see 1/16/90) for script systems;
; whenever backspacing over a script boundary the keyscript wasn't
; updated. Bug #59422. - In TEBufferText, must set d0 to the
; current position before calling SetFont2Keyboard (in case of a
; kbd change while buffering)
; <6> 2/18/90 SMB NEEDED in 6.0.5 - DoSearch didn't work correctly if the
; TEHitTestHook had been replaced. We needed to check a
; terminating condition when hooked out: the high word of d0 was
; set T if found a char offset.
;*********** End of domestic 6.0.5 changes; SS-6.0.4, SS-6.0.5 and 7.0 changes still occurring ***************************
; <5> 2/13/90 SMB NEEDED for 6.0.5 - Fixed broken TEWidthHook by putting back in
; the old C2P code and adding a new hook nTEWidthHook for the SMgr
; compatible C2P.
; <4> 1/30/90 SMB NEEDED FOR 6.0.5 - multiple bugs fixed: see history below.
; 1/30/90 smb - Fix in TEKey so that when the current position is at a line end and
; the height of the current line is > the height of the next line, the
; down arrow will put the caret on the next line. Bug #53697.
; 1/30/90 smb - Fix to PtToLine to leave the line # negative when going up on the
; top line. Makes DoFind do the right thing. Fixes bug 35646: up-arrow
; key doesn't get to beginning of text.
; 1/29/90 smb - No longer call SetFont2Keyboard for DumpBuffer.
; - Added patch to DoCaret to pin the caret in view when
; blanks exceed the edge of the view rect.
; 1/26/90 smb - Before synchronizing the font to the keybd, dump the text buffer: user
; could change the keyboard in the middle of buffering. (see TEBufferText and
; SetFont2Keyboard)
; 1/25/90 smb - Call HideCaret for up & down arrows to erase the old caret before
; setting teLftCaret in TEKey. Fixes bug #52887!
; - Fixed up arrow bug, #51967, that caused the caret to move up multiple
; lines according to the size of the largest font on the current line.
; - If zero width in DoSearch, want to branch ow this one pixel difference
; causes the caret to display on the wrong line ending. Roman fix.
; Bugs #58921,59247.
; 1/24/90 smb - Found bug in DoSearch where needed to setup a2 as current line again.
;*********** End of SS-6.0.4 f3 (for Arabic and Hebrew 6.0.4 only!) changes **********************************************
;*********** Did not add humane scrolling or move the equates (see 1/22-1/23 comments) for SS-6.0.4! *********************
; 1/23/90 - Changed FindWord branch for linebreaking to 'bge' instead of 'bgt'.
; emt - Added humane scrolling (slower) to DefClikProc (also see TEClick).
; 1/22/90 - Moved private equates and frames into TextEditPriv.a.
; 1/16/90 SMB NEEDED FOR SS-6.0.4 and 6.0.5 - (added 1/22/90 to Scripts604 build)
; Added call to SetKeyboard2Font in DelGuts for Script Systems:
; whenever backspacing over a script boundary the keyscript wasn't
; updated. Bug #59422.
; Reorg beginning of FindWord in order to be compatible with applications
; using incorrect char breaking algorithms for Script Systems.
; <3> 1/16/90 SMB NEEDED FOR 6.0.5 - Fixed bug in TEGetPoint, added double-byte
; buffer at end of dispatch record, fixed bug in r-to-l processing
; of caret that showed up when scrolling down.
; 1/15/90 smb Fixed Hebrew/Arabic scrolling down bug - caused selRect's top & bottom
; values to be negative which caused a BIG caret to be drawn. Fixed in
; CaretInsideRun.
; 1/9/90 smb Using private space in TEDispatchRec for buffering of a double-byte
; char rather than using ExpandMem as a global buffer which can affect
; any active TE record. This fixes a bug seen in KanjiTalk (AppleShare)
; when an application uses two TE records. Buffering in one record can
; be dumped into the other record due to the global storage space not
; knowing which record it applies to.
; 1/8/90 smb NEEDED FOR 6.0.5: bug 58823, TEGetPoint returned incorrect values
; when there's no text in the TERec.
; <2> 1/4/90 PKE NEEDED FOR 6.0.5 (smb's changes from SS-6.0.4b23 to SS-6.0.4f1):
; ¥<15Dec89smb> Set the offset parameter to non-zero for
; StyledLineBreak for unstyled text. ¥<17Dec89smb> Preserve
; register d2 in HiliteMiddle. ALSO: Changed conditionals from
; (Scripts604 | SysVers >= $700) to (Scripts604 | SysVers >=
; $605). Updated header to BBS format.
; <1> 12/18/89 CCH Adding for the first time into BBS.
; BBS versions above:
;___________________________________________________________________________________________________
; EASE versions below:
; <3.2> 12/11/89 smb See history of bug fixes below dated Nov. 22, 1989 -> Dec. 7,
; 1989.
; 12/7/89 smb Fixed problem with setting the boundaries in ChkBounds. Also set
; boundary in DoDraw based on WordRedraw rather than teSysJust.
; ¥ Corrected test of teForceLeft in iTEGetPoint.
; ¥ Fixed bug of a large cursor (#52888) due to RomanFindLine (really
; StylMeasure & P2C) incorrectly increasing the char count due to
; an invalid leftSide flag set in TE's P2C. This caused ReCalLines
; to read beyond the end of the line heights record. Fixed by
; setting a flag which said to ignore the leftSide flag if TextWidth
; did the measuring in P2C.
; 12/6/89 smb Unconditionalized code in VisibleLength to fix a LR line w/ R
; justification display bug. Mark was right!
; ¥ Set flags in caret display code to indicate when in the middle
; of a style run but on a line end (see CaretInsideRun).
; ¥ Fixed bug in {hit-down on,cursor movement to} a script boundary
; to set the keyboard to the preceeding style run rather than the
; succeeding one. (see calls to ClickKeyboard2Font).
; ¥ In BufferChar & DumpBuffer backed up one offset posn to get
; previous style run for SetFont2Keybaord call.
; 12/5/89 smb Fixed LR highlighting bug at line ends; in InvrtRectangle.
; 12/3/89 smb Added a new keyboard/font synchronization routine to be used
; when doing a hit-down which allows a Roman keyboard with a
; non-Roman font, specifically because KanjiTalk wants to enter
; Roman text from a Japanese font.
; ¥ Fixed potential bug in TESetStyle: must test the doFont bit in
; the mode since it's possible for the mode to be an additive
; combination of styles.
; ¥ Use application font for SetFont2Keyboard rather than system
; font.
; ¥ Have to use emBufferPtr for a flag to indicate when I
; unsynchronize the font & keyboard in ClickKeyboard2Font. These
; will be used to keep SetFont2Keyboard from synchronizing the
; font & keyboard when trying to paste a character in this
; unsynchronized situation.
; ¥ Also had to add a call to ClickKeyboard2Font from TESetSelect in
; order for horizontal cursor movement to work correctly in this
; new unsynchronized situation.
; 11/26/89 smb More cursor movement pinning, this time in GetStyleEnd. Also,
; need to use the high caret rectangle in TEKey rather than always
; using the teSelRect!
; 11/22/89 smb In CursorMovement had to pin the style run to the line end for
; correct position.
; <3.1> 11/21/89 smb See history of bug fixes below dated Oct. 4, 1989 -> Nov. 20,
; 1989.
; 11/20/89 smb Added a test in ptchGetRLPosition because when processing a CR
; entered at the EOD, the current line (a2) is the next line. This
; causes TE to look beyond the end of the lineStarts array.
; 11/17/89 smb Bug in DumpBuffer for unstyled textEdit: screwed up stack since
; was popping the stack w/o doing the push! Now doing the push as
; well!
; 11/16/89 smb Fixed TrimMeasure for unstyled TE. Also moved the firstStyleRun
; and secondStyleRun to the top of the the FmtOrderFrame.
; 11/13/89 smb Bug fix for buffering 2 byte text on Kanji! see DumpBuffer and
; TEBufferText.
; 11/8/89 smb Moved secondStyleRun and firstStyleRun from SharedFrame to
; FmtOrderFrame since TextFrame needs this info for XTrimMeasure
; changes.
; 11/6/89 smb Fixed buffering bug in BufferChar & TEKey; must set emBufferLen
; non-zero when buffer the 1st byte of a 2-byte character.
; 11/1/89 smb Adding call to GetStylesInOrder in order to call VisibleLength
; for a line's style runs. We need to traverse the style runs in
; display order but backwards!
; 10/31/89 smb Fixed TETrimMeasure to call VisibleLength at the appropriate
; times for unstyled text: LineRect uses the line direction and
; justification to determine when to call it.
; 10/26/89 smb Bug fix in FindWord for Chinese Script System: clear
; fwLeadingEdge flag!
; 10/16/89 smb Added updating of outlined region in TEUpdate.
; 10/6/89 smb Had to clear (a2) in iTEFeatureFlag so that the return result
; was set right for an initial state of clear (vs. set).
; 10/4/89 smb Removed LRTextFlag since it's based on WordRedraw. Will tst
; WordRedraw instead!
; <3.0> 10/12/89 smb Checked in fix below dated 10/3/89.
; 10/3/89 smb Fixed the caret display in TEActivate and TEDeactivate for
; outline highlighting. Put in old DoHilite code for Roman systems
; for HyperCard outlining.
; <2.9> 9/26/89 smb Checked in fixes below dated 8/31/89-9/19/89, plus: Saving the
; bit in the upper byte of the ExpandMemRec.emBufferLen word.
; 9/19/89 smb Adding Outline Hilighting to TEActivate/TEDeactivate.
; 9/17/89 smb Fixed TEKey to turn off and reset the text buffering bit around
; the StdEntry call.
; 9/15/89 smb Must move newTEFlags into a data reg for modulo 32 bit ops
; (bset,bclr,btst).
; 9/14/89 smb Added calls to dump the text buffer in StdEntry and TeKey.
; 9/12/89 smb Fixed up DumpBuffer and TeFeatureFlag code.
; 9/6/89 smb Removed call to SetFont2Keyboard in TEKey since I added it to
; BufferChar.
; 9/5/89 smb Complete rewrite of SetFont2Keyboard.
; 9/2/89 smb Fixed bug #52736, CursorMovement should jump 2 bytes for Kanji
; on a RL line. Had to also add call to SetFont2Keyboard in
; BufferChar since changing the styled teRec's initial kbd setting
; (from Roman to Japanese) before entering Kanji text caused the
; character to display incorrectly. It was using the initial
; setting in the style run array, rather than synchronizing the
; font to the current keyboard before displaying.
; 8/31/89 smb Fixed TEKey bug: when returning from BufferChar should branch
; signed rather than unsigned. Also fixing bug in SetFont2Keyboard
; to always modify the Rsrved font if it exists. Both fixes for
; bug #51962.
; <2.8> 8/30/89 smb NEEDED FOR 604 Script Systems AND BIG BANG ...(see additional
; comments below dated 7/31/89 - 8/29/89)
; 8/29/89 smb Fixed Roman RL hiliting. Wasn't hiliting correctly for line
; ends. See MeasureWidth. (added to SS-6.0.4 and 7.0 PTCH!)
; 8/25/89 smb Fixed Kanji word dragging bug, #51603, by comparing the char
; offset to the Left anchor and setting the leadingEdgeFlag
; accordingly. (added to SS-6.0.4 and 7.0 PTCH!)
; 8/19/89 smb Fixed another unlocked handle bug. Similar to bug #51602. Made
; d3StyleRun(a6) and d4StyleRun(a6) offsets rather than pointers.
; See OnSameLine. (added to 6.0.4 PTCH!)
; 8/10/89 smb Added one more fix in teKey for arrow keys to work after a
; hit-down on the R. end of a line. (added to 6.0.4 PTCH!)
; 8/8/89 smb Added Gestalt function. (added to 6.0.4 PTCH!)
; 8/7/89 smb Fixed bug #51640 - the hyphenation bug - the right way in
; FindWord. When RecalLines calls FindWord on a Roman system
; should use the old FindWord code. (not added to 6.0.4 PTCH!)
; 8/5/89 smb Fixed multiple cursor bug, #51602 - was saving a ptr to the
; styleRun array in a2StyleRun(a6) (see teGetFormatOrder) when the
; handle to the styleRec wasn't locked! Oh-Dopey-Me! ANY memory
; movement could cause this bug! Fixed in GetNextDisplayStyle,
; DoSearch, TEGetFormatOrder by saving it as an offset, and then
; restoring it to a ptr when I need it. This is just for styled
; text. I save it as a pointer for unstyled text since I create it
; myself (see GetFormatOrdering). (added to 6.0.4 PTCH!) Fixed bug
; #51961 - striking an up/down arrow key after a hitdown at either
; line end caused the caret to display at the opposite end of the
; line rather than the previous line. This bug occurred because
; teKey was inappropriately setting teLftCaret to T. It should
; only be set initially if the key was not a cursor key. (added to
; 6.0.4 PTCH!)
; 8/4/89 smb Fixed Roman line breaking bug, #51677 - must incr to the next
; char posn in StylMeasure when the LeftSide flag from P2C is
; False. RomanFindLine expects the result back to be a LeftSide
; hit, not a rightSide hit! (added to 6.0.4 PTCH!)
; 8/2/89 smb Added SMgr VisibleLength code. (added to 6.0.4 PTCH!)
; 8/1/89 smb In yesterday's fix I had a bug in swapping d2 around a test of
; the CCs. Fixed by saving d2 and restoring it w/ a "movem" which
; won't affect my CCs!
; 7/31/89 smb Fixed an Arabic highlighting bug that occured by having an
; arabic word followed by a long Roman word that forced a
; linewrap. The problem was that code was added to TE's C2P to use
; TextWidth for hit-test on line ends rather than SMgr C2P.
; However, it should still use SMgr C2P for hiliting and it
; wasn't. So, fixed it so it would! (not added to 6.0.4 PTCH!)
; <2.7> 7/25/89 smb NEEDED FOR 604 Script Systems AND BIG BANG É (see comments below
; dated 7/17/89 - 7/24/89)
; 7/24/89 smb ConcatStyles should only be called in DelGuts for a styled
; record. Oops! NOT ADDED TO 604 AURORA PTCH: Cleanup of nEqu.d
; file: renamed nStyle to nStyles, as it should be.
; 7/21/89 smb Added ConcatStyles to DelGuts - when it deletes a style it
; doesn't check to see if the two adjacent styles are the same.
; Found this in Arabic.
; 7/20/89 smb Before using an existing NullStyle in SetFont2Keyboard must make
; sure the font's script is the same as the keyScript. Otherwise,
; use script's default font.
; 7/19/89 smb Fixed Roman FindWord hyphenation bug. Problem was occurring
; because RecalLines used the SMgr-compatible FindWord for
; determining a word boundary but when it called FindLine for the
; line break, FindLine used the oldFindLine code (RomanFindLine)
; which used the old FindWord code. This inconsistency caused
; RecalDraw to only redraw the second line where the word
; following the hyphen was to be displayed. It needed to also
; redraw the first line where the first half of the hyphenated
; word existed. There was also a problem with "where" the second
; part of the hyphenated word was being displayed on the next
; line. Because performance dictated the need to use the old
; FindLine code for Roman systems, we can't easily fix these
; problems. The best and easiest fix for this is to always use the
; old FindWord for all of Roman word breaking needs. Removed code
; from RomanFindLine that said the caller of FindWord was
; RomanFindLine. It's no longer necessary.
; 7/18/89 smb TEInit fix: replaced d1 w/ d3 for WordRedraw determination, and
; fixed loop incremental. Replaced call to AltSetRsrved in
; SetFont2Keyboard to SetRsrved. Changed in v2.2.
; 7/17/89 smb NOT ADDED TO 604 AURORA PTCH: Cleanup of branching in DoMeasure.
; NOT ADDED TO 604 AURORA PTCH: Faster clearing of d0's high word
; in FindLine.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6.0.4 patches and 7.0 ptch0 from here up ;;;;;;;;;;;;;;;;;;;;
; <2.6> 7/13/89 smb NEEDED FOR AURORA! (see comments below dated 7/3/89-7/12/89)
; 7/12/89 smb Misc. cleanup after code review.
; 7/10/89 smb Cleaned up TEFeatureFlag routine, and added another feature bit,
; teFForceScriptFont (to be used in SetFont2Keyboard for Script
; Systems).
; 7/7/89 smb Fixed bugs for Arabic and Kanji.
; 7/5/89 smb Fixed dummy run bug in DupStyle - had fixed in PstStylGuts but
; then I broke inserting a style in the middle of another style,
; and in fixing this discovered an easier fix to the original bug!
; 7/3/89 smb Moved vector initialization above SMgr init code in TEInit in
; order to boot script systems before they are enabled. (They were
; calling TENew, and since vectors weren't initialized it was
; crashing.)
; <2.5> 7/9/89 smb Moved include of ScriptPriv.a back into casm statement! V2.4
; broke my ROM build. Since ROMS and System files are built from
; this file, I had to modify the System patch file for TE instead.
; <2.4> 7/8/89 smb Moved include statement for ScriptPriv.a out of a casm statement
; for Big Bang build.
; <2.3> 6/30/89 smb NEEDED FOR AURORA! Mucho worko accompli! (see comments below
; dated 6/19/89 - 6/30/89)
; 6/30/89 smb Fixed bug in TEInit code for setting wordRedraw in order to use
; on Script Systems.
; 6/29/89 smb Fixed signed/unsigned bugs. Added vectors. Misc. clean up,
; performance improvements, and bug fix.
; 6/24/89 smb Fixed problem of a dummy run being created in DupStyle when only
; one style was being pasted. For more than one style, fixed the
; problem by calling ConcatRuns in teStyleInsert, InsRsrved,
; DelGuts, and PasteGuts. Cleared out ExpandMem space that I use.
; Misc. bug fix and clean up.
; 6/23/89 smb Fixed many direction bugs: teSysJust and wordRedraw problems.
; 6/20/89 smb Fixed Arabic lineEnd bugs in C2P. Was breaking highlighting and
; hitdown.
; 6/19/89 smb Fixed obscure measuring bugs for Arabic in DoMeasure and
; GetWidth. Was breaking display of two adjacent Roman fonts on an
; Arabic SIS w/ RL line direction.
; <2.2> 6/13/89 smb Check-in (see comments below dated 5/30/89-6/12/89)
; 6/12/89 smb Fixed FindLine to work w/ Peter's correct version of
; StyledLineBreak. Fixed script run boundary bug in FindWord.
; Added TEFeatureFlag interface and activated buffering code (was
; casm'd out.
; 6/8/89 smb Fixed RomanFindLine to call the old FindWord code rather than
; the SMgr FindWord code.
; 6/7/89 smb Modified CaretDisplay code for RL text by calling new
; GetDirection rather than GetStyleDirection.
; 6/5/89 smb Finally found the style run bug: problem was caused by
; subtracting two pointers to get a length; one of the pointer had
; the high byte set; fixed by calling StripAddress. Fixed for
; other guilty code!
; 5/30/89 smb Added direction of font to high-order byte of stFace in the
; array of stElements for performance. Also added TEFeatureFlag
; interface for outline highlighting and text buffering.
; <2.1> 5/30/89 smb Check in (see comments below dated 5/16/89-5/23/89)
; 5/23/89 smb Fixing FindWord problems for double-byte text by replacing a
; huge piece of logic with some simple statements for determining
; the leadingEdge flag for SMgr's FindWord. Also fixed some bugs
; in FindLine for MultiScript and Kanji systems.
; 5/17/89 smb Must lock the StScrpHandle for SetStylScrap to work correctly:
; see bug #36986.
; 5/16/89 smb 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.
; <2.0> 5/13/89 smb Added back in mods for v1.8. Also fixed more bugs: see comments
; below dated 5/12/89-5/13/89.
; 5/13/89 smb In TE's P2C had to test if pixelWidth passed in was = to
; TextWidth's result; if so, done. Exit w/o calling SMgr's P2C.
; Fix for bugs #47756,48159.
; 5/12/89 smb Had to save a1 in FindLine before calling GetEnvirons since
; RecalLines depended on it. Also added FindLineRegs to old
; FindLine for this.
; <1.9> 5/5/89 smb Backed out v1.8!
; <1.8> 5/5/89 smb Check in (see comments below dated 5/2/89-5/5/89)
; 5/5/89 smb Added the old FindLine code back in for Roman text: performance
; hit!
; 5/4/89 smb Bug fix in DoSearch: hit-test on line ends wasn't correct for
; Arabic SIS. Fix for HyperCard bug 47857: clicking at the left of
; a line was placing the cursor at the end of the previous line.
; Needed to add a test for CR in order to fix this.
; 5/2/89 smb Changed branch condition after test of teCROnly. Fix for bug
; 39276: changed add operation in TECustomHook from a long op to a
; word op.
; <1.7> 3/29/89 smb Misc. bugs fixed: see comments below dated 3/17/89-3/21/89
; 3/21/89 smb Bug fix: should be a word op and not a long op!
; 3/19/89 smb Bug when number of lines in a teRec is zero, but lineStarts
; array still contains values from previous times. Either first
; two words in array should be zeroed or should always test for
; teNLines(a3) before accessing these words. (in RecalLines)
; 3/17/89 smb Another TEFindLine bug in CRonly mode: branching on exit to the
; wrong label.
; <1.6> 3/15/89 smb Double-byte char fix in BufferText.
; 3/15/89 smb Fixed teCROnly bug in FindLine - was returning one character too
; soon.
; 3/13/89 smb Broke out the common part of TextFrame, SharedFrame, and Cursor
; Frame and created FmtOrderFrame. Bug fix for Cobra II! Left
; cursor key at the beginning of a teRecord wraps to the end of
; the teRecord! Fix in DoubleByte.
; 3/12/89 smb More synch'ing problems: must use nullStyle if it exists in
; SetFont2Keyboard; Also fixed a bug in TeKey for
; SetFont2Keyboard, to use the style of the char previous to the
; selection start/end. This will handle the case of being on a
; format boundary.
; 3/10/89 smb Fixed problem in synch'ing Font 2 Keyboard: needed a pointer to
; ExpandMemRec.emNewFont for SetRsrved.
; 3/6/89 smb Performance enhancements; called FixFormatEnd for problem of
; last style run in record.
; 3/4/89 smb Fixed bug in BufferChar; wasn't saving 1st byte of double byte
; char in the correct place in ExpandMem.
; <1.5> 2/22/89 smb Removed casm flags from code in RangeRect since included all
; configurations!
; <1.4> 2/19/89 smb Removed rom casms (see comment below) and removed extraneous
; routines not being used due to my new code. If needed can back
; up a version or two.
; 2/17/89 smb Removed Rom casms that I added yesterday.
; <1.3> 2/17/89 smb Check in; see comment below.
; 2/16/89 smb Fixed bug in TEInit: reset a0 w/ ExpandMem address after calling
; StripAddress. Also adding Rom casms for pre-Cobra II roms to use
; TE code that's not Script Manager compatible,
; <Not(NuMac|HcMac|MacPP)>. Also fixed bug in TEBufferText,
; although it's code not being used yet.
; <1.2> 2/15/89 SMB Merged System File version with Rom version + added code to make
; TE Script Manager compatible (see non-EASE comments below dated
; 31Aug88SMB and later)
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
;___________________________________________________________________________________________________
; old EASE versions:
; <1.7> 11/2/88 GGD Got rid of machine specific conditionals in favor of feature
; based conditionals.
; <1.6> 10/27/88 PKE added script manager support in teinit.
; <¥1.5> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <1.4> 9/6/88 BBM changed routine names, so they would not conflict with mpw
; includes.
; <1.3> 5/2/88 RWW Fixed last-minute System Tools 6.0 bugs - caretHook was never
; being called, and Pixel2Char was being called directly in one
; place instead of TEHitTestHook.
; <¥1.2> 3/25/88 RWW Fixed bug in iTEGetHeight when no characters in buffer.
; <¥1.1> 3/16/88 RWW Roll-in of System Tools changes
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
;___________________________________________________________________________________________________
; non-EASE/pre-EASE versions:
; 2/13/89 smb Fixed bug in FindLine, where I wasn't adding the finalLength to
; the overall length of the line.
; 2/1/89 smb Modified TeKey for textBuffering, but casm for a later build.
; Also defined new bits in the newTEFlags field (long) in the
; TEDispatchRec: bit 0 = teFAutoScr (already being used as such,
; just made a constant) and bit 1 = teFBuffText. Added ExpandMem
; calls, and removed equates that have been moved to ToolEqu.a.
; Added ExpandMemRec in place of with/endwith pair around all uses
; of ExpandMem fields.
; 1/25/89 smb Modified SMgr calls for MPW 3.0 Equates.
; 1/24/89 smb Fixed a bug in hiliting for unstyled text. Was wiping out my
; fake style run array when I hilited the left end of the line,
; and before I used it for the right end of the line.
; 1/21/89 smb Removed ChkBounds fixes since didn't appear to be working with
; them.
; 1/20/89 smb Modified CursorMovement to remove unneccessary code and to
; branch correctly.
; 1/18/89 smb CodeReview mods: added FreeFmtOrderArray. Modified ChkBounds,
; added R-to-L test for TrimMeasure, and reorganized
; formatOrdering code.
; 12/21/88 smb Fixed teDrawHook bug: at entry, a4 was not the handle to the
; teRecord as documented. Replaced Lo3Bytes code in FindWord with
; _StripAddress. Added code to keep the high caret in view
; (TESelView+) when split cursors occur.
; 12/13/88 smb Modified GetRLPosition routine to correctly display split
; cursors. The rule is to display the high cursor at the script
; run whose direction corresponds to the line direction
; (downstream flow), and the low cursor at the script run whose
; direction is opposite of the line direction (upstream flow).
; 12/9/88 smb Added new conditionals and creating one file for Rom and System
; File builds.
; 12/5/88 smb Modified teHiliteText to work correctly for mixed directional
; text. Must pin not only to style run but also current line. 
; Results from SM HiliteText vary due to line direction; Modified
; PixelWidths to call C2P with the offsets returned. Cleanup all
; this new code for unstyled text. Fixed FindLine bug that caused
; a crash when adding new styles that forced a line wrap.
; 11/29/88 smb Fixed FindLine code to use the correct parameters for script
; changes when calling StyledLineBreak. Added a routine,
; ConcatRuns, to clean up the styleRun array. A null run (not
; entry) was being added to the array the first time a style was
; added to the teRec (this is after the default run is set up.)
; Also fixed a bug in SetOneStyle. Was creating the initial run
; with a length of teLength rather than teLength+1.
; 10/25/88 smb In DoMeasure, changed test for reverse order from TESysJust to
; WordRedraw. Added code for caret positioning. Also synched the
; keyboard to the font and the font to the keyboard.
; 10/25/88 smb Find correct WordRedraw value in TEInit; fixed GetWidth to
; measure with TextWidth when trying to measure a whole line or a
; complete style run, otherwise to measure with Char2Pixel. This
; fixed the problem of the selRect falling outside the right edge
; of the view rectangle when TESysJust is set R->L. (23Sept) Fixed
; the selection problem in Pixel2Char when TESysJust is set R->L.
; Rewrote highlighting code now that I can see the right results
; for display and hiliting. (25Oct) GetFormatOrder was added to
; display style runs correctly on a line.
; 8/31/88 SMB ALTAIR enhancements: changes made to FindLine, FindWord, and
; DoHilite to call SMgr routines to get the job done. Also added a
; new routine GetCurScript to return the current script at a given
; character position for a styled teRec. Renamed routines (by
; adding an 'i' for internal) due to MPW name collisions in the
; rom.
; <S508> 8/2/88 RWW S508 revisited, since it got copied over. Figured out a much
; simpler method of handling the problem (handle being
; dereferenced over a call to InstallIntDispatch which could
; thrash the heap) involving only a one line change - calling
; MyNewHandle instead of _NewHandle.
; 6/27/88 SMB ALTAIR Changes: Incorporate changes to support different script
; systems in order to be SMgr compatible. East Asian support and
; left-dominant Middle Eastern complete. Changes made in:TEInit,
; Pixel2Char, Char2Pixel, TeKey, MeasureIt. Added DoubleByte and
; BufferChar.
; <S425> 3/16/88 RWW Fixed bug in TEContinuousStyle and changed the way it handles
; face attributes
; <PMAB387> 2/10/88 DBG Fixed bug in TEDispose where dispatch vector was not getting
; released for unstyled TE records.
; <PMAB381> 2/4/88 RWW 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
; <C971> 11/4/87 RWW Yanked SetEraseFlag and associated logic. Only bought us about
; 10% - not enough to get excited over. Added TECustomHook to give
; a high end way to stuff new internal dispatch table addresses
; <C971> 11/3/87 RWW 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> 10/30/87 RWW Added some hysteresis to lineStarts hack, to try to prevent some
; heap thrashing from constant SetHandleSize calls
; <C971> 10/29/87 RWW Changed fail test in SetGuts to masking uninteresting bits Added
; doToggle functionality to SetGuts, StyleGuts, SetRsrved,
; CheckMatch
; <C971> 10/28/87 RWW 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> 10/27/87 RWW Changed references to faces to be byte instead of word length
; <C971> 10/26/87 RWW InitRsrved had some strangeness in it Added TESetEraseFlag and
; TEContinuousStyle. Added in code to check for erase flag before
; performing _EraseRect's
; <C971> 10/23/87 RWW Broke out some common code, trying not to reinvent the wheel:
; AnyNullStyle, GetTrueStyle, GetOneStyle Changed GetStylScrap 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 TEGetHeight to properly sort and pin
; start/end Added conditional inclusion of TEDispatch'ed routine
; addresses so I can find them without a Cray
; <C971> 10/22/87 RWW Patched ReCalLines to properly shrink lineStarts array
; <C971> 10/21/87 RWW Added conditional equates to make RAM-based testing easier
; <C971> 10/19/87 RWW Fixed 0 length bug in TEStylInsert
; <C971> 10/12/87 RWW 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.
;
;------------------------------ System 6.0 from here up ----------------------------
;
; <C914> 10/29/87 rwh Port to Modern Victorian
; <C905> 10/13/87 MSH Port to HcMac (Laguna). No color on this machine
; <C858> 6/4/87 MBK Fixed problems of TEStylInsert destroying the StScrpHandle,
; style duplication problem in PstStylGuts, and TEGetPoint
; returning incorrect offset when text ends in CR. Removed
; conditionals around bug fixes.
; <C854> 5/21/87 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 TEGetHeight.
; <C851> 4/27/87 MBK Miscellaneous bug fixes (search on 851 to get more detailed
; descriptions); added code to handle setting styles on null
; selections.
;
; ** BETA 8 from here up **
;
; <C815> 2/13/87 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.
; <C788> 2/11/87 MBK Fixed TEStylInsert to get the input parameters in the correct
; order.
; <C766> 2/5/87 MBK Fixed CopyStyle to lock my style handle before calling PutScrap.
; Fixed DelGuts to relock text handle after munging. Removed call
; to StdEntry from TEStylInsert because TEDispatch does it.
;
; ** BETA 6 from here up **
;
; <C734> 1/30/87 MBK I changed PutStylScrap to TEStylInsert, 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 TEGetHeight to
; subtract 1 from startLine because GetLineHites wants it 0-based.
; SetStylHandle fixed to dispose of old style handle before
; setting new one.
;
; ** BETA 5 from here up **
;
; <C719> 1/29/87 MBK I removed the C717 change to SetHiteAscent. The ptr there was
; not an offset from styleTab, it was an addr on the stack.
; <C717> 1/28/87 MBK Made changes in GetDefStyle, DoDraw, MeasureIt, StylMeasure,
; SetHiteAscent, and SetStyle to protect unlocked pointers from
; memory reallocation. Added startLine and endLine input to
; TEGetHeight. Added RecalDraw to PutStylScrap.
;
; ** BETA 4 from here up **
;
; <C676> 1/23/87 MBK Added GetStylScrap, PutStylScrap, TEGetPoint, and TEGetHeight.
;
; ** BETA 3 from here up **
;
; <C622> 1/13/87 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.
; <C597> 1/6/87 MBK Restore A3 ptr after RGBForeColor call in StdExit, in case TERec
; gets moved.
; <C574> 12/30/86 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.
; <C513> 12/12/86 MBK Changed to clear bit in HiliteMode instead of setting bit in
; pnMode for color hilighting. Fixed selection bug in Pixel2Char.
; <C485> 12/4/86 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).
; <C475> 12/2/86 MBK Set the high bit of the pnMode before highlighting, to use the
; new background color highlighting method.
; <C454> 11/21/86 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.
; <C440> 11/19/86 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.
;
;--------------------------------- ROM 77 from here up ----------------------------
;
; <C393> 11/10/86 MBK Fixed CopyStyle and InsertRecal to reset ptr values after a
; memory allocation call (the ptrs were pointing to trash).
; <C381> 11/8/86 MBK Made all changes resulting from code review.
; <C229> 10/29/86 MBK Fixed 2 register preservation problems. Fixed InsertRecal memory
; overload problem. Redesigned method of updating line heights.
; <C207> 10/16/86 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.
; <C182> 10/6/86 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.
; <C139> 9/10/86 MBK Fixed TEGetStyle 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.
; <C105> 9/3/86 MBK Renamed TEGetStyle to GetStylHandle and TEFindStyle to
; TEGetStyle. Added SetStylHandle. 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 TESetStyle and TEReplaceStyle 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.
; <C95> 8/4/86 MBK Fixed the scrolling problem in SelView; Modified Recallines to
; take into account changes in point size.
; <C94> 7/29/86 MBK Added 3 more traps (TEReplaceStyle, TEGetOffset, TEFindStyle);
; renamed TEGetStyle to TEFindStyle (TEGetStyle now returns the
; style handle); fixed selection bug, the problem was in
; ScanMeasure and DoSearch. Fixed bug in CharByChar. Started
; fixing recalibration problem.
; <C78> 7/17/86 MBK removed equates to an external file; added four new traps
; (TEStylNew, TEStylPaste, TESetStyle, TEGetStyle); 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.
;
;--------------------------------- ROM 76 from here up ----------------------------
;
; 2/19/86 BBM Made some modifications to work under MPW
; 1/14/86? 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
;
;--------------------------------- Lonely Heifer ROMs from here up ----------------------------
;
; 11/5/85 EHB Moved label to make WordRedraw fix work right
; 11/3/85 SC Fixed special case D3=0 in DoCaret
; 11/1/85 EHB If WordRedraw=0->draw normal, if >0 -> draw word, if <0 -> draw
; line
; 10/31/85 EHB Fast TextBox was scanning 0 len strings for CR's
; 10/31/85 EHB In RecalDraw, draw whole words if WordRedraw (new lowMem) is
; TRUE
; 10/30/85 EHB In DoFind, set up D3/D4 with selStart/selEnd before calling
; DoText
; 10/1/85 EHB Set up D2 for all calls to CallBreak (identifies caller)
; 10/1/85 EHB Added hooks for TrimMeasure, FindWord, and FindLine.
; 7/26/85 EHB Added ShowCaret to end of TEPinScroll (needed for null scroll)
; 7/16/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.
; 6/15/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
; 6/15/85 SC DoText must return ThePort in A0 for compatibility
; 6/10/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).
; 6/10/85 SC DoText links a stack frame/DoBye and findDone UNLK
; 6/10/85 SC In rangeRect, stuff the rect.left in TempRect and set pen to
; right for compatibility with old DoText
; 6/10/85 SC DoSearch returns in D0 as before
; 6/7/85 EHB Fast TextBox shouldn't catch zero strings else no
; EraseRect(oops)
; 5/23/85 SC Dropped port save/restore font
; 5/21/85 SC Added negative length to Fast TextBox
; 5/20/85 SC SelView called before caret view in DelGuts and PasteGuts;
; should be after (leaves carets behind in Dialogs)
; 5/20/85 SC CleanupSel saved teTextH flags twice!!
; 5/20/85 SC DoSearch longize D3-D4 (Thanks Bill and Larry)
; 5/20/85 SC Fast TextBox didn't catch zero string length case (oops)
; 5/18/85 SC Made DefClikProc obey autoScroll bit
; 5/18/85 SC LineWidth didn't handle the line past teLength correctly
; 5/18/85 SC Merged LineWidth and TrimMeasure
; 5/18/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)
; 5/18/85 SC New routine PinDisplay replaces pin code in Hilite and Refresh
; 5/18/85 SC Put back DoText funnel for compatibility
; 5/18/85 SC Dropped printable trim in FindLine @ end
; 5/15/85 SC Multiple standard entries with stack peel amount in D1. Does a
; preflight and then escapes if the preflight fails
; 5/13/85 SC Save/Restore text stuff in std entry/exit and made setlinarray
; avoid calling _GethandleSize(done once in stdEntry)
; 5/13/85 SC Added preflight routine to check memory. Called from pasteguts,
; insertGuts, and TextBox. Did similar to TENew
; 5/12/85 SC New local proc MungeSetup to do common munger stuff
; 5/12/85 SC Use D5 in recallines to hold telength
; 5/11/85 SC Added TEAutoView trap to enable/disable the auto scrolling
; 5/11/85 SC Local proc Scroll broken out for use by TEScroll and TEPinScroll
; 5/11/85 SC Use _XMunger instead of _Munger
; 5/11/85 SC Reinstated teSelPoint, it's in documentation
; 5/11/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.
; 5/9/85 SC Made a local CalText proc to avoid StdEntry
; 5/9/85 SC StdEntry/Exit save restore teTextH flags
; 5/9/85 SC Made SelView local proc
; 5/9/85 SC Dropped trim measure black stuff
; 5/9/85 SC teLftClick not a byte, now the tefLeftClk bit in teFlags
; 5/8/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
; 5/8/85 SC Added TEScrollView which insures selection is visible before
; doing something. Called from TEKey, TEPaste, TECut, TEIdle, etc.
; 5/8/85 SC Added default click proc for auto scrolling
; 5/7/85 SC Undo refresh hilite stuff, moved similar stuff to Hilite
; 5/6/85 SC DoFormat had an extra measure for left justify that was not
; needed
; 5/6/85 SC DoText used TempRect, use stack frame instead
; 5/5/85 SC Longized all the 0(A0,DX.L) and call to _TextWidth and _DrawText
; 5/5/85 SC Made StdEntry/Exit use LINK instructions not SP based
; 5/5/85 SC Fixed up recalLines to reduce flashiness
; 5/5/85 SC Dropped teSelPoint usage, get off stack frame instead of
; TeHandle
; 5/5/85 SC Tricks played with A0 and teCarOn, teCarAct in DrawCaret,
; cleaned up for readability.
; 5/5/85 SC TESetSelect trashed teSelPoint, cleaned up code a bit
; 5/4/85 SC SkipLoop in TrimMeasure could go negative
; 5/4/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
; 5/4/85 SC Changed D2 usage in TEClick to D5 long sign bit
; 5/3/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.
; 5/3/85 SC Dropped forROM and for44T compile switches for readability
; 5/3/85 SC New version of FindLine, cleaner and fixes bugs. Still
; inefficient because it measures whole line repeatedly, but
; faster quickdraw fixes this.
; 5/3/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
; 1/25/85 EHB Fixed Refresh to only hilight visible part of selection
; 1/25/85 EHB Added Capp's TextBox fix
; 1/24/85 EHB Added patch in RecalDraw
; 1/23/85 LAK Adapted for new equate files.
; 1/16/85 EHB Fixed center/right justify in TextBox fix
;
;-----------------------------------------------------------------------
;
; 9/12/83 Made InvertHook push the rectangle
; 9/9/83 Fixed caret activate problem w/ inactive records Dropped
; background stuff(Finally gave up) Added global word break for
; Europe.
; 9/4/83 Fixed First char select bug in DoText
; 8/25/83 Fixed Insert D7 bug
; 8/25/83 Fixed unwind bug in stdexit
; 8/21/83 Added DoText and recal hooks
; 8/19/83 Added system double/caret times
; 8/17/83 Fixed Rony bug in RecalDraw
; 8/8/83 Dropped pinrects and used extended rects in DoText to save code
; 8/7/83 Reinstated total dobackgnd from recal(FUCK!)
; 8/6/83 Dropped total dobackgnd from recal(I guess addition IS
; communitive)
; 8/5/83 Fixed a bug in FindLine Fixed bug in Recaline (now waits for
; whole text to finish) Optimized dobackgnd to always stop at end
; 8/3/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
; 8/2/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
; 7/23/83 New Today
;
;<<<END HISTORY>>> <- This is to make the end of these comments easy to find with MPW.
;___________________________________________________________________________________________________
; To Do:
; Remove extraneous code from NewRomanFindLine. Marked with (XX).
; There may be a measuring bug using TextWidth, due to StdTxMeas' use of pnLoc. TE doesn't seem to
; initialize the pnLoc to 0 before it measures w/ TextWidth.
;___________________________________________________________________________________________________
; Useful MPW commands
;
; '/<RWW[0-9]Ç6È>[ÂNO]/'
;
;Set teversion 'SMgrTE';Export teversion
;Delete -i "{SystemFolder}TEPatcher"
;rez -o "{SystemFolder}TEPatcher" "{RIncludes}"Types.r TEPatcher.r
;SetFile "{SystemFolder}TEPatcher" -t INIT -c tept -a B
; Set opt "-d OnNuMac=0,OnMvMac=0,OnMacPP=0,OnHcMac=0,forR0M=0"
;Asm {opt} TEPatcher.a -o TEPatcher.a.o -d &RWWDebug -i {MyIncludes}
;link -rt INIT=0 -o "{SystemFolder}TEPatcher" TEPatcher.a.o ShowINIT.a.o
;___________________________________________________________________________________________________
Blanks On
String AsIs
If &TYPE('&RWWDebug') = 'UNDEFINED' Then
If &TYPE('InsideTEPatch') = 'UNDEFINED' Then ; <S383>
LOAD 'StandardEqu.d'
INCLUDE 'ScriptPriv.a'
INCLUDE 'TextEditPriv.a' ; <1/9/90smb>
INCLUDE 'fontPrivate.a' ; <20>
EndIf ; <S383>
EndIf
IF &TYPE('Scripts604') = 'UNDEFINED' THEN
Scripts604 EQU 0
ENDIF
IF &TYPE('SysVers') = 'UNDEFINED' THEN
SysVers EQU 0
ENDIF
IF &TYPE('forLocalizability') = 'UNDEFINED' THEN ; <32>
forLocalizability EQU 1 ; <32>
ENDIF ; <32>
INCLUDE 'GestaltEqu.a' ; <18Aug89smb>
; *************************************************************************************************
; *************************************************************************************************
; *************************************************************************************************
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
; exported for debugging use
Export DoMeasure
Export MeasureIt
Export HideCaret
Export DoFind
Export DoCaret
Export DoText
Export DoHilite
Export DoSearch
Export RangeRect
Export PrepLine
Export LineRect
Export xGetWidth
Export xteGetFormatOrder
Export xDoErase
Export DoDraw
Export ChkBounds
Export xCaretDisplay
Export xGetRLPosition
Export xOnSameLine
Export iTESetStyle
Export xSetKeyboard2Font
Export xSetFont2Keyboard
Export xCursorMovement
Export xTEBufferText
Export xDumpBuffer
Export iTEFeatureFlag
Export xConcatRuns ; <11>
Export xStyleGuts ; <11>
Export xBufferChar ; <11>
Export xTestRunDirection ; <11>
Export xPixelWidths ; <11>
Export xInvrtRectangle ; <11>
Export xHiliteLineEnds ; <11>
Export xMeasureWholeRun ; <11>
Export xMeasureWidth ; <11>
Export xGetCurScript ; <11>
Export xGetStylesInOrder ; <11>
Export xGetDirection ; <11>
Export xSetDirection ; <11>
Export xCaretInsideRun ; <11>
Export xOnLineEnd ; <11>
Export xGetLRPosition ; <11>
; hooks to be stored in the trap table
Export XTrimMeasure
Export XFindWord
Export XFindLine
Export XReCalLines
Export vPixel2Char
Export vChar2Pixel
; sets up vectors to be used for patching TextEdit and clears ExpandMem TE globals <28June89smb>
Export TEGlobalInit ; <13>
;-------------------------------------------------------------------------------------------------
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
DC.W iTEFeatureFlag-AddrTable ; 14
DC.W NewTextEditEntryPoint-AddrTable ; 15
;-------------------------------------------------------------------------------------------------
; Add new vectors <28June89smb>
; EMVectorTable contains the offset in ExpandMemRec which holds the routine address
; and the offset to the routine from here.
EMVectorTable
with ExpandMemRec
dc.w vDoErase, xDoErase-EMVectorTable
dc.w vCaretDisplay, xCaretDisplay-EMVectorTable
dc.w vGetLRPosition, xGetLRPosition-EMVectorTable
dc.w vGetRLPosition, xGetRLPosition-EMVectorTable
dc.w vOnLineEnd, xOnLineEnd-EMVectorTable
dc.w vCaretInsideRun, xCaretInsideRun-EMVectorTable
dc.w vSetDirection, xSetDirection-EMVectorTable
dc.w vGetDirection, xGetDirection-EMVectorTable
dc.w vGetStylesInOrder, xGetStylesInOrder-EMVectorTable
dc.w vteGetFormatOrder, xteGetFormatOrder-EMVectorTable
dc.w vGetWidth, xGetWidth-EMVectorTable
dc.w vGetCurScript, xGetCurScript-EMVectorTable
dc.w vOnSameLine, xOnSameLine-EMVectorTable
dc.w vMeasureWidth, xMeasureWidth-EMVectorTable
dc.w vMeasureWholeRun, xMeasureWholeRun-EMVectorTable
dc.w vHiliteLineEnds, xHiliteLineEnds-EMVectorTable
dc.w vInvrtRectangle, xInvrtRectangle-EMVectorTable
dc.w vPixelWidths, xPixelWidths-EMVectorTable
dc.w vTEBufferText, xTEBufferText-EMVectorTable
dc.w vDumpBuffer, xDumpBuffer-EMVectorTable
dc.w vCursorMovement, xCursorMovement-EMVectorTable
dc.w vTestRunDirection, xTestRunDirection-EMVectorTable
dc.w vBufferChar, xBufferChar-EMVectorTable
dc.w vSetFont2Keyboard, xSetFont2Keyboard-EMVectorTable
dc.w vSetKeyboard2Font, xSetKeyboard2Font-EMVectorTable
dc.w vStyleGuts, xStyleGuts-EMVectorTable
dc.w vConcatRuns, xConcatRuns-EMVectorTable
dc.w 0,0
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEGlobalInit
; <27June89smb>
;
; To be called from StartInit, in order to assign vectors
; and clear expandMem globals only once.
;
;----------------------------------------------------------------------
TEGlobalInit
movem.l a2/a3,-(sp)
; <SM8>
Lea XDoText,A0 ; set up doText hook <SM8>
Move.L A0,TEDoText ; <SM8>
Lea XReCalLines,A0 ; set up recal hook <SM8>
Move.L A0,TERecal ; <SM8>
Lea DefWordBrk,A0 ; get default word break <SM8>
Move.L A0,TEWdBreak ; <SM8>
; <SM8>
; initialize expandMem with my TE vectors
lea EMVectorTable,a0 ; base address of vector table
move.l a0,a1
move.l ExpandMem,a2 ; get pointer to expandMem
VectorLoop
move.l (a1)+,d0 ; get routine offset from EMVectorTable
beq.s LoopXit
lea 0(a0,d0.w),a3 ; get routine address
swap d0 ; get expandMem offset (vector place holder)
move.l a3,0(a2,d0.w) ; load into expandMem
bra.s VectorLoop
LoopXit
movem.l (sp)+,a2/a3
rts
;----------------------------------------------------------------------
;
; 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
IF 0 THEN
;IF &TYPE('&SMgrINIT') <> 'UNDEFINED' THEN ;<1Feb89smb> added for Init testing of ExpandMem
; only necessary for Init's before Cobra II and 6.0.4.
ENDIF
; Defensive reset in case an application changed teSysJust contrary to system default.
;
; Now, we just reset it for Roman-only systems (because TE in such a system cannot currently <32>
; handle R-L direction; we will fix this eventually). For other scripts, the Text Control <32>
; Panel lets users choose the default line direction, so we don't want to override it. <32>
WITH smgrRecord,scriptRecord
GetSMgrCore a0 ; load SMgr globals pointer.
IF 1 THEN ; <32>
move.b smgrEnabled(a0),d0 ; how many scripts enabled? <32>
ble.s @bail ; if 0 (or neg!), can't initialize <32>
subq.b #1,d0 ; Roman-only? <32>
bne.s @doneSetSysJust ; if not, don't reset <32>
clr.w TESysJust ; Roman-only, force to L-R (else TE screws up) <32>
@doneSetSysJust ; <32>
ELSE ; (keep old code for reference for a while) <32>
tst.b smgrEnabled(a0) ; script manager disabled?
beq.s @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.
ENDIF ; <32>
endWith ;
;<2Feb89smb>
; initialize NewStyle params for SetRsrved call in SetFont2Keyboard (flag.b, textStylePtr.l, mode.w)
move.l ExpandMem,a0
lea ExpandMemRec.emNewStyle(a0),a0 ; changed from add to lea <12July89smb>
move.b #$FF,(a0) ; flag.b
move.w #1,6(a0) ; mode.w
; Find correct WordDraw value. Used for redrawing for line calculation
; after character input. A WordDraw value of:
; 0 = redraw the char in front of the inputted char,
; 1 = redraw the word in front of the inputted char,
; FF = redraw the whole line.
; To set the correct value walk through the scripts (32 of them!),
; <OR> in 1 for each double-byte script and <OR> in FF for each right-left script.
move.b #0,WordRedraw ; default case
move.l d3,-(sp) ; save <18July89smb>
moveq #0,d3 ; init d3; for d3 := 0 to 32 do
@WordRedrawLoop
clr.l -(sp) ; allocate return
move.w d3,-(sp) ; script number
move.w #smScriptRedraw,-(sp) ; verb
_GetScript ; if disabled, will return zero.
move.l (sp)+,d0 ; values are 0, 1, FF
or.b d0,WordRedraw ; add it in: 1 ++ x, FF ++ x
; if all FFs, then dont need to go further-so check for negative
bmi.s @WRLoopXit
addq.w #1,d3 ; next script to check <18July89smb>
cmpi.w #32,d3 ; beyond last script? <18July89smb>
bls.s @WordRedrawLoop ; keep going until done w/ scripts
@WRLoopXit
move.l (sp)+,d3 ; restore <18July89smb>
; Get number of scripts installed <9Nov88smb>
clr.l -(sp)
move.w #smEnabled,-(sp) ; verb
_GetEnvirons
move.l (sp)+,d0
move.l ExpandMem,a0 ; <1Feb89smb>
move.b d0,ExpandMemRec.emScriptsInstalled(a0) ; total number of installed scripts
; guarantee default WordBreak address is 32-bit clean <21Dec88smb>
lea DefWordBrk,a1
move.l a1,d0
_StripAddress
move.l ExpandMem,a0 ; <16Feb89smb> StripAddress wipes out a0!
move.l d0,ExpandMemRec.emCleanWordBrk(a0)
@bail
Rts
ErrorXit
_SysError
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION TEGetText( h: TEHandle ): Handle;
;
; Returns the text handle
;
;----------------------------------------------------------------------
TEGetText
Bsr StdEntry
Move.L teTextH(A3),(A2) ; return the text handle
Bra epilog4
;formFeed
;----------------------------------------------------------------------
;
; 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
; dump text buffer before exiting (cleanup!) <21>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops <21>
btst #teFTextBuffering,d0
beq.s @noBuffer
bsr DumpBuffer ; dump text from buffer
@noBuffer
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 TESetStyle. 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TextBox( Text: Ptr; Length: LONGINT; r: Rect; style: INTEGER );
; 18 14 10 8
;
;moved following equates to TextEditPriv.a <18>
;TBJust Equ 8
;TBBox Equ 10
;TBLength Equ 14
;TBText Equ 18
;----------------------------------------------------------------------
;TETextBox ; comment out for now <45>
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>
IF NOT forLocalizability THEN ; <39-YDS-1/30/92> don't set to 0 for #teForceLeft !!!
@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>
ELSE
@05
ENDIF
; 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 tbExit ; escape if illegal string <C971/RWW102887>NO
Beq.S NoZeroScan ; => don't scan NIL strings <EHB 31-Oct-85>
@0
Cmp.B #returnChar,(A0)+
Beq 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.W UseRealOne
Move.L A0,-(SP) ; erase the rect
_EraseRect
SubQ #8,SP
Move.L SP,-(SP)
_GetFontInfo
IF forLocalizability THEN ; see <41> <41-YDS-2/6/92>.we are in
; an un styled record, give the hight of the assoc
; font or the script font (the bigger)
Subq #2,sp ; make room on stack
_FontScript ; get the script
Move.W (SP)+, D4 ; into D4
Beq.W @DoNothing ; it roman ! do nothing
Subq #4,sp ; make room on stack, will use it later
Move.W D4, -(SP) ; push script number on stack for later
Move.L GrafGlobals(A5),A3 ; get graf globals and then thePort
Move.L thePort(A3),A3 ;
Move.W txFont(A3),D5 ; get the font face <42-YDS-4/2/92>
Cmp.W #sysFont, D5 ; is it system font ?
Beq.S @SystemFont ; yes
Cmp.W #applFont, D5 ; is it app font ?
Beq.S @AppFont ; yes
Subq #4,sp ; make room on stack for result
Move.W D4, -(SP) ; push script # on stack
Move.W #smScriptSysFond, -(SP) ; push verb
_GetScript ; get the system pref fond id
Move.L (SP)+, D0 ; take result font
Cmp.W D5, D0 ; are you sure it's not system font ?
Beq.S @SystemFont ; it is !
Subq #4,sp ; make room on stack for result
Move.W D4, -(SP) ; push script # on stack
Move.W #smScriptAppFond, -(SP) ; push verb
_GetScript ; get the application pref fond id
Move.L (SP)+, D0 ; take result font
Cmp.W D5, D0 ; are you sure it's not application font ?
Beq.S @AppFont ; it is !
@OtherFont Move.W #smScriptFntBase ,-(SP) ; we have result space & script # on stack allready
Bra.S @GetTheFont ; so push the right verb
@SystemFont Move.W #smScriptSysBase ,-(SP) ; we have result space & script # on stack allready
Bra.S @GetTheFont ; so push the right verb
@AppFont Move.W #smScriptAppBase ,-(SP) ; we have result space & script # on stack allready
@GetTheFont _GetScript ; so push the right verb
Move.L (SP)+, D0 ; get the associated font
Tst.W D0 ; we have to test, since only the word counts <42-YDS-4/2/92>
Beq.S @DoNothing ; no associated font ? bail out !
Move.W D0, txFont(A3) ; set the font to the assoc font
SubQ #8,SP ; space on stack
Move.L SP,-(SP) ; push addres
_GetFontInfo ; get the assoc font info
Move.W D5, txFont(A3) ; restore port font
Move.W (SP), D0 ; get assoc font ascent
Cmp.W 8(SP), D0 ; compare with script font ascent
Bgt.S @3 ; used to be '@1' by mistake <43-YDS-4/19/92>
Move.W D0, 8(SP) ; let the bigger one win !
@3 AddQ #8,SP ; strip stack
@DoNothing
ENDIF
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
Beq.S @2 ; if left go do it
IF forLocalizability THEN ; <39-YDS-1/30/92> don't forget to check
Cmp.W #teForceLeft,TBJust(A6) ; for #teForceLeft (if we had 0, we had set
Beq.S @2 ; it allready to system justification)
ENDIF
; 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
;----------------------------------------------- <22>
; Turn PreserveGlyph off before drawing, but save its previous setting <22>
clr.w -(sp) ; boolean result <22>
_GetPreserveGlyph ; <22>
; leave result on stack
tst.w (sp) ; preserve or squash? (byte result but cleared word)
beq.s @IsFalse ; <22>
move.b #0,-(sp) ; set PreserveGlyph FALSE <22>
_SetPreserveGlyph ; <22>
@IsFalse
;----------------------------------------------- <22>
Move.L TBText(A6),-(SP) ; pass text
Clr -(SP)
Move TBLength+2(A6),-(SP) ; pass length (low word)
_DrawText
;----------------------------------------------- <22>
; Restore PreserveGlyph
; previous PreserveGlyph value still on stack
_SetPreserveGlyph ; <22>
;----------------------------------------------- <22>
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
;formFeed
;----------------------------------------------------------------------
;
; 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
addq.w #1,d0 ; increment for dummy character <23Nov88smb>
Bsr.S GetDefStyle ; store default style in StyleRec <C971/RWW102887>NO
@0 Rts
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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 STElements <24July89smb> changed to nStyles
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 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
; set the direction of the font in the high bit of the high-order byte <30May89smb>
move.l a0,-(sp)
move.w stFont(a0),d1
lea stFace+1(a0),a0
Bsr SetDirection
move.l (sp)+,a0
Move.W txSize(A1),stSize(A0) ; save the size
Pea stColor(A0) ; place to store color ** <C182/6oct86/MBK> **
If NOT ForROM THEN ; <9Dec88smb>
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 hasCQD THEN ; <9Dec88smb>
_GetForeColor ; for Ikki ** <C182/6oct86/MBK> **
Else
Bsr GetForeColor ; for Alladin ** <C182/6oct86/MBK> **
EndIf
Rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE GetSize
;
; ** <C207/10oct86/MBK> **
;
; Get ascent and line height from current font.
;
; Exit:
; D0: ascent
; D1: line height (= ascent + 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
IF forLocalizability THEN ; see <41> <41-YDS-2/6/92>.if we are in
; an un styled record, give the hight of the assoc
; font or the script font (the bigger)
Tst.W teSize(a3) ; is it styled ?
Bmi.W @NoAssocFont ; if yes, don't do anything
Move.L D3, -(SP) ; save d3 on stack for now
Subq #2,sp ; make room on stack
_FontScript ; get the script
Move.W (SP)+, D3 ; into D3
Beq.W @DoNothing ; it roman ! do nothing
Subq #4,sp ; make room on stack, will use it later
Move.W D3, -(SP) ; push script number on stack for later
Cmp.W #sysFont, teFont(A3) ; is it system font ?
Beq.S @SystemFont ; yes
Cmp.W #applFont, teFont(A3) ; is it app font ?
Beq.S @AppFont ; yes
Subq #4,sp ; make room on stack for result
Move.W D3, -(SP) ; push script # on stack
Move.W #smScriptSysFond, -(SP) ; push verb
_GetScript ; get the system pref fond id
Move.L (SP)+, D0 ; take result font
Cmp.W teFont(A3), D0 ; are you sure it's not system font ?
Beq.S @SystemFont ; it is !
Subq #4,sp ; make room on stack for result
Move.W D3, -(SP) ; push script # on stack
Move.W #smScriptAppFond, -(SP) ; push verb
_GetScript ; get the application pref fond id
Move.L (SP)+, D0 ; take result font
Cmp.W teFont(A3), D0 ; are you sure it's not application font ?
Beq.S @AppFont ; it is !
@OtherFont Move.W #smScriptFntBase ,-(SP) ; we have result space & script # on stack allready
Bra.S @GetTheFont ; so push the right verb
@SystemFont Move.W #smScriptSysBase ,-(SP) ; we have result space & script # on stack allready
Bra.S @GetTheFont ; so push the right verb
@AppFont Move.W #smScriptAppBase ,-(SP) ; we have result space & script # on stack allready
@GetTheFont _GetScript ; so push the right verb
Move.L (SP)+, D0 ; get the associated font
Tst.W D0 ; test the low word <42-YDS-4/2/92>
Beq.S @DoNothing ; no associated font ? bail out !
Move.L (SP)+, D3 ; restore D3, we need a fresh stack
Move.L teGrafPort(A3),A0 ; get thePort
Move.W D0, txFont(A0) ; set the font to the assoc font
SubQ #8,SP ; space on stack
Move.L SP,-(SP) ; push addres
_GetFontInfo ; get the assoc font info
Move.L teGrafPort(A3),A0 ; get the port
Move.W teFont(A3),txFont(A0) ; restore the font
Move.W (SP)+, D0 ; get assoc font ascent
Cmp.W 6(SP), D0 ; compare with script font ascent
Bgt.S @1
Move.W D0, 6(SP) ; let the bigger one win !
@1 Move.W (SP)+, D0 ; get assoc font descent
Cmp.W 6(SP), D0 ; compare with script font ascent
Bgt.S @2
Move.W D0, 6(SP) ; let the bigger one win !
@2 AddQ #2,SP ; skip max wid
Move.W (SP)+, D0 ; get assoc font leading
Cmp.W 6(SP), D0 ; compare with script font ascent
Bgt.S @3
Move.W D0, 6(SP) ; let the bigger one win !
@3 Bra.S @NoAssocFont ; back to normal !
@DoNothing
Move.L (SP)+, D3 ; restore D3,
@NoAssocFont
ENDIF
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
;formFeed
;----------------------------------------------------------------------
;
; 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 NOT ForROM THEN ; <9Dec88smb>
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 hasCQD THEN ; <9Dec88smb>
_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)
;formFeed
;----------------------------------------------------------------------
;
; 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
; set the current font in the grafort so can synch the keyboard to the font <10Nov88smb>
tst.w teSize(a3) ; if unstyled, can't synch keyboard to font <1Dec88smb>
bpl.s @NoSynch
move.w teSelStart(a3),d0
beq.s @BufferStart ; <6Dec89smb>
sub.w #1,d0 ; backup one to get previous style <6Dec89smb>
@BufferStart
move.w d0,d3 ; save offset position <6Dec89smb>
bsr GetCurStyle
bsr SetStyle
move.w d3,d0 ; <6Dec89smb>
IF hasInlineInput THEN ; <16>
; if inline input is on then don't unsynchronize the keyboard! <16>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d1 ; move into reg for modulo 32 bit ops
btst #teFInlineInput,d1 ; is this Inline Input feature desired?
bne.s @NoSynch ; yes, so don't unsynch!
ENDIF ; <16>
bsr ClickKeyboard2Font ; <3Dec89smb>
;; Bsr SetKeyboard2Font ; synch keyboard to font <10Nov88smb>
@NoSynch
Bsr ShowCaret
Bsr HiLite
Bsr SelView ; insure selection is visible
Bra go12
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION TENew{ ( destRect, viewRect: Rect ): TEHandle };
;
; Called when creating an unstyled TERecord.
;----------------------------------------------------------------------
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
; set the direction of the font in the high bit of the high-order byte <30May89smb>
move.l a0,-(sp) ; save
move.w teFontStuff(a3),d1 ; font
lea teFace+1(a3),a0 ; store direction here
Bsr SetDirection
move.l (sp)+,a0
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
MoveQ #8,D0
Bra Std2Exit ; <C971/RWW102887>NO
;formFeed
;----------------------------------------------------------------------
;
; 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 TESetStyle. 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
;formFeed
;----------------------------------------------------------------------
;
; 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)
;;<2/8/90smb> Lea Char2Pixel,A1
lea OldChar2Pixel,a1 ; install old routine here <2/8/90smb>
move.l a1,WIDTHHook(a0)
lea Pixel2Char,a1 ; <C971/RWW111887>
move.l a1,HITTESTHook(a0) ; <C971/RWW111887>
clr.l newTEFlags(a0) ; <PMAB381/RWW020488>
clr.l newTEFlags+4(a0) ; <1/9/90smb> storage for double-byte char
; added for SMgr's C2P interface <2/8/90smb>
lea Char2Pixel,a1 ; install SMgr-compatible routine here <2/8/90smb>
move.l a1,nWIDTHHook(a0) ; <2/8/90smb>
IF hasTextWidthHook THEN ; <17>
; added so developers can hook the TextWidth calls in TextEdit <18>
lea OldChar2Pixel,a1 ; install TextWidth routine as the default for the hook <18>
move.l a1,TextWidthHook(a0) ; <18>
ENDIF ; <17>
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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.
;
;----------------------------------------------------------------------
;TEStyleNew ; comment out for now <45>
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 InstallIntDispatch ; install new internal dispatch tbl <C971/RWW110387>
Bsr.S InitRsrved ; init reserved handle
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
MoveQ #8,D0
Bra Std2Exit ; <C971/RWW102887>NO
;formFeed
;----------------------------------------------------------------------
;
; 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 TESetStyle. 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEUpdate( r: Rect; h: TEHandle )
;
; Redraws the entire object sected by r
;
;----------------------------------------------------------------------
TEUpdate
Bsr StdEntry
Move.L (A2)+,A0 ; get rect
Bsr Refresh
; if window is active, don't bother with outlining. <16Oct89smb>
tst.b teActive(a3)
beq.s @TestOutline
Bra epilog8
@TestOutline
; if outlining is on, redraw outline! <16Oct89smb>
with OutlineFrame
link a6,#OutlineFrameSz ; only link if outlining
move teSelStart(a3),d0 ; is this a selection point?
cmp teSelEnd(a3),d0
bne.s @drawRegion ; fall through for caret processing
; is outlining desired?
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFOutlineHilite,d0
beq.s @drawRegion ; outline bit not on
; if caret on invert it
tst.b teCarOn(a3)
beq.s @noDraw
bsr DrawIt
@noDraw
; turn on flag in case off - want to display an outlined caret
st teCarOn(a3) ; will be turned off in HideCaret
@drawRegion
bsr InitOutline
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFOutlineHilite,d0
beq.s @noOutline ; outline bit not on
st teActive(a3) ; flag as active for hiliting
bsr HideCaret ; hide the caret
bsr.s HiLite ; Frame new region
sf teActive(a3) ; flag as inactive
sf paintFlag(a6) ; don't paint region!
bsr TEOutlineHilite
@noOutline
unlk a6
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
;formFeed
;----------------------------------------------------------------------
;
; 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 #teHighlight,D7 ; set mark mode
Bra DoText ; Remove old selection
;formFeed
;----------------------------------------------------------------------
;
; 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 (bad! bad! bad!) <27>
; a4 teHandle across other TE routines <27>
; 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
add.l d0,teClikTime(a3) ; Update click time for click proc. <4>
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
; synch the keyboard to the font <10Nov88smb>
tst.w teSize(a3) ; if unstyled, try synch keyboard even if we don't
IF forLocalizability THEN ; have all info <31g-YDS-8/27/91>
bmi.w @Styled ; styles !!!
tst.w teLength(A3) ; do we have text at all ?
beq.w @NoSynch ; don't synch if no text !!!
IF 0 THEN ; now using 'itlb' flag in CubeE <45>
; 6.1 : synch only r->l, for 7.0 synch for double byte
;; tst.b WordRedraw ; is it a R->L script ? <34>
;; bge.w @NoSynch ; don't synch. <34>
; Really want to synchronize for unstyled text in ALL scripts. However, this will cause problems for <34>
; input methods, so we will skip this code in this case. (WordRedraw only indicates the <34>
; types of scripts installed and not the current oneÉ) <34>
subq #2,sp ; result space for Font2Script & GetScript <34>
move.w teFont(a3),-(sp) ; app font id <34>
_Font2Script ; it's a non-roman char so get script font <34>
move.w (sp)+,d0 ; <34>
beq @UseFont ; if Roman then always synchronize <34>
cmp.w #smEastEurRoman,d0 ; Extended Roman? <38>
beq @NoSynch ; If so, never synchronize <38>
subq #4,sp ; result space <34>
move.w d0,-(sp) ; script <34>
move.w #smScriptRedraw,-(sp) ; <34>
_GetScript ; <34>
move.l (sp)+,d1 ; <34><37>
tst.b d1 ; leave in d1 for later <34><37>
bgt @NoSynch ; if double-byte script don't synchronize <34>
; otherwise, we have a single-byte non-Roman font <34>
; IF SysVers > $610 THEN
; move.l teDispatchH(a3),a0 ;
; move.l (a0),a0
; move.l newTEFlags(a0),d0 ; move into reg the flags
; btst #teFInlineInput,d0 ; are we in an inline input window ?
; bne.w @NoSynch ; yes, don't synch keyboard.
; ENDIF
ELSE ; now using 'itlb' flag in CubeE <45>
; optimize for Roman-only: do not have to synch font & kbd <50>
with smgrRecord ; <50>
GetSMgrCore a0 ; load SMgr globals pointer. <50>
cmp.b #1,smgrEnabled(a0) ; how many scripts enabled? <50>
beq @NoSynch ; skip synchronization for Roman-only system <50>
endwith ; <50>
subq #6,sp ; result space for Font2Script & GetScript <45>
move.w teFont(a3),-(sp) ; app font id <45>
_Font2Script ; get script font <45>
; script left on stack ; <45>
move.w #smScriptFlags,-(sp) ; now get script-specific flags <45>
_GetScript ; <45>
move.l (sp)+,d0 ; <45>
and.l #(1<<smsfSynchUnstyledTE),d0 ; leave only the synchronize bit <45>
beq @NoSynch ; 0=> do not synchronize <45>
; otherwise synchronize
ENDIF ; now using 'itlb' flag in CubeE <45>
move.w d6,d3 ; don't trash d6
tst.b teLftClick(a3) ; check if the click was on the previos char.
bne.s @2 ; else sub 1
sub.w #1,d3 ; see the char we clicked (from 0 !!!)
@2
; Check char to determine how to synch
move.l teTextH(a3),a2 ; handle to text <37>
move.l (a2),a0 ; ptr to text <37>
move.b 0(a0,d3.w),d0 ; get character <37>
cmp.b #$20,d0 ; control char? <37>
blo @NoSynch ; if so, don't synch <37>
move.b d1,-(sp) ; save scriptRedraw <37>
subq #2,sp ; room for return
move.l a0,-(sp) ; push text ptr on stack <37>
move.w d3,-(sp) ; offset on stack
_CharType ; what char is it
move.w (sp)+,d0 ; take result
move.b (sp)+,d1 ; recover scriptRedraw <37>
; Mask off what interested in: the Type ($000F) and the Direction ($2000) <34>
; Want a char whose Direction is LR (smCharLeft, $0000) and whose Type is Roman letter <34>
; which can be smCharAscii (1) or smCharEuro (7) or smCharPunct (0). <34>
;
; New approach. Different behavior for bidi and non-bidi scripts, because of caret <37>
; requirements for bidi scripts. <37>
bne.s @doBidi ; check scriptRedraw for bidi <37>
; For non-bidirectional scripts, set keyboard to Roman for Roman letters, <37>
; sync to font for script letters, dont sync for anything else. <37>
and.w #smcTypeMask,d0 ; isolate info we need <37>
cmp.w #smCharPunct,d0 ; non-letter? <37>
beq.s @NoSynch ; if so, don't synch keyboard <37>
cmp.w #smCharAscii,d0 ; low-ASCII Roman? <37>
beq.s @isRoman ; if so, go set keyboard <37>
cmp.w #smCharEuro,d0 ; Extended ASCII Roman? <37>
beq.s @isRoman ; if so, go set keyboard <37>
bra.s @UseFont ; otherwise, sync keyboard to font <37>
; For bidirectional scripts, don't synch control chars (stripped out above) or low-ASCII <37>
; (L-R) digits; synch other L-R chars to Roman, and everything else to font script. <37>
@doBidi ; <37>
and.w #smcTypeMask+smcClassMask+smcRightMask,d0 ; isolate info we need <37>
cmp.w #smCharPunct+smPunctNumber+smCharLeft,d0 ; is char a low-ASCII digit? <37>
beq.s @NoSynch ; if so, don't synch <37>
and.w #smcRightMask,d0 ; now just check direction <37>
beq.s @isRoman ; if left-right, sync to Roman <37>
; Otherwise, synch the font to the script of the character <34>
@UseFont
subq #2,sp ; room for return
move.w teFont(a3),-(sp) ; app font id
_Font2Script ; it's a non-roman char so get script font
; leave script on stack
bra.s @SetKbd
@isRoman move.w #smRoman,-(sp) ; we think it is roman
@SetKbd
move.w (sp), d0 ; script param on the stack
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0 ;
move.b d0, lastScript(a0) ; push script number used to highlight (d0) to lastScript
_KeyScript ; set keyboard
bra.s @NoSynch
ELSE
bpl.s @NoSynch
ENDIF
@Styled move.w d6,d0
beq.s @BufferStart ; <6Dec89smb>
IF forLocalizability THEN ; <31e-YDS-8/27/91>
tst.b WordRedraw ; do we have a R->L script
bge.s @BufferStart ; no, take the prev allways
tst.b teLftClick(a3) ; check if the click was on the previos char.
bne.s @BufferStart ; else sub 1;
ENDIF
sub.w #1,d0 ; backup one to get previous style <6Dec89smb>
@BufferStart
move.w d0,d3 ; save offset position <6Dec89smb>
bsr GetCurStyle ; returns ptr to current style in a0
bsr SetStyle ; set the font in the grafport
move.w d3,d0 ; char offset needed in ClickKeyboard2Font <6Dec89smb>
bsr ClickKeyboard2Font ; sink up! <3Dec89smb>
;; bsr SetKeyboard2Font ; sink up!
@NoSynch
; 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.
move.l a4,-(sp) ; preserve teHandle for hook calls <27>
; <27>
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
; a4 ok here due to bra to this point <27>
Bsr HiLite ; Remove old selection
MoveQ #teWordSelect,D2 ; say "ClickExpand, word selection" <EHB 01Oct85>
Bsr 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)
move.l a4,-(sp) ; save current use of a4 across calls <27>
move.l 4(sp),a4 ; restore teHandle <27>
Bsr ShowCaret ; feedback to user
Bsr HiLite
move.l (sp)+,a4 ; restore TEClick's use of a4 <27>
waitLoop
Move.L teClikProc(A3),D0 ; call the click proc
Beq.S noClikProc
Move.L D0,A0
Jsr (A0)
Beq done1 ; if returns zero abort drag <SM7> CSS
noClikProc
Clr -(SP) ; make room for result
_WaitMouseUp ; see if button still down
Tst.b (SP)+ ; pop result, only check significant byte <36>
Beq.S done1
Pea teSelPoint(A3) ; pass address for point
_GetMouse
move.l a4,-(sp) ; save current use of a4 across calls <27>
move.l 4(sp),a4 ; restore teHandle <27>
Bsr.S DoFind ; juggle dispStart/End and do find
move.l (sp)+,a4 ; restore TEClick's use of a4 <27>
Cmp D6,D5 ; see if change
Beq.S waitLoop
move.l a4,-(sp) ; save current use of a4 across calls <27>
move.l 4(sp),a4 ; restore teHandle <27>
Bsr HideCaret
move.l (sp)+,a4 ; restore TEClick's use of a4 <27>
; There was a change so highlight only the new part. This is a really tricky part...
; The thing we're trying to do 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 (in teSelStart!)
Move D0,D4 ; save dispEnd too
Swap D3
Swap D4
Move A4,D3 ; save other dispStart
Move (A0),D4 ; save other dispEnd (old teSelEnd)
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
move.l a4,-(sp) ; save current use of a4 across calls <27>
move.l 4(sp),a4 ; restore teHandle <27>
MoveQ #teHighlight,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
move.l (sp)+,a4 ; restore TEClick's use of a4 <27>
keepWaiting
Move D6,D5 ; save new end
Bra.S waitLoop ; continue on
done1
move.l (sp)+,a4 ; restore teHandle for the last time <27>
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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; Pixel2Char
; ** Added 6/18/86 MBK **
;
; Entry:
; D0.W: length of block (style run)
; 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 character offset in block
; (high word) boolean = TRUE (0001) if offset corresponding to
; the given pixel width was found
; D1.W: character offset
; D2.W: flagged (0001) if hit on leading edge of char
;
; Must preserve A2 for DoSearch.
;----------------------------------------------------------------------
Pixel2Char
Move.L JPixel2Char,-(SP) ; call the Pixel2Char Routine
Rts
vPixel2Char
with P2CFrame
link a6,#locals
move.l a0,textPtr(a6) ; save for result
move.w d1,pixelWidth(a6) ; save for SMgr P2C (and width used for 7.0)
; use NPixel2Char now for a faster and more powerful hit-test routine! <23>
subq #2,sp
move.l a0,-(sp) ; pass text ptr to buffer
and.l #$0000FFFF,d0 ; want length as a longint
move.l d0,-(sp)
swap d2 ; here's the slop
clr.w d2 ; as a FIXED
move.l d2,-(sp)
move.w d1,txtWidth(a6) ; save for result
swap d1 ; pass de pixel width
clr.w d1 ; as a FIXED
move.l d1,-(sp)
pea leadingEdge(a6) ; leadingEdge is a var
pea widthRemaining(a6) ; width remaining is a var & FIXED
move.w #smOnlyStyleRun,-(sp) ; default style run position
move.l #$00010001,d0 ; default 1/1 scaling
move.l d0,-(sp) ; push numer
move.l d0,-(sp) ; push denom
_NPixel2Char
move.w (sp)+,d1 ; returns the char offset
move.w txtWidth(a6),d0 ; return initial width for a hit
moveq #0,d2 ; must clear since DoSearch tests it
tst.w widthRemaining(a6) ; is there a hit? (FIXED result)
bmi.s @SetLEFlag ; yep
sub.w widthRemaining(a6),d0 ; return actual measured width
@SetLEFlag
; indicate to DoSearch that SMgr's P2C used hence leadingEdge flag is valid
bset #16,d2 ; flag that P2C used
move.b leadingEdge(a6),d2 ; renamed from leftSide <23>
bne.s @finis ; bra if leadingEdge is T since whole character fits <20>
; decrement if LeadingEdge is F to be sure whole character will display <20>
; backup correctly for either single or double byte text
movem.l d0/d2/d3/d6,-(sp) ; <20>
move.l textPtr(a6),a0 ; pointer to text measured <21>
move.l teTextH(a3),a1 ; <21>
move.l (a1),a1 ; <21>
suba.l a1,a0 ; offset of this text <21>
move.w a0,-(sp) ; save for decrement <21>
move.w d1,d6 ; DoubleByte wants offset here <21>
add.w a0,d6 ; current position <20>
move.w #-1,d3 ; incremental direction to move <20>
bsr DoubleByte ; <20>
move.w d6,d1 ; new position <20>
sub.w (sp)+,d1 ; restore as an offset w/in this text <21>
movem.l (sp)+,d0/d2/d3/d6 ; <20>
@finis
unlk a6
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; DoSearch
; ** Rewritten 6/18/86 MBK **
;
; Used to determine hit-test of a character
; <4May89smb> gave DoSearch a face-lift
; On Entry:
; d3 start offset
; d4 end offset
; a3 ptr to teRecord
;
; On Exit:
; d0 character offset where hit
; leftSide (leading Edge!) set for knowing where the caret should appear
;----------------------------------------------------------------------
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
with TextFrame,TEFormatOrder
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
sf teLftClick(A3) ; assume false for later! <4May89smb>
Move.W teSelPoint+h(A3),D5 ; get h coord
Sub.W teSelRect+left(A3),D5 ; subtract justification
; set d0 and teLftClick(a3) if at left of selRect <4May89smb>
ble @BailToLeft ; special case on left of whole line
;;<1/25/90smb> if zero width, want to branch ow this one pixel difference causes the
;;<1/25/90smb> caret to display on the wrong line ending. (Roman fix)
;;<1/25/90smb> blt @BailToLeft ; special case on left of whole line <16Aug89smb>
Move teSelRect+left(A3),teSelRect+right(A3); init right side to left
Move.W #UnboundLeft,teSelRect+left(A3); bogus left
Move.W 2(A2),D6 ; end of line
Tst.W teSize(A3) ; check style flag
Bmi.S @StyledRecord
st useOldMethod(a6)
MoveQ #1,D2 ; just 1 style
Move.W D3,D1 ; start of line
Move.W D6,D0 ; whole line
Bra @DoMeasure
@StyledRecord
sf useOldMethod(a6) ; flag for getting style runs <28Sept88smb>
; determine if display order is different from backin-store order <28Sept88smb>
tst.b WordRedraw ; $FF if a R->L directional script installed
bge.s @getStyleOld ; nope, only L->R directional text
Move.W D3,D0 ; start offset
Move.W D6,D1 ; end of selection
bsr GetStylesInOrder ; <15Nov88smb>
; tests whether any styles to process <15Nov88smb>
bge.s @GetStyleHandle ; <15Nov88smb>
bra @NoMoreStyles ; done <15Nov88smb>
@getStyleNew
; get next style using the results from getFormatOrder <28Sept88smb>
;; <5Aug89smb> movea.l a2StyleRun(a6),a0
; Made a2StyleRun(a6) an offset - can't save the ptr! (the handle's not locked!)
; Get to posn in styleRun array via the Style Handle and saved offset <5Aug89smb>
move.l teStylesH(a3),a0 ; <5Aug89smb>
move.l (a0),a0 ; deref <5Aug89smb>
add.l a2StyleRun(a6),a0 ; add in offset to desired posn in the array <5Aug89smb>
move.w fmtOrderingIndex(a6),d0 ; index (0-d2) into array for next style run
;; mulu #2,d0 ; index into fmtOrdering array
lsl.w #1,d0 ; index into fmtOrdering array <28June89smb>
lea.l fmtOrderingPtr(a6),a1 ; get ptr to array of format runs ordering <15Nov88smb>
move.l (a1),a1 ; dereference for ordering <15Nov88smb>
move.w 0(a1,d0.w),d0 ; index of next style run
;; mulu #stStartSize,d0 ; offset in styleRun array from d3 style run
lsl.w #lnStStartSize,d0 ; offset in styleRun array from d3 style run <28June89smb>
lea.l 0(a0,d0.w),a0 ; next style run
addq #1,fmtOrderingIndex(a6) ; incr the style run counter
subq #1,d2 ; dec the style counter
bge.s @GetStyleHandle
bra @NoMoreStyles ; done
@getStyleOld
st useOldMethod(a6)
Move.W D3,D0 ; get selection start!!!
Move.W D6,D1 ; end of line
Bsr GetCurStyle ; get its style <7Oct88smb>
Bsr GetNumStyles ; # of styles between offsets <7Oct88smb>
Move.W D0,D2 ; preserve # of styles
@GetStyleHandle
Move.L A0,A2 ; preserve ptr to current style
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> **
@StyleLoop
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 run in StyleRun array
Move.W startChar(A0),D0 ; want end of this style run
Cmp.W D3,D1 ; compare styleStart to beginning of line
Bhs.S @OnSameLine ; made this unsigned ** <C381/6nov86/MBK> **
Move.W D3,D1 ; set beginning of style to beginning of line
@OnSameLine
Move.W D1,D7
Cmp.W D0,D6 ; compare styleEnd to end of line
Bhs.S @DoMeasure ; made this unsigned ** <C381/6nov86/MBK> **
Move.W D6,D0 ; set end of style to end of line
@DoMeasure
Move.W D2,-(SP) ; style count
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 TEHitTestHook ; call our hook instead <C971/RWW111887>
Add.W D0,teSelRect+right(A3) ; update selRect
Add.W D1,D7 ; update char offset
Sub.W D0,D5 ; update pixel offset
; find out if the pixel position was within the style run. <9Nov88smb>
ble.s @HitIt ; got a hit! (D5 <= 0)
;----------------------------------------------------------------------
; if at the last style, and pixel width > 0, and the TEHitTestHook is replaced, then
; must check the high word of d0 to see if we REALLY got a hit! <2/16/90smb>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l HITTESTHook(a0),a0
pea Pixel2Char
cmpa.l (sp)+,a0
beq.s @NotAHit
; we've been hooked out so test per the old interface specs for a hit.
swap d0
tst.b d0
bne.s @HitIt
@NotAHit
;----------------------------------------------------------------------
Move.L A2,A0 ; ptr to current style
moveq #0,d2 ; clear P2C flag from high word <7Dec89smb>
Move.W (SP)+,D2 ; restore style count
; if no more style runs (at right of selRect), set exit info <4May89smb>
beq.s @NoMoreStyles ; replaced next 2 lines <10>
;; bne.s @getNextStyle ; last style on line? <10>
;; bra.s @NoMoreStyles ; <10>
; get next style
@getNextStyle
tst.b useOldMethod(a6) ; is this a styled, RL record? <28Sept88smb>
beq @getStyleNew ; yes, use formatOrder array
; either unstyled or styled, LR record.
Addq.l #stStartSize,a0 ; get next style <7Oct88smb>
SubQ #1,D2 ; dec # of styles
Bne.S @StyleLoop ; keep looping if more <C971/RWW102887>NO
@NoMoreStyles
move.w #UnboundRight,teSelRect+right(A3) ; else store bogus right
; <29Mar89smb> need to set up a2 again w/ lineStart
move.w d3,d0
lea teLines(a3),a2
bsr GetLine
bra.s @BailToRight
; All of Bail new: <4May89smb>
; if at the Left of selRect then
; if TESysJust = 0
; then set (a2) and teLftClick = T.
; else set 2(a2) and teLftClick = F.
; if at the Right of selRect then
; if TESysJust = FFFF
; then set (a2) and teLftClick = T.
; else set 2(a2) and teLftClick = F.
; set d2 to indicate which side of rectangle we are on: 0 = Right, FF = Left. Cmp to line direction.
@BailToLeft
st d2 ; flag on L. side of selRect (ow is 0 for R. side)
@BailToRight
move.w 2(a2),d7 ; assume at end of line
cmp.b TESysJust,d2 ; compare edge of rectangle to line direction
beq.s @CRTest ; at EOL (R. edge of LR line OR L. edge of RL line)
move.w (a2),d7 ; know at Start of line
st teLftClick(a3) ; mark on left to keep caret on same line (see doCaret)
tst.b d2 ; since at Start of line don't need to test for CR
bne.s Done ; on left of selRect, no handle allocated
bra.s findDone ; test for style handle
; moved here <4May89smb>
@HitIt
addq.l #2,sp ; remove style count from stack
; if SMgr's P2C measured the text then the leftSide flag is valid <7Dec89smb>
tst.l d2 ; flag in high word; whole reg 0 if TextWidth used <7Dec89smb>
beq.s findDone ; TextWidth used, not SMgr's P2C <7Dec89smb>
bclr #16,d2 ; clean up! <7Dec89smb>
tst.b d2 ; left or right side of char? (set in P2C) ; <7Dec89smb> flag in byte
; undo what did in Pixel2Char (it was done for linebreaking and there's no way to know who called)
st teLftClick(A3) ; mark it to left
bne.s findDone ; bra if leadingEdge is T <20>
movem.l d2/d3/d6,-(sp) ; <20><23>
move.w d7,d6 ; current position <20>
move.w #1,d3 ; incremental direction to move <20>
bsr DoubleByte ; <20>
move.w d6,d7 ; new position <20>
movem.l (sp)+,d2/d3/d6 ; <20><23>
sf teLftClick(A3) ; mark it to right
; Only want to test for a CR if the charOffset = 2(a2) and the leftSide = T.
; CR is a neutral character therefore, if it follows a style run whose direction is
; different from the line direction, it will always occur at the EOL posn, in the
; line direction. <5May89smb>
; <1/24/90smb> need to set up a2 again w/ lineStart
move.w d3,d0 ; <1/24/90smb>
lea teLines(a3),a2 ; <1/24/90smb>
bsr GetLine ; <1/24/90smb>
cmp.w 2(a2),d7 ; EOL?
bne.s @doneTest
; Test for a CR <4May89smb>
@CRTest
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
Move.B -1(A0,D7),D0 ; <C971/RWW110387>
Bsr.S TEEOLHook ; normally compare d0 with $0D <C971/RWW110387>
beq.s HitCR ; is a CR, so backup 1 char and set teLftClick(a3)
@doneTest
tst.w d5
ble.s done ; if neg pixelWidth, no locked style handle
bra.s findDone ; not a CR
HitCR
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 Done
Move.L teStylesH(A3),A0 ; handle to style info
_HUnlock ; unlock it
Done ; moved here <47>
bsr FreeFmtOrderArray ; <18Jan89smb>
;;Done
Move D7,D0 ; return in D0
Bra doBye
;formFeed
;----------------------------------------------------------------------
;
; 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 #returnChar,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.
;
; modified <2/8/90smb>
; This internal interface still uses TextEdit's old Char2Pixel routine
; for backwards compatibility for developers. Specifically, if a developer
; has been using this interface, and chains his routine in, the new Char2Pixel
; routine would have broken his application. We now have a new interface,
; ScriptChar2Pixel (below) that allows a developer to replace our new
; Char2Pixel routine or chain with it instead.
;
; However, if a script system is installed, we override this hook and
; automatically use the new hook. Also, if a developer has not replaced our
; internal measuring routine (OldChar2Pixel) then we use the new routine.
; Hence, the only time we use the OldChar2Pixel code is when a developer has
; used this hook. <2/8/90smb>
;
; Measures from start of text to offset, length means length of style run!!!!
;
; ENTRY:
; a0.l => ptr to 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
; If a non-Roman system then use new WidthHook routine.
move.l ExpandMem,a1 ; <2/8/90smb>
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a1) ; total number of installed scripts
bne.s ScriptChar2Pixel ; <2/8/90smb>
; Test if the hook contains our internal address <2/8/90smb>
move.l teDispatchH(a3),a1
move.l (a1),a1
move.l WIDTHHook(a1),a1
; if the address of the TEWidthHook is our own OldChar2Pixel routine then use the
; new Char2Pixel routine. Otherwise, use the old routine. <2/8/90smb>
pea OldChar2Pixel ; <2/8/90smb>
cmpa.l (sp)+,a1 ; <2/8/90smb>
beq.s ScriptChar2Pixel ; <2/8/90smb>
; set up the length and offset correctly for the OldChar2Pixel (at this point they have
; been set up for the new Char2Pixel that calls the SMgr's C2P routine.
; adjust the length to reflect the length to measure (from the offset) rather than the
; whole length of the text that the SMgr's C2P expects. <2/8/90smb>
move.w d1,d0 ; the C2P offset (d1) should be the byte count or length (d0) <2/8/90smb>
move.w #0,d1 ; set the offset to 0. <2/8/90smb>
jmp (a1) ; default is to call OldChar2Pixel which calls TextWidth
;----------------------------------------------------------------------
;
; ScriptChar2Pixel
;
; new <2/8/90smb>
; This internal interface uses the new width hook which allows
; a developer to replace TextEdit's new Char2Pixel code that
; uses the Script Manager's Char2Pixel routine.
;
; If a developer chains in his routine w/o understanding our new interface
; (ie - he expects the old TEWidthHook registers to be used) then his code
; will not work.
;
; Stock version only calls new Char2Pixel.
;
; Measures from start of text to offset, length means length of style run!!!!
;
; ENTRY:
; a0.l => ptr to text buffer
; a2.l => ptr to current lineStart (from teLines)
; d0.w = overall style run length, pinned to the line end
; d1.w = offset position within the style run, pinned to the line start
; d2.l = slop (low word) (see SMgr C2P routine)
; direction flag (high word) (see SMgr C2P routine)
;
; EXIT:
; d1.w = width of measured text
;----------------------------------------------------------------------
ScriptChar2Pixel ; renamed from nTEWidthHook <18>
move.l teDispatchH(a3),a1
move.l (a1),a1
move.l nWIDTHHook(a1),a1 ; default is Char2Pixel
jmp (a1)
IF hasTextWidthHook THEN ; <18>
;----------------------------------------------------------------------
;
; TETextWidthHook <18>
;
; new <9/19/90smb>
;
; This internal interface uses the new TextWidth hook which allows
; a developer to replace the TextWidth calls in TextEdit with their
; own measuring code.
;
; The default is to use the OldChar2Pixel routine which calls
; _TextWidth.
;
; ENTRY:
; a0.l => ptr to text to measure
; d0.w = Length of text to be measured
; d1.w = Offset into text
;
; EXIT:
; d0.l,
; d1.l = Width of measured text, with result in low word and high word clear
; (using both registers since some callers use d0 for the result and
; others use d1)
;----------------------------------------------------------------------
TETextWidthHook
move.l teDispatchH(a3),a1 ; <18>
move.l (a1),a1 ; <18>
move.l TextWidthHook(a1),a1 ; <18>
jsr (a1) ; result in d1.w <18>
moveq #0,d0 ; <18>
move.w d1,d0 ; result in longized d0 <18>
move.w d0,d1 ; result in longized d1 <18>
rts ; <18>
ENDIF ; <18>
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; DoDraw
;
; ** Rewritten 6/18/86 by MBK **
;
; Given display start and end in [D3..D4], this draws the text
;
;----------------------------------------------------------------------
DoDraw
with TextFrame,TEFormatOrder
Bsr PinDisplay
Bsr Preamble ; set rLine to A2 line
; ** <C105/14aug86/MBK> Only call LineRect at start to avoid height search **
Bsr LineRect
;----------------------------------------------- <22>
; Turn PreserveGlyph off before drawing, but save its previous setting <22>
clr.w -(sp) ; boolean result <22>
_GetPreserveGlyph ; <22>
; leave result on stack
tst.w (sp) ; preserve or squash? (byte result but cleared word)
beq.s @IsFalse ; <22>
move.b #0,-(sp) ; set PreserveGlyph FALSE <22>
_SetPreserveGlyph ; <22>
@IsFalse
;----------------------------------------------- <22>
@lineLoop
Bsr PrepLine ; pin D4 at line end
Bls @Test4Handle ; done...
Bsr ChkBounds ; extend bounds if necessary
;; <7Dec89smb> Tst.W TESysJust ; reverse order?
;; <7Dec89smb> Beq.S @LROrientation ; no, left->right flow
tst.b WordRedraw ; if R-L script (-1), then erase whole line <7Dec89smb>
bge.s @LROrientation ; no, left->right flow <7Dec89smb>
Move.W #UnboundLeft,teSelRect+left(A3) ; else, set unbound left
Move.W #UnboundRight,teSelRect+right(A3) ; else, set unbound right <7Dec89smb>
@LROrientation
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 @styledRecord
; 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 @nxtLine ; <C971/RWW102887>NO
; record has style, so draw one style at a time
@styledRecord
Tst.W D0 ; check default ascent
Bpl.S @ascentSet ; use it if set
Bsr PtrToLine ; convert A2 ptr to 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
@ascentSet
Add D0,(SP) ; drop pen to baseline
_MoveTo
sf useOldMethod(a6) ; init flag for getting style runs <28Sept88smb>
; determine if display order is different from backin-store order <28Sept88smb>
tst.b WordRedraw ; $FF if a R->L directional script installed
bge.s @getStyleOld ; nope, only L->R directional text (unsigned!)
Move.W D3,D0 ; start offset
Move.W D4,D1 ; end of selection
bsr GetStylesInOrder ; <15Nov88smb>
; tests whether any styles to process <15Nov88smb>
bge.s @styleLoop ; <15Nov88smb>
bra @nxtLine ; <15Nov88smb>
@getStyleNew
; get next style using the results from getFormatOrder <28Sept88smb>
bsr GetNextDisplayStyle ; <4Jan89smb>
addq #1,fmtOrderingIndex(a6) ; incr the style run counter
SubQ #1,D2 ; dec the style counter
bge.s @styleLoop
bra.s @nxtLine
@getStyleOld
st useOldMethod(a6)
Move.W D3,D0 ; start offset
Move.W D4,D1 ; end of selection
Bsr GetCurStyle ; get its style <7Oct88smb> replaces GetFirstStyle call
Bsr GetNumStyles ; # of styles between offsets <7Oct88smb>
Move.W D0,D2 ; save style count
@styleLoop
Move.L A0,-(sp) ; ptr to style: preserve a4 <21Dec88smb>
;; 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
move.l a1,d1 ; <21Dec88smb>
Sub.L d1,2(A7) ; save as an offset <21Dec88smb>
;; 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
move.l a1,d1 ; <21Dec88smb>
Add.L d1,2(A7) ; restore as pointer <21Dec88smb>
;; Add.L A1,A4 ; restore as pointer
Move.W (SP)+,D2 ; restore the count
Move.L (sp)+,A0 ; ptr to style <21Dec88smb>
;; Move.L A4,A0 ; ptr to style
tst.b useOldMethod(a6) ; <28Sept88smb>
beq.s @getStyleNew ; use formatOrder array
Addq.l #stStartSize,a0 ; get next style <7Oct88smb> replaces GetNextStyle call
SubQ #1,D2 ; dec the style counter
Bne.S @styleLoop ; must be more than 1 line
; ** <C105/14aug86/MBK> NextLineRect will not search for height from start **
@nxtLine
Bsr PtrToLine ; convert A2 to line #
AddQ #1,D0 ; next line
Bsr NextLineRect ; set next line's rect
Move (A2),D3 ; get start
Bra @lineLoop ; keep going
@Test4Handle
;----------------------------------------------- <22>
; Restore PreserveGlyph
; previous PreserveGlyph value still on stack
_SetPreserveGlyph ; <22>
;----------------------------------------------- <22>
bsr FreeFmtOrderArray ; <18Jan89smb>
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
endWith
;formFeed
;----------------------------------------------------------------------
;
; 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.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vDoErase(a0),a0
jmp (a0)
xDoErase
with TextFrame,TEFormatOrder
Move.W teSelRect+left(A3),-(SP) ; save left side for draw
Cmp.W (A2),D3 ; at start of line?
Beq.s @GoErase ; 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 @GoErase ; do it the old way if so
Tst.W teSize(A3) ; TERec with style?
Bpl.S @MeasureChar ; skip style setup if not
; determine if display order is different from backin-store order <28Sept88smb>
tst.b WordRedraw ; $FF if a R->L directional script installed
bge.s @getStyleOld ; nope, only L->R directional text
Move.W D3,D0 ; start offset
Move.W D4,D1 ; end of selection
bsr GetStylesInOrder ; <15Nov88smb>
bra.s @SetPort
@getStyleOld
Move.W D3,D0 ; selection start
Move.W D0,D1 ; don't care about end
Bsr GetCurStyle ; get its style <7Oct88smb> replaces GetFirstStyle call
Bsr GetNumStyles ; # of styles between offsets <7Oct88smb>
@SetPort
Bsr SetStyle ; set the port
@MeasureChar
IF hasTextWidthHook THEN ; <18>
move.l teTextH(a3),a0 ; text handle <18>
move.l (a0),a0 ; wants text ptr here <18>
move.w d3,d1 ; wants offset here <18>
moveq #1,d0 ; wants length here <18>
bsr TETextWidthHook ; hook out TextWidth <18>
ELSE ; <18>
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
ENDIF ; <18>
; 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 @ZeroWidth ; else subtract one from char width ** <C485/04dec86/MBK> **
SubQ.W #1,D0 ; to fix caret erase problem ** <C485/04dec86/MBK> **
@ZeroWidth
Add.W D0,teSelRect+left(A3) ; adjust left
@GoErase
Pea teSelRect(A3) ; erase the expanded rect
_EraseRect
Move.W (SP)+,teSelRect+left(A3) ; restore left side for draw
bsr FreeFmtOrderArray ; <18Jan89smb>
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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 (compare to lineStart of next line)
Blo.S @0
Move 2(A2),D4 ; set to line end (= start of next line)
@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
; a2 a pointer to the current line for d3
;
;----------------------------------------------------------------------
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
;formFeed
;----------------------------------------------------------------------
;
; 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
; On entry d7:
; teFind (0)
; teMark (1) renamed to teHighlight
; teDraw (-1)
; teLoc (-2) renamed to teCaret
;----------------------------------------------------------------------
DoText
Move.L TEDoText,-(SP)
Rts
XDoText
with TextFrame,TEFormatOrder
Link A6,#TextFrameSz ; link frame for DoText procs
Tst D7 ; check dispatch code
Beq DoSearch
Bgt DoHilite
Cmp #teDraw,D7
Beq DoDraw ; fall into doCaret
;formFeed
;----------------------------------------------------------------------
;
; 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. (That's nothing
; compared to the weird shit it has to do for split carets! -.ed)
;
;----------------------------------------------------------------------
DoCaret
Bsr.S Preamble ; set rLine to A2 line
Tst D3 ; special case @ 1st character <03Nov85> SC
Beq.S @GetSelRect ; if so skip all these checks <03Nov85> SC
Cmp (A2),D3 ; at line start?
Bne.S @GetSelRect ; skip if not next-line start
Move teLength(A3),D0 ; are we past last char?
Beq.S @GetSelRect ; (and is there a last char?)
Cmp D0,D3 ; are we past last char?
Blo.S @LeftCaret ; 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 #returnChar,-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 @GetSelRect ; skip the line
bra.s @PrevLine
@LeftCaret
Tst.B teLftCaret(A3) ; to left?
Bne.S @GetSelRect ; skip line pull back if so
@PrevLine
SubQ #2,A2 ; skip to previous line
@GetSelRect
; determines the boundaries of the selection rectangle that contains the cursor, setting left = right
bsr LineRect ; removed from Prep ** <C105/14aug86/MBK> **
tst.w teSize(a3) ; <27Oct88smb>
bmi.s @GetCursors ; bra if styled text
tst.b WordRedraw ; old style record, test for Roman/double-byte system
;;<22June89smb> bmi.s @OldStyleRecord
bmi.s @GetCursors ; bra if RL unstyled text <22June89smb>
tst.b teSysJust ; <22June89smb>
beq.s @OldStyleRecord ; bra if LR text on a LR line <22June89smb>
@GetCursors
; styled text OR unstyled RL text OR unstyled LR text on a RL line
bsr CaretDisplay ; possibly split cursors <27Oct88smb>
move.w teSelRect+left(a3),d0
move.w d0,saveLeft(a6)
bra.s @Fix4Cursor
; Old style edit record for Roman; process as before <27Oct88smb>
@OldStyleRecord
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
@Fix4Cursor
SubQ #1,D0
Move D0,teSelRect+left(A3)
;-----------------------------------------------------------------------------------------
; pin caret to edge of view rect if it's displaying out of view <1/29/90smb>
; make sure it's a caret position (selStart = selEnd)
move.w teSelStart(a3),d0
cmp.w teSelEnd(a3),d0
bne @Done
tst.b teSysJust
bne.s @RLDirection
; for a left-to-right line:
; if the viewRect.right >= the destRect.right and
; if the selRect.left >= the viewRect.right
; then selRect.right = viewRect.right
; selRect.left = viewRect.right-1.
; is the viewRect.right >= the destRect.right?
move.w teViewRect+right(a3),d0
cmp.w teDestRect+right(a3),d0
blt.s @Done
; is the selRect.left >= the viewRect.right?
move.w teViewRect+right(a3),d0
cmp.w teSelRect+left(a3),d0
bgt.s @Done
; pin caret to edge of view rect
move.w d0,teSelRect+right(a3)
subq.w #1,d0
move.w d0,teSelRect+left(a3)
; test for split carets
move.l ExpandMem,a0
tst.b ExpandMemRec.emTwoCursorsFlag(a0)
beq.s @Done
; test if 2nd (split) caret is out of view also:is the Left edge greater than the view rect's Right edge
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right of 2nd caret
addq.w #1,d0 ; view rect still here: get back to right edge.
cmp.w left(a0),d0
bgt.s @Done
; pin split caret to edge of view rect also.
move.w d0,right(a0)
subq.w #1,d0
move.w d0,left(a0)
bra.s @Done
@RLDirection
; for a right-to-left line:
; if the viewRect.left <= the destRect.left and
; if the selRect.right <= the viewRect.left
; then selRect.left = viewRect.left
; selRect.right = viewRect.left+1.
; is the viewRect.left <= the destRect.left?
move.w teViewRect+left(a3),d0
cmp.w teDestRect+left(a3),d0
bgt.s @Done
; is the selRect.right <= the viewRect.left?
move.w teViewRect+left(a3),d0
cmp.w teSelRect+right(a3),d0
blt.s @Done
; pin caret to edge of view rect
move.w d0,teSelRect+left(a3)
addq.w #1,d0
move.w d0,teSelRect+right(a3)
; test for split carets
move.l ExpandMem,a0
tst.b ExpandMemRec.emTwoCursorsFlag(a0)
beq.s @Done
; test if 2nd (split) caret is out of view also:is the Right edge less than the view rect's Left edge
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right of 2nd caret
subq.w #1,d0 ; view rect still here: get back to left edge.
cmp.w right(a0),d0
blt.s @Done
; pin split caret to edge of view rect also.
move.w d0,left(a0)
addq.w #1,d0
move.w d0,right(a0)
@Done
; end of changes <1/29/90smb>
;-----------------------------------------------------------------------------------------
Bra doBye
;formFeed
;----------------------------------------------------------------------
;
; CaretDisplay
; <27Oct88smb>
;
; This routine will be used to display cursors, split cursors
; when necessary. Will not enter this routine with an old styled
; TE record for a left-to-right directional script. Walk through
; a line, style run by style run, measuring and accumulating
; widths until hit a run containing a cursor.
;
; Input
; a2 LineStart of current line containing d3 (from TE LineStarts array)
; a3 pointer to locked edit record
;
; d3 position of cursor
; d4 position of cursor
;
; Uses
; d2 number of style runs on the line
; d5 pixelWidth of the measured style runs
; a0 pointer to current style
; a1 format ordering array
; a2 lineStart
; a4 pointer to cursor's style run
; d5 pixelWidth of the measured style runs
;----------------------------------------------------------------------
CaretDisplay
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vCaretDisplay(a0),a0
jmp (a0)
xCaretDisplay
with SharedFrame,TEFormatOrder
link a6,#SharedFrameSz
move.l ExpandMem,a0 ; <1Feb89smb> initialize for only 1 cursor
sf ExpandMemRec.emTwoCursorsFlag(a0)
sf ExpandMemRec.emFmtOrderHFlag(a0) ; no handle allocated for styles
clr.w gotOneRun(a6) ; set gotOneRun and onBoundaryFlag to F.
sf scriptDirection(a6) ; initialize to LR
clr.w d5
bsr GetFormatOrdering ; <8Mar89smb>
; accumulate widths of style runs until hit one containing a cursor.
@MeasureLoop
bsr GetNextDisplayStyle ; <4Jan89smb>
addq #1,fmtOrderingIndex(a6) ; incr for the next measurement
; does this style contain a cursor?
@Check4Cursor
cmp.w startChar(a0),d3 ; cursor at beginning of run?
;; bhi.s @CheckUpperBound ; <26June89smb> made unsigned <11>
beq.s @CursorRun ; cursor on start boundary of it's run
;; bra @GetWidth ; cursor outside of run <11>
blo @GetWidth ; <11>
@CheckUpperBound
bsr FixFormatEnd ; if last format run, must decrement <17Jan89smb>
cmp.w d0,d3 ; cursor at end of run? <17Jan89smb>
bhi.s @GetWidth ; cursor outside of run <26June89smb> made unsigned
blt.s @FoundCursor ; cursor in middle of run
; in style previous to cursor's run
tst.b gotOneRun(a6) ; set up second rectangle now?
bne @SetEnds ; yup, already have top and bottom
st prevStyleFlag(a6) ; cursor at end of this run (previous style)
bra.s @OnBoundary
@CursorRun
; in cursor's run
tst.b gotOneRun(a6) ; set up second rectangle now?
bne @SetEnds ; yup, already have top and bottom
sf prevStyleFlag(a6) ; cursor at beginnning of it's run
@OnBoundary
st onBoundaryFlag(a6) ; cursor on boundary of run
; cursor either in middle of the style run or on a boundary
@FoundCursor
tst.w teSize(a3) ; <1Dec88smb>
bpl.s @DontSet
bsr SetStyle
@DontSet
tst.b WordRedraw ; <4Oct89smb>
blt.s @ContainsRLText ; <4Oct89smb>
tst.b teSysJust
bne.s @ContainsRLText
; in LR text only on a LR directional line: done stepping thru style <
clr.l d2 ; #smLeftCaret set in low word of d2
bsr GetLRPosition
add.w d1,d5 ; add C2P width to totalWidth of line thus far (d5)
add.w d5,teSelRect+left(a3) ; add width to left and right edges of selRect
add.w d5,teSelRect+right(a3)
bra @done
@ContainsRLText
move.w d2,-(sp) ; save style counter
bsr GetRLPosition
move.w (sp)+,d2 ; restore style counter
tst.b doneFlag(a6)
bne.s @finis
tst.b lineEndFlag(a6)
bne.s @GetWidth ; must measure rest of style runs on line
; added more robust tests for determining whether need to measure style run or not <8Nov88smb>
tst.b scriptDirection(a6)
bne.s @ChkRLMeasure ; bra if RL script direction
; in LR script direction <8Nov88smb>
tst.b prevStyleFlag(a6)
bne @MeasureLoop ; bra if previous LR run: already measured
bra.s @GetWidth ; measure since in cursor run w/ LR direction
@ChkRLMeasure
; in RL script direction <8Nov88smb>
tst.b prevStyleFlag(a6)
beq @MeasureLoop ; bra if in cursor run: already measured
; cursor's not in this style run, so measure it and save its width for later OR
; found cursor in it's style run but the script has LR direction so need to measure
@GetWidth
move.w d1,-(sp)
bsr MeasureWholeRun
add.w d0,d5
move.w (sp)+,d1
tst.b WordRedraw ; <4Oct89smb>
bge.s @GetNext ; <4Oct89smb>
SubQ #1,D2 ; dec the style counter
beq.s @finis
bra @MeasureLoop
@GetNext
Addq.l #stStartSize,a0 ; get next style
SubQ #1,D2 ; dec the style counter
Bne @Check4Cursor ; must be more than 1 line
bra.s @finis
@SetEnds
; second cursor style run. Must set up the second rectangle for the second cursor
tst.b prevStyleFlag(a6)
bne.s @InCursorRun ; in cursor script
move.b previousScriptDir(a6),d0
bra.s @GetScriptDirection
@InCursorRun
move.b cursorScriptDir(a6),d0
@GetScriptDirection
bne.s @RLScript
; LR Script <7Nov88smb>
; if in previous style and LR script direction then measure since at end of style run
; otherwise, width is 0 since at beginning of run so, have width to use
tst.b prevStyleFlag(a6)
beq.s @MeasureRun ; bra to measure if in prevStyle's run
bra.s @HaveWidth
@RLScript
; if in cursor style and RL script direction then measure since at beginning of style run
; otherwise, width is 0 since at end of run so, have width to use <7Nov88smb>
tst.b prevStyleFlag(a6)
bne.s @MeasureRun ; bra to measure if in cursor's run
bra.s @HaveWidth
@MeasureRun
move.w d5,-(sp) ; necessary for two cursors
Bsr MeasureWholeRun
add.w d0,d5
bra.s @HaveWidth
@finis
tst.b lineEndFlag(a6)
beq.w @done
IF forLocalizability THEN ; <31m-YDS-8/27/91>
move.l ExpandMem,a0
tst.b ExpandMemRec.emTwoCursorsFlag(a0) ; if we have one cursor
beq.w @done ; skip all the rest
ENDIF
@HaveWidth
; finish setup of 2nd cursor rectangle
move.l ExpandMem,a0 ; <1Feb89smb>
lea ExpandMemRec.emCursor2Rect(a0),a0 ; <12July89smb> changed to lea
addq #2,a0 ; top edge ok
add.w selRectL(a6),d5 ; add original L. edge
move.w d5,(a0) ; left
sub.w #1,(a0)+ ; cursor posn
addq #2,a0 ; bottom edge ok
move.w d5,(a0) ; right (same as left)
IF forLocalizability THEN ; <31d-YDS-8/27/91>
; added to support a single carret at styled TE,
clr.l -(sp) ; make space for function result
move #smGenFlags,-(sp) ; put smSysScript verb to get the SMGR general flags
_GetEnvirons ; now wh have the general flags
Move.l (sp)+, d5 ; take return value.
and.l #(1<<smfDualCaret),d5 ; leave only the right bit
bne.w @done ; leave the split carret as is ?
move.l ExpandMem,a0 ; get the scplit cursor addres into A0
lea ExpandMemRec.emCursor2Rect(a0),a0
Move.w top(a0), d5 ; some times we get the lower
Cmp.w teSelRect+top(a3), d5 ; in selrect & the upper in "ExpandMem"
bgt.s @3 ; so we would like to sort it out.
move.l top(a0),d5 ; switch the two rects. keep in mind
move.l teSelRect+top(a3),top(a0) ; that the upper one has the width of
move.l d5,teSelRect+top(a3) ; zero, while the lower one has the
move.w bottom(a0),d5 ; witdth of 1, it ws set later tio the correct values,
move.w teSelRect+bottom(a3),bottom(a0) ; but that's how it is now, and i'm not
move.w d5,teSelRect+bottom(a3) ; going to change it.
move.w teSelRect+left(a3),teSelRect+right(a3)
move.w left(a0),right(a0)
add.w #1,right(a0)
@3 clr.l -(sp) ; we will need a place on the stack anyway !
Tst.b teCarOn(A3) ; if caret on, we would like to calculate the same caret allways
bne.s @1 ; carret is going on, calculate a new one
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0
move.b lastScript(a0),d5 ; push script numberused to highligt (d5) to lastScript
bra.s @2
@1 move #smKeyScript,-(sp) ; we will call _GetEnvirons to get the current active (keyboard) script.
_GetEnvirons ; now we know who the active script
Move.l (sp), d5 ; take return value (the script number (long !!!)), leave place for return value
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0
move.b d5, lastScript(a0) ; push script numberused to highligt (d5) to lastScript
@2 move.w d5, -(sp) ; push the script (word !!!) for the next call we will need
move #smScriptRight,-(sp) ; is that script a right to left script ?
_GetScript ; we have smScriptRightflag the stack
move.l (sp)+, d0 ; do = result
move.l ExpandMem,a0 ; get the scplit cursor addres into A0
lea ExpandMemRec.emCursor2Rect(a0),a0
cmp.b TESysJust, d0
beq.s @UseTop
@UseBottom
move.w teSelRect+top(a3),top(a0) ; strech lower cursor
move.w teSelRect+top(a3),teSelRect+bottom(a3) ; make top = bottom in upper cursor
bra.s @done
@UseTop
move.w bottom(a0),teSelRect+bottom(a3) ; strech upper cursor
move.w bottom(a0),top(a0) ; make top = bottom in lower cursor
ENDIF
@done
bsr FreeFmtOrderArray ; <18Jan89smb>
unlk a6
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; GetLRPosition
; <27Oct88smb>
;
; The cursor is in this style run and there's only LR text in this
; teRecord. Sets up for and call Char2Pixel for pixel width in
; this style run and adds this to the total width of the line
; thus far. Then puts this width in the selRect so the cursor
; can be drawn.
;
; Input
; a0: style run of cursor (could be previous run w/ cursor at end)
; a2: pointer at current line in lineStart array
; d2: direction parameter for C2P
; d3: absolute position of cursor
; d5: total pixelWidth of style runs thus far in the line
; Uses
; a1
; d0: length of style run to measure (may not be whole run) for C2P
; d1: start offset for C2P
; d4: diffence between lineStart and style start
; Output
; d1: pixel width
;----------------------------------------------------------------------
GetLRPosition
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vGetLRPosition(a1),a1
jmp (a1)
xGetLRPosition
move.l a0,-(sp)
; call Char2Pixel to get the pixel position for the cursor
move.l teTextH(a3),a1 ; get text handle
move.l (a1),a1 ; dereference
add.w startChar(a0),a1 ; add beginning of the style run to get to desired line
exg a1,a0 ; C2P wants text ptr here
; test if style run begins on previous line, and if so adjust text ptr & offset posn in run
moveq #0,d4
move.w (a2),d0
cmp.w startChar(a1),d0
bls.s @StyleStartOK ; <26June89smb> made unsigned
; pin to lineStart
sub.w startChar(a1),d0 ; |begin of line - begin of style run|
add.w d0,a0 ; fix text ptr
move.w d0,d4 ; save difference for length adjustment
move.w d3,d1 ; cursor posn: C2P wants offset here
sub.w (a2),d1 ; offset from start of line
bra.s @getLength
@StyleStartOK
move.w d3,d1
sub.w startChar(a1),d1 ; cursor posn relative to start of style run
@getLength
; test if style run ends on next line, and if so, pin to end of this line & adjust length
move.l a0,-(sp) ; <6Mar89smb>
move.l a1,a0 ; <6Mar89smb>
bsr FixFormatEnd ; <6Mar89smb>
move.l (sp)+,a0 ; <6Mar89smb>
cmp.w 2(a2),d0
bls.s @UseStyleEnd ; <26June89smb> made unsigned
move.w 2(a2),d0 ; pin to line end
@UseStyleEnd
sub.w startChar(a1),d0 ; length of style run
sub.w d4,d0 ; adjust for lineStart
swap d2 ; direction:slop
Bsr TEWidthHook ; returns in d1
move.l (sp)+,a0
rts
;formFeed
;----------------------------------------------------------------------
;
; GetRLPosition
; <27Oct88smb>
;
; The cursor is in this style run and there's RL text in this
; teRecord OR there's only LR text but the line direction is RL.
;
; If the cursor is not on a boundary of the run then
; call C2P twice (with the values smLeftCaret and
; smRightCaret). If the values returned are different then
; two cursors must be drawn, otherwise only one.
;
; If the cursor is on a cluster boundary, then the cursor
; must be drawn in two places. A cluster boundary also applies
; to the beginning and end of a line, when the style run at these
; positions is different then the directional flow of the line.
; Otherwise, the cursor is drawn in one place.
;
;
; Input
; a0: style run containing cursor
; a2: lineStart array
; d3: absolute position of cursor
; d5: total pixelWidth of style runs thus far in the line
; Uses
; d0: total length of style run for C2P
; d1: start offset for C2P
; a1: other style run for cursor
;----------------------------------------------------------------------
GetRLPosition
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vGetRLPosition(a1),a1
jmp (a1)
xGetRLPosition
RLPosnRegs reg a0
with SharedFrame,TEFormatOrder
movem.l RLPosnRegs,-(sp)
sf doneFlag(a6)
clr.w highCaret(a6) ; set lineEndFlag and highCaret to F. <6mar89smb>
st gotOneRun(a6)
clr.l d2 ; used for direction params for C2P
; save original edges of selection rectangle
move.l a2,-(sp)
lea teSelRect+top(a3),a1
lea selRectT(a6),a2
move.l (a1)+,(a2)+
move.l (a1)+,(a2)+
move.l (sp)+,a2
tst.b onBoundaryFlag(a6) ; cursor on boundary of run
beq @InMiddle
tst.w teSize(a3) ; need to test if on a block boundary for
bpl @InMiddle ; old-styled TE <1Dec88smb>
; on a boundary so must test scripts of surrounding style runs (backing-store order) to
; determine if on a cluster boundary.
Bsr GetDirection ; get this style run's direction in byte of d1 <7June89smb>
tst.b prevStyleFlag(a6) ; test if at end or beginning of cursor style run
beq.s @GotCursorStyle
; got script for style run previous to cursor style run
move.b d1,previousScriptDir(a6) ; <7June89smb>
; test for EOL cluster boundary since in previous style run <8Nov88smb>
cmp.w 2(a2),d3 ; is cursor posn at EOL?
beq @LineEnd
; if already at EOL then make sure not looking beyond lineStarts array <20Nov89smb>
move.l a0,-(sp)
lea 2(a2),a0
lea teLines(a3),a1 ; <20Nov89smb>
move.w teNLines(a3),d0 ; get num of lines <20Nov89smb>
add.w d0,d0 ; double for words <20Nov89smb>
adda.w d0,a1 ; <20Nov89smb>
cmpa.l a1,a0 ; <20Nov89smb>
movem.l (sp)+,a0 ; <20Nov89smb>
bgt.s @LineEnd ; bra if beyond end <20Nov89smb>
; truly in the lineStarts array!
move.l a0,-(sp) ; save <21June89smb>
addq.l #stStartSize,a0 ; in previous style run, so need next style run
bra.s @GetScript
@GotCursorStyle
; got script for cursor style run
move.b d1,cursorScriptDir(a6) ; <7June89smb>
; test for BOL cluster boundary since in cursor style run <8Nov88smb>
cmp.w (a2),d3 ; is cursor posn at BOL?
beq.s @LineEnd
move.l a0,-(sp) ; save <21June89smb>
subq.l #stStartSize,a0 ; at beginning so need to check previous style run
@GetScript
; get the other style run's direction (in display order!)
Bsr GetDirection ; <7June89smb>
tst.b prevStyleFlag(a6)
beq.s @GotPrevStyleNow
move.b d1,cursorScriptDir(a6) ; <7June89smb>
bra.s @CmpDirs ; <7June8smb>
@GotPrevStyleNow
move.b d1,previousScriptDir(a6) ; <7June89smb>
@CmpDirs
move.l (sp)+,a0 ; restore <21June89smb>
; compare scripts to see if on a cluster boundary
move.b cursorScriptDir(a6),d0
cmp.b previousScriptDir(a6),d0
bne.s @ClusterBoundary
; same script so display one cursor
Bsr OneCursor ; added for simplicity <12/13/88smb>
bra.s @done ; <12/13/88smb>
;**********************
@ClusterBoundary
; on a cluster boundary: need split cursors
tst.b prevStyleFlag(a6)
beq.s @GetScriptDirection ; in cursor script
move.b previousScriptDir(a6),d0
@GetScriptDirection
move.b d0,scriptDirection(a6)
cmp.b TESysJust,d0 ; added <22Dec88smb>
bne.s @DiffDirections ; added <22Dec88smb>
st highCaret(a6) ; added <22Dec88smb>
@DiffDirections
tst.b d0
bne.s @RLScript
@LRScript
; if in previous style and LR script direction then measure since at end of style run
; if in cursor style, width is 0 since at beginning of run so, have width to use <7Nov88smb>
tst.b prevStyleFlag(a6)
bne.s @MeasureRun ; bra to measure if in prevStyle's run
bra.s @SetUpTwoRects
@RLScript
; if in cursor style and RL script direction then measure since at beginning of style run
; if in previous style and RL script direction AND
; if RL flow, width is 0 since at end of run, so have width to use <7Nov88smb>
; if LR flow, then measure since at beginning of RL script run <8Nov88smb>
tst.b prevStyleFlag(a6)
bne.s @SetUpTwoRects ; bra to measure since in prevStyle's run <12July89smb>
@MeasureRun
Bsr MeasureWholeRun
add.w d0,d5
@SetUpTwoRects
; Setup two rectangles for the split cursors.
bsr.s SetUp2Rectangles ; moved init of rects into proc <12July89smb>
bra.s @done
;**********************
@LineEnd
Bsr.s OnLineEnd ; added for simplicity <12/13/88smb>
bra.s @done
@InMiddle
Bsr CaretInsideRun ; added for simplicity <12/13/88smb>
@done
movem.l (sp)+,RLPosnRegs
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; SetUp2Rectangles
; <12/16/88smb>
; Only set up top and bottom edges of split cursor rectangles.
; The left and right edges will be setup in CaretDisplay.
;
; d2 = midpoint (pixels) between top and bottom edges of selRect
;----------------------------------------------------------------------
SetUp2Rectangles
with SharedFrame,TEFormatOrder
add.w d5,teSelRect+left(a3) ; left edge of rectangle
add.w d5,teSelRect+right(a3) ; right edge of rectangle
; Use half a line heighth for split cursors.
move.w teSelRect+bottom(a3),d2
add.w teSelRect+top(a3),d2 ; get line height <12July89smb> performance
IF forLocalizability THEN ; <31a-YDS-8/27/91>
asr.w #1,d2 ; 1/2 line height - fix Applink bug
ELSE
lsr.w #1,d2 ; 1/2 line height
ENDIF
; need two cursors because have arabic/english in same run OR on a cluster boundary
move.l ExpandMem,a0 ; <1Feb89smb> must save for processing at a higher level!
st ExpandMemRec.emTwoCursorsFlag(a0)
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right <12July89smb>
tst.b highCaret(a6)
beq.s @LowCaret
; In High Caret run (T): the top edge is ok. Adjust the bottom.
move.w d2,teSelRect+bottom(a3) ; new bottom (raised by 1/2 the heighth) <12July89smb>
; Setup low cursor (perpendicular symbol) now. Save in Cursor2Rect space. <12/13/88smb>
move.w teSelRect+bottom(a3),(a0)+ ; new top of line
addq #2,a0
move.w selRectB(a6),(a0) ; use original bottom
bra.s @done
@LowCaret
; in Low Caret run (perpendicular symbol): the bottom edge is ok. Adjust the top.
move.w d2,teSelRect+top(a3) ; new top (lowered by 1/2 the heighth) <12July89smb>
; Setup high cursor (T) now. Save in Cursor2Rect space.
move.w selRectT(a6),(a0)+ ; use original top
addq #2,a0
move.w teSelRect+top(a3),(a0) ; new bottom of line
; say high caret in Cursor2Rect space <21Dec88smb> - for TeSelView
move.l ExpandMem,a0 ; <1Feb89smb>
ori.w #$00FF,ExpandMemRec.emTwoCursorsFlag(a0)
@done
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; OnLineEnd
; <12/13/88smb>
;
; The cursor is on a line ending, either the start or end.
; If the style run is in a direction different than the overall
; line direction then, on a cluster boundary and need split
; cursors.
;
; Input
; a0: style run containing cursor
; a2: ptr to lineStarts array
; a3: pointer to TE record
; d0: present style run's script id number
; d3: absolute position of cursor
; d5: total pixelWidth of style runs thus far in the line
;
;----------------------------------------------------------------------
OnLineEnd
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vOnLineEnd(a1),a1
jmp (a1)
xOnLineEnd
with SharedFrame,TEFormatOrder
; at EOL/BOL. Is the style run of different persuasion then the line direction? <8Nov88smb>
bsr GetDirection ; <30May89smb>
cmp.b TESysJust,d1 ; test if TESysJust = script direction <30May89smb>
bne.s @EOLClusterBoundary ; if not then on a EOL cluster boundary
; on a line end but the style run has the same direction as the line, so only one cursor.
st doneFlag(a6) ; modified <12/13/88smb>
tst.b d1 ; <30May89smb>
bne.s @RLDirection
; LR direction
; if in previous style and LR script direction, then measure since at end of style run
; if in cursor style, width is 0 since at beginning of run, so have width to use <7Nov88smb>
tst.b prevStyleFlag(a6)
bne @MeasureRun ; bra to measure if in prevStyle's run
bra @finis
@RLDirection
; if in cursor style and RL script direction then measure since at beginning of style run
; if in previous style and RL script direction AND
; if RL flow, width is 0 since at end of run so, have width to use <7Nov88smb>
; if LR flow, then measure since at beginning of RL script run <8Nov88smb>
tst.b prevStyleFlag(a6)
beq @MeasureRun ; bra to measure if in cursor's run
tst.b TESysJust
beq @MeasureRun ; LR flow but RL script
bra @finis
;***********
@EOLClusterBoundary
; on a cluster boundary at a line end => script direction different from line direction.
; need split cursors
tst.b d1 ; <30May89smb>
beq.s @LRdirection
; RL script direction
cmp.w 2(a2),d3
beq.s @AtDisplayR ; bra if d3 = lineEnd
bra.s @AtDisplayL ; d3 = lineStart
@LRdirection
; LR script direction
cmp.w (a2),d3
beq.s @AtDisplayR ; bra if d3 = lineStart
;-----------------------------------------------------------------------------------------
@AtDisplayL
; at left end of display line
; if in LR flow, RL script direction, at BOL, OR if in RL flow, LR script direction, at EOL then
; 1st cursor at left edge of screen (high caret) and
; 2nd cursor at measured end of this style run (low caret)
move.w selRectL(a6),teSelRect+left(a3) ; 1st cursor at L. edge
move.w selRectL(a6),teSelRect+right(a3)
; measure style run for second cursor
bsr MeasureWholeRun
add.w d0,d5
st doneFlag(a6)
st lineEndFlag(a6)
; use half a line heighth for split cursors
move.w teSelRect+bottom(a3),d2
add.w teSelRect+top(a3),d2 ; get line height <12July89smb> performance
IF forLocalizability THEN ; <31a-YDS-8/27/91>
asr.w #1,d2 ; 1/2 line height - fix Applink bug
ELSE
lsr.w #1,d2 ; 1/2 line height
ENDIF
move.w d2,teSelRect+bottom(a3) ; new bottom (raised by 1/2 the heighth) <12July89smb>
move.l ExpandMem,a0 ; <1Feb89smb> must save for processing at a higher level!
st ExpandMemRec.emTwoCursorsFlag(a0)
; The high cursor (T) goes with the line ending. the top edge is ok. Adjust the bottom. Can only
; set the top and bottom edges now. May need to measure more style runs. <12/13/88smb>
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right <12July89smb>
move.w teSelRect+bottom(a3),(a0)+ ; top edge
addq #2,a0
move.w selRectB(a6),(a0) ; use original bottom
bra.s @finis
;-----------------------------------------------------------------------------------------
@AtDisplayR
; at right end of display line
; if in LR flow, RL script direction, at EOL, OR if in RL flow, LR script direction, at BOL then
; 1st cursor at present measured width (low caret) and
; 2nd cursor at end of all style runs on the display line (high caret) (continue measuring till out of runs)
add.w d5,teSelRect+left(a3) ; 1st cursor at present measured width
add.w d5,teSelRect+right(a3)
; Setup two rectangles for the split cursors. The low cursor goes with this script run. So,
; adjust the top edge of the rectangle. <12/13/88smb>
st lineEndFlag(a6)
; use half a line heighth for split cursors
move.w teSelRect+bottom(a3),d2
add.w teSelRect+top(a3),d2 ; get line height <12July89smb> performance
IF forLocalizability THEN ; <31a-YDS-8/27/91>
asr.w #1,d2 ; 1/2 line height - fix Applink bug
ELSE
lsr.w #1,d2 ; 1/2 line height
ENDIF
move.w d2,teSelRect+top(a3) ; new top (lower by 1/2 the heighth) <12July89smb>
move.l ExpandMem,a0 ; <1Feb89smb> must save for processing at a higher level!
st ExpandMemRec.emTwoCursorsFlag(a0)
; say high caret in Cursor2Rect space <21Dec88smb> - for TESelView
ori.w #$00FF,ExpandMemRec.emTwoCursorsFlag(a0)
; The high cursor (T) goes with the line ending. the top edge is ok. Adjust the bottom. Can only
; set the top and bottom edges now. May need to measure more style runs. <12/13/88smb>
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right <12July89smb>
move.w selRectT(a6),(a0)+ ; use original top of line
addq #2,a0
move.w teSelRect+top(a3),(a0) ; bottom edge
bra.s @finis
@MeasureRun
Bsr MeasureWholeRun
add.w d0,d5
add.w d5,teSelRect+left(a3) ; left edge of rectangle
add.w d5,teSelRect+right(a3) ; right edge of rectangle
@finis
rts
endwith
;formFeed
;----------------------------------------------------------------------
;
; CaretInsideRun
; <12/13/88smb>
;
; The cursor is in this style run and there's RL text in this
; teRecord. We may be on a block boundary for unstyled RL text.
; The cursor is in the middle of a style run so, call C2P twice
; (with the values smLeftCaret and smRightCaret). If the values
; returned are different, then two cursors must be drawn, otherwise
; only one.
;
; Input
; a0: style run containing cursor
; a3: pointer to TE record
; d3: absolute position of cursor
; d5: total pixelWidth of style runs thus far in the line
; Uses
;----------------------------------------------------------------------
CaretInsideRun
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vCaretInsideRun(a1),a1
jmp (a1)
xCaretInsideRun
with SharedFrame,TEFormatOrder
; cursor is in the middle of this run, so call C2P twice to see if split cursors necessary
st doneFlag(a6)
move.w #smRightCaret,d2 ; second offset to measure
swap d2
move.w #smLeftCaret,d2 ; first offset to measure
; parameters for PixelWidths routine (calls Char2Pixel twice)
move.l a0,a1 ; save pointer to current style run
move.w d5,-(sp) ; save pixel width from MeasureAndHilite routine
move.w d3,d0
sub.w startChar(a1),d0 ; cursor posn relative to start of style run
; pin to lineStart <5Dec88smb>
move.w (a2),d1 ; lineStart <5Dec88smb>
cmp.w startChar(a1),d1 ; <5Dec88smb>
bls.s @UseStyleStart ; <5Dec88smb> <26June89smb> made unsigned
sub.w startChar(a1),d1 ; |beginning of line - beginning of style run| <5Dec88smb>
sub.w d1,d0 ; pin to lineStart! <5Dec88smb>
; may be at lineStart
bne.s @UseStyleStart ; <6Dec89smb>
; if at offset 0 of this line then at the lineStart and may need to measure more style runs <6Dec89smb>
sf doneFlag(a6) ; <6Dec89smb>
st lineEndFlag(a6) ; <6Dec89smb>
@UseStyleStart
move.w d0,d1 ; same posn just different direction
bsr PixelWidths ; returns pixelwidths in d5 (R block) & d6 (L block)
; <3May89smb> this is a special case that makes this UGLY! If LR text and RL line direction
; and (offset = SOL or EOL), then must setup teSelRect a little differently with the
; results returned from C2P.
tst.b TESysJust
beq.s @LRdownstream
; RL line direction. a0 contains the current style.
bsr GetDirection ; returns script direction in d1
cmp.b TESysJust,d1
beq.s @RLdownstream ; RL line direction & RL script run
; Otherwise, RL line and LR script
cmp.w d5,d6
beq.s @RLdownstream
tst.w d5
beq.s @ZeroWidth
exg d5,d6 ; want 0 width in d5: L&R edges are already set in teSelRect.
@ZeroWidth
add.w (sp),d6
bra.s @SetUp2nd ; set up the second rectangle
; test line direction to determine where high caret and low caret should display. <12/13/88smb>
;; tst.b TESysJust
;; bne.s @RLdownstream
; <3May89smb> done with mods.
; L-R is the downstream direction. d6 is the L block's width. <12/13/88smb>
; Want downstream script's width in d5. Simplifies set up for second rectangle.
@LRdownstream
exg d5,d6
@RLdownstream
; R-L is the downstream direction. d5 is the R block's width. <12/13/88smb>
add.w (sp),d5 ; add pixel width of previous runs on line
add.w d5,teSelRect+left(a3)
add.w d5,teSelRect+right(a3)
add.w (sp),d6
; test for one cursor
cmp.w d5,d6
beq.w @finis
; Setup two rectangles for the split cursors.
; The high cursor (T): the top edge is ok. Adjust the bottom. <12/13/88smb>
; use half a line heighth for split cursors
@SetUp2nd
move.w teSelRect+bottom(a3),d2
IF NOT forLocalizability THEN ; <31a-YDS-8/27/91>
bls.s @ScrollDownBug ; scrolling down in hebrew applelink <1/15/90smb> <14>
ENDIF
add.w teSelRect+top(a3),d2 ; get line height <12July89smb> performance
IF forLocalizability THEN ; <31a-YDS-8/27/91>
asr.w #1,d2 ; 1/2 line height - fix Applink bug
ELSE
lsr.w #1,d2 ; 1/2 line height
ENDIF
move.w d2,teSelRect+bottom(a3) ; new bottom (raised by 1/2 the heighth) <12July89smb>
; need two cursors because have arabic/english in same run OR on a cluster boundary
move.l ExpandMem,a0 ; <1Feb89smb> must save for processing at a higher level!
st ExpandMemRec.emTwoCursorsFlag(a0)
; <7July89smb> indicate that high caret is not stored in ExpandMem space.
andi.w #$FF00,ExpandMemRec.emTwoCursorsFlag(a0)
; set up low cursor (perpendicular symbol). <12/13/88smb>
; top edge of rectangle
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right <12July89smb>
move.w teSelRect+bottom(a3),(a0)+ ; new top of line (same as other rect's bottom edge)
add.w selRectL(a6),d6 ; add original L. edge
move.w d6,(a0) ; left
sub.w #1,(a0)+ ; cursor posn
move.w selRectB(a6),(a0)+ ; use original bottom of line
move.w d6,(a0) ; right (same as left)
IF forLocalizability THEN ; <31c-YDS-8/27/91>
;YS - added to support single carret option
; handles unstyled text !!!! <3.3>
clr.l -(sp) ; make space for function result
move #smGenFlags,-(sp) ; put smSysScript verb to get the SMGR general flags
_GetEnvirons ; now wh have the general flags
Move.l (sp)+, d5 ; take return value.
and.l #(1<<smfDualCaret),d5 ; leave only the right bit
bne.w @finis ; leave the split carret as is ?
clr.l -(sp) ; we will need a place on the stack anyway !
Tst.b teCarOn(A3) ; if caret on, we would like to calculate the same caret allways
bne.s @1 ; carret is going on, calculate a new one
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0
move.b lastScript(a0),d5 ; push script numberused to highligt (d5) to lastScript
bra.s @2
@1 move #smKeyScript,-(sp) ; we will call _GetEnvirons to get the current active (keyboard) script.
_GetEnvirons ; now we know who the active script
Move.l (sp), d5 ; take return value (the script number (long !!!)), leave place for return value
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0
move.b d5, lastScript(a0) ; push script numberused to highligt (d5) to lastScript
@2 move.w d5, -(sp) ; push the script (word !!!) for the next call we will need
move #smScriptRight,-(sp) ; is that script a right to left script ?
_GetScript ; we have smScriptRightflag the stack
move.l (sp)+, d0 ; do = result
move.l ExpandMem,a0 ; get the scplit cursor addres into A0
lea ExpandMemRec.emCursor2Rect(a0),a0
cmp.b TESysJust, d0
beq.s @UseTop
@UseBottom
move.w teSelRect+top(a3),top(a0) ; strech lower cursor
move.w teSelRect+top(a3),teSelRect+bottom(a3) ; make top = bottom in upper cursor
bra.s @finis
@UseTop
move.w bottom(a0),teSelRect+bottom(a3) ; strech upper cursor
move.w bottom(a0),top(a0) ; make top = bottom in lower cursor
ENDIF
@finis
addq.l #2,sp ; restore stack (d5 pushed)
rts
IF NOT forLocalizability THEN ; <31a-YDS-8/27/91>
@ScrollDownBug
; when scrolling down the selRect top & bottom values are negative. this causes a large caret once divided
move.l ExpandMem,a0 ; <1/15/90smb>
sf ExpandMemRec.emTwoCursorsFlag(a0) ; <1/15/90smb>
addq.l #2,sp ; restore stack (d5 pushed)
rts
ENDIF
endwith
;formFeed
;----------------------------------------------------------------------
;
; OneCursor
; <12/13/88smb>
;
; The cursor is on a script boundary but surrounded by runs of
; the same script, therefore only one cursor is necessary. This
; routine sets up the selection rectangle at the position where
; the cursor should be displayed.
;
; Input
; a0: style run containing cursor
; a3: pointer to TE record
; d0: present style run's script id number
; d3: absolute position of cursor
; d5: total pixelWidth of style runs thus far in the line
; Modifies d5 (appropriately), d0.
;----------------------------------------------------------------------
OneCursor
with SharedFrame,TEFormatOrder
st doneFlag(a6) ; only need one cursor since not a cluster boundary
bsr.s GetDirection ; <30May89smb> cc's set
bne.s @RLScript
; LR Script
; if in previous style and LR script direction then measure since at end of style run
; if in cursor style width is 0 since at beginning of run so, have width to use <7Nov88smb>
tst.b prevStyleFlag(a6)
bne.s @MeasureRun ; bra to measure if in prevStyle's run
bra.s @finis
@RLScript
; if in cursor style and RL script direction then measure since at beginning of style run
; if in previous style and RL script direction AND
; if RL flow, width is 0 since at end of run so, have width to use <7Nov88smb>
; if LR flow, then measure since at beginning of RL script run <8Nov88smb>
tst.b prevStyleFlag(a6)
beq.s @MeasureRun ; bra to measure if in cursor's run
tst.b TESysJust
bne.s @finis ; don't branch if LR flow but RL script
@MeasureRun
Bsr MeasureWholeRun
add.w d0,d5
add.w d5,teSelRect+left(a3) ; left edge of rectangle
add.w d5,teSelRect+right(a3) ; right edge of rectangle
@finis
rts
endwith
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE SetDirection
; <30May89smb>
;
; Sets the direction of the current font in the stFace word in the
; StyleRecord by calling the Script Manager.
;
; Input:
; d1 = font number
; a0 = pointer to face+1 byte where to set the direction
;
; Output:
; Destroys d1.
; Preserves d0,d2,a0,a1.
; High bit of high-order byte of stFace(a0) set to direction.
;----------------------------------------------------------------------
SetDirection
movem.l d0/d2/a0/a1,-(SP) ; GetScript destroys these
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vSetDirection(a0),a0
jmp (a0)
xSetDirection
sub.w #6,sp ; allocate returns, 1 long, 1 int
move.w d1,-(sp) ; fontNumber param
_Font2Script ; returns script
move.w #smScriptRight,-(sp) ; pass verb
_GetScript
move.l (sp)+,d1 ; get byte equal to line direction
movem.l (SP)+,d0/d2/a0/a1 ; restore
bclr #7,(a0)
tst.b d1 ; right directional script?
beq.s @LeftDir ; bra if not
bset #7,(a0)
@LeftDir
Rts
;formFeed
;----------------------------------------------------------------------
;
; GetDirection
; <30May89smb>
;
; Gets the script direction for the current style run by getting
; it from the top bit of the high-order byte of the Face value
; that corresponds to the style index of the current style run
; (REMEMBER: the Face value is in different places for styled and
; unstyled teRecords).
;
; Input
; a0: ptr to current style run (for styled text)
; a3: ptr to teRecord (for unstyled text)
; Output
; d1.b: script direction (00 = LR/ $FF = RL)
; cc's set, but not all calling routines take advantage of this
; Preserves d0/a0.
;----------------------------------------------------------------------
GetDirection
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vGetDirection(a1),a1
jmp (a1)
xGetDirection
movem.l d0/a0,-(sp)
tst.w teSize(a3) ; <15June89smb>
bpl.s @Unstyled ; <15June89smb>
; styled text
move.w styleIndex(A0),D0 ; fetch index into style table
bsr GetStyle ; returns ptr to associated style table entry in a0
clr.w d1
move.b stFace+1(a0),d1 ; sets condition codes
bra.s @setRtn
@Unstyled
move.b teFace+1(a3),d1 ; get from the teRecord not the styleRec
@setRtn
beq.s @done
st d1 ; want the return value to be 00/FF <6June89smb>
@done
movem.l (sp)+,d0/a0
rts
;formFeed
;-----------------------------------------------------------------------------------------
;
; GetFormatOrdering
; <8Mar89smb>
;
; Created a routine that sets up format ordering information for styled and
; unstyled text.
;-----------------------------------------------------------------------------------------
GetFormatOrdering
with SharedFrame,TEFormatOrder
tst.w teSize(a3)
bmi.s @GetStyles ; bra if styled edit record
; old-style record: one style for the whole record. My code is expecting a0 to contain a ptr to
; the startChar for the current style so must fake the setup.
clr.l firstStyleRun(a6)
clr.l secondStyleRun(a6)
move.w teLength(a3),secondStyleRun(a6)
lea firstStyleRun(a6),a0
move.l a0,a2StyleRun(a6) ; save style run of lineStart as a ptr
move.w #1,d2
move.w d2,numberOfRuns(a6) ; save
lea.l fmtOrdering(a6),a1 ; <18Jan89smb>
move.l a1,fmtOrderingPtr(a6) ; <18Jan89smb>
clr.w fmtOrderingIndex(a6) ; <18Jan89smb>
clr.w (a1)
bra.s @done ; <4Jan88smb>
@GetStyles
move.w (a2),d0
move.w 2(a2),d1
bsr.s teGetFormatOrder ; <4Jan88smb>
@done
rts
endwith
;formFeed
;-------------------------------------------------------------------
;
; GetStylesInOrder
;
; This gets the ordering of format runs on a line and accesses
; the first display format order.
; <10Nov88smb>
; ENTRY
; d0 start offset
; d1 end offset
; a6 DoText's local frame: TextFrame;
;
; EXIT
; d2 number of styles still to process
; a0 ptr to next style for processing
; a1 ptr to storage area for format orderings
; fmtOrdering(a6) contains a handle (if allocated) to a storage area
; fmtOrderingPtr(a6) contains a pointer to a storage area
; condition codes set for evaluation
;
;-------------------------------------------------------------------
GetStylesInOrder
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vGetStylesInOrder(a0),a0
jmp (a0)
xGetStylesInOrder
with SharedFrame,TEFormatOrder
bsr.s teGetFormatOrder ; <9Jan89smb>
; get next style in a0 using the results from getFormatOrder
bsr GetNextDisplayStyle ; <4Jan89smb>
addq #1,fmtOrderingIndex(a6) ; incr the style run counter
SubQ #1,D2 ; dec the style counter
Rts
endwith
;formFeed
;-------------------------------------------------------------------
;
; teGetFormatOrder
;
; This routine orders the text properly for DISPLAY of bidirectional
; format runs on a line by calling the SMgr routine GetFormatOrder.
; We won't come in here unless the teRecord is styled!
;
; <10Nov88smb>
; ENTRY
; d0 start offset
; d1 end offset
; a3 dereferenced pointer to teRecord
; a6 DoText's local frame: TextFrame
; USES
; a0,a1,d0-d2
; EXIT
; d2 number of styles still to process
; a0 ptr to next style for processing
; a1 ptr to storage area containing correct ordering of format runs for DISPLAY
; fmtOrdering(a6) contains a handle (if allocated) to a storage area
; fmtOrderingPtr(a6) contains a pointer to a storage area
; condition codes set for evaluation
;-------------------------------------------------------------------
teGetFormatOrder
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vteGetFormatOrder(a0),a0
jmp (a0)
xteGetFormatOrder
FormatOrderRegs reg d2-d4
with SharedFrame,TEFormatOrder
moveq.l #0,d2
bsr GetCurStyle
; Made a2StyleRun(a6) an offset - can't save the ptr! (the handle's not locked!) Oh-Dopey-Me!
move.l teStylesH(a3),a1 ; <5Aug89smb>
move.l (a1),a1 ; deref <5Aug89smb>
sub.l a1,a0 ; save posn as an offset <5Aug89smb>
move.l a0,a2StyleRun(a6) ; save offset to style run of lineStart
add.l a1,a0 ; restore for GetNumStyles call!
bsr GetNumStyles ; number of runs on this line
move.w d0,d2
move.w d2,numberOfRuns(a6) ; save
Bsr GetStyleStorage ; <18Jan89smb> returns fmtOrdering array in a1
; Initialize fmtOrdering array with LR format ordering (0->d2) (aka: backin-store ordering)
moveq #0,d0
bra.s @CheckZero
@FillArray
move.w d0,(a1)+ ; fill 'er up!
addq.w #1,d0 ; next integer value for array
@CheckZero
dbra d2,@FillArray ; loop til d2 = -1
move.w numberOfRuns(a6),d2 ; restore
; determine if display order is different from backin-store order
clr.w fmtOrderingIndex(a6)
tst.b WordRedraw ; $FF if a R->L directional script installed
bge.s @finis
; call GetFormatOrder for correct display order for style runs
; test for only one style run <23June89smb>
move.l a0,-(sp) ; save
Move.L teStylesH(a3),a0 ; handle to style info
Move.L (a0),a0 ; dereference
cmpi.w #1,nRuns(a0) ; only one run?
beq.s @done ; yep, so done
move.l (sp)+,a0 ; restore
movem.l FormatOrderRegs,-(sp)
; parameter setup
move.l fmtOrderingPtr(a6),-(sp) ; formatOrder array
move.w #0,-(sp) ; 1st format
subq.w #1,d0
move.w d0,-(sp) ; last format (1 less than num of runs)
move.b TESysJust,-(sp) ; lineRight
pea teDirectionProc
; parameter for direction procedure
move.l a0,startStyleRun(a6) ; dirParam is the ptr to first style run and
move.l a3,teRecPtr(a6) ; and the pointer to the teRecord
pea.l directionParam(a6)
_GetFormatOrder ; returns display ordering in array
movem.l (sp)+,FormatOrderRegs
bra.s @finis
@done
move.l (sp)+,a0
@finis
rts ; return to sender!
endwith
;formFeed
;----------------------------------------------------------------------
;
; GetNextDisplayStyle
; <22Dec88smb>
; Does exactly what it's name says it does!
;
; On entry
; a6 = the local stack frame
; On exit
; a0 = pointer to next style run
; a1 = trashed
; d0 = trashed
;----------------------------------------------------------------------
GetNextDisplayStyle
with SharedFrame,TEFormatOrder
movea.l a2StyleRun(a6),a0
; For styled is an offset to desired posn in style run array, otherwise is a ptr <5Aug89smb>
; Made a2StyleRun(a6) an offset - can't save the ptr! (the handle's not locked!)
; Get to posn in styleRun array via the style handle and saved offset <5Aug89smb>
tst.w teSize(a3) ; <5Aug89smb>
bpl.s @Unstyled ; saved as a ptr for unstyled text! <5Aug89smb>
; styled teRec
move.l teStylesH(a3),a1 ; <5Aug89smb>
move.l (a1),a1 ; deref <5Aug89smb>
add.l a1,a0 ; add to offset to get desired posn in the array <5Aug89smb>
@Unstyled
move.w fmtOrderingIndex(a6),d0 ; index (0-d2) into array for next style run
lsl.w #1,d0 ; index into fmtOrdering array <27June89smb>
move.l fmtOrderingPtr(a6),a1
move.w 0(a1,d0.w),d0 ; index of style run to process
move.w d0,styleRunIndex(a6)
lsl.w #lnStStartSize,d0 ; offset in styleRun array <27June89smb>
lea.l 0(a0,d0.w),a0 ; pointer to next style run
rts
endwith
;formFeed
;----------------------------------------------------------------------
;
; GetStyleStorage
;
; This routine allocates a storage area for the ordering of
; style runs on this line in teGetFormatOrder. It will be in the
; local frame if the number of style runs on this line is small
; enough (<= #numStyleRuns). Otherwise, a handle is allocated
; for storage. It saves the handle in fmtOrdering(a6) and the
; pointer in fmtOrderingPtr(a6).
; <14Nov88smb>
;
; Entry:
; d2: number of style runs between the offsets in low word/ high word cleared
; a0: ptr to style run at first offset
; Exit:
; a0: preserved
; a1: ptr to storage area for ordering of style runs
; d2: preserved
; fmtOrderingPtr(a6): pointer to space for format ordering array
; Uses:
; d0
; Modifies fmtOrdering(a6) if a handle is allocated for storage
;----------------------------------------------------------------------
GetStyleStorage
StorageRegs reg d2/a0
with SharedFrame,TEFormatOrder
movem.l StorageRegs,-(sp)
; indicate a handle was NOT allocated
move.l ExpandMem,a0 ; <1Feb89smb>
sf ExpandMemRec.emFmtOrderHFlag(a0)
; initialize a1 for teGetFormatOrder call: wants a pointer to the storage area
lea.l fmtOrdering(a6),a1 ; may be replaced if too many style runs
move.l a1,fmtOrderingPtr(a6)
cmpi.w #numStyleRuns,d2
bls.s @done ; bra if fits ok <26June89smb> made unsigned
; local frame too small, get a handle to hold all the style runs on this line
move.l ExpandMem,a0 ; <1Feb89smb> indicate a handle was allocated
st ExpandMemRec.emFmtOrderHFlag(a0)
lsl.w #1,d2 ; mult number of style runs by 2 for byte cnt
move.l d2,d0
_NewHandle ,CLEAR ; allocate and clear a block and return handle in a0
bne.s @sysErr ; exit if system error
_HLock
bne.s @CleanUp
; dereference the handle and save
move.l (a0),a1 ; for teGetFormatOrder
move.l a0,fmtOrdering(a6) ; save handle
move.l (a0),fmtOrderingPtr(a6) ; need pointer for processing style runs
@done
movem.l (sp)+,StorageRegs
Rts
; OH NO!!!! can't get no memory!
@CleanUp
; deallocate handle in a0
move.l d0,-(sp) ; save initial error
_DisposHandle
move.l (sp)+,d0 ; restore initial error
@sysErr
_SysError ; go bye-bye with error in d0
endwith
;formFeed
;-------------------------------------------------------------------
;
; teDirectionProc
; <29Sept88smb>
;
; This routine returns the direction of a style run,
; 00 for Left and $FF for Right. It is called from
; the Script Manager routine GetFormatOrder.
;
; Function MyRLDirProc (theFormat: Integer;
; dirParam: Ptr): Boolean;
;
; Input:
; sp.w: theFormat
; sp.l: dirParam:
; - ptr into the styleRun array at the 1st offset's style run
; - pointer to the teRecord
; Output:
; a0 contains the return address at exit
; 00/$FF on the stack (sp.b) for direction
; Register Usage:
; a3 = teRecord
;------------------------------------------------------------------
teDirectionProc
DirFrame record {a6Link},decr
result ds.w 1 ; MyDirProc boolean result
argTop equ *
format ds.w 1 ; theFormat parameter
dirParam ds.l 1 ; dirParam parameter
argBottom equ *
return ds.l 1
a6Link ds.l 1
DirFrameSz equ *
EndR
DirProcRegs reg d0/d1/a1/a3
with DirFrame
link a6,#DirFrameSz
movem.l DirProcRegs,-(sp)
; get parameters: style run pointer and teRecord pointer
move.l dirParam(a6),a0
move.l (a0)+,a1 ; pointer to style run array
move.l (a0),a3 ; get to teRecord
move.w format(a6),d0
lsl.w #2,d0 ; incr ptr into styleRun array
move.l a1,a0 ; address of style run array
add.w d0,a0 ; new pointer to current style run <10jan89smb>
bsr GetDirection ; <10jan89smb>
move.b d1,result(a6) ; 0 => Left to Right; otherwise Right to Left <10jan89smb>
movem.l (sp)+,DirProcRegs
unlk a6
move.l (sp)+,a0 ; pop return
addq.l #(argTop-argBottom),sp
jmp (a0)
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; FreeFmtOrderArray
; <15Nov88smb>
; Determine if a handle for style runs needs to be deallocated
; and if so, do it!
;
;----------------------------------------------------------------------
FreeFmtOrderArray
with SharedFrame,TEFormatOrder
move.l ExpandMem,a0 ; <1Feb89smb>
tst.b ExpandMemRec.emFmtOrderHFlag(a0)
beq.s @NoHandle
; deallocate the handle that's saved in FmtOrdering(a6)
sf ExpandMemRec.emFmtOrderHFlag(a0)
move.l fmtOrdering(a6),a0
_DisposHandle
@NoHandle
rts
;formFeed
;----------------------------------------------------------------------
;
; DoHilite
;
; Modified to use SMgr HiliteText.
; ********* Be sure to notice the unusual use of link/unlk here *******
; ********* due to multiple line highlighting! *******
; Entry
; a3 pointer to locked edit record
; a4 handle to teRecord <27>
; d3 position of first character to redraw
; d4 position of last character to redraw
; a6 DoText's local frame: TextFrame
;----------------------------------------------------------------------
DoHilite
; If a Roman system then use old DoHilite code: HyperCard expects to hilite a whole region not three! <3Oct89smb>
move.l ExpandMem,a0
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a0) ; total number of installed scripts
beq RomanDoHilite ; use old DoHilite
; use this code for mixed directional text
Bsr PinDisplay
Bsr Preamble ; set rLine to A2 line, d5 = d4
; sets A2 to point to line containing d3
Bsr LineRect ; get top, bottom and just (from A2)
move.l a4,-(sp) ; need for OnSameLine vector <26June89smb>
with HiliteFrame
link a6,#HiLiteSz ; LineRect needs to access doText stack frame
movea.l a2,a1 ; save d3 lineStart
cmp.w d3,d4 ; wrong order?
beq @unLinkFrame
bhi.s @Get2ndLine ; no, correct
exg d3,d4 ; fix
; find out the first offset's line for Right to Left directional text
move.w d3,d0
lea teLines(a3),a2 ; point to line starts
bsr GetLine ; returns ptr to line in a2
bra.s @CompareLines
@Get2ndLine
; test if 2nd offset is at the end of the 1st offset's line <2Dec88smb>
cmp.w 2(a2),d4 ; <2Dec88smb>
beq.s @CompareLines ; <2Dec88smb>
; get the second offset's line. Already have lineStart for d3 in a1
move.w d4,d0
bsr GetLine ; returns ptr to line in a2
@CompareLines
exg a1,a2
cmpa.l a1,a2
bne.s @MultipleLines ; over multiple lines
bsr xOnSameLine ; skip the vector code since it wipes out a4 <27>
bra @unLinkFrame
@MultipleLines
; [d3,d4] over multiple line
; set up for line containing d3
move.l a1,d4Line(a6) ; save lineStart for d4 for later
move.l a2,d3Line(a6)
move.w d4,savD4(a6)
move.w 2(a2),d4 ; end of d3 line
bsr xOnSameLine ; skip the vector code since it wipes out a4 <27>
; set up for line containing d4
move.w savD4(a6),d4
move.l d4Line(a6),a2 ; LineRect wants the current line in a2
move.w (a2),d3 ; beginning of d3 line
; ********* Be sure to notice the unusual use of link/unlk here *******
; ********* due to multiple line highlighting! *******
move.l d3Line(a6),a1 ; temp for unlink
unlk a6 ; unlink HiliteFrame for LineRect *********
move.w teSelRect+bottom(a3),-(sp) ; save for middle rectangle's top edge
move.l a1,-(sp) ; save d3's line
bsr LineRect ; get top, bottom and just (from A2)
bsr xOnSameLine ; skip the vector code since it wipes out a4 <27>
move.l (sp)+,a1 ; d3's line
; now hilite the middle rectangle, between the lines containing the offsets.
; a1 = ptr to line containing d3
; a2 = ptr to line containing d4
; tests for lines inbetween 1st and last
move.w 2(a1),d2 ; end of 1st line
cmp.w (a2),d2 ; end of 1st rectangle = beginning of last rectangle
beq.s @noMidRect ; done: no middle rectangle
;------------------------------------------- <16>
IF hasInlineInput THEN ; <16>
; if inlineInput then don't want to hilite to edge of selRect, only to text boundaries <16>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFInlineInput,d0 ; is this Inline Input feature desired?
beq.s @HiliteMiddle ; no, so hilite middle rect as one!
; inline input so measure the middle rectangle of text
; a1 = ptr to line containing d3
; a2 = ptr to line containing d4
@AnotherLine
move.w d2,d3 ; d2 contains the new d3
add.w #2,a1 ; increment to pt to line containing new d3
move.w 2(a1),d4
movem.l a1/a2,-(sp) ; save d3 & d4's line
move.l a1,a2 ; LineRect wants the current line in a2
bsr LineRect ; get top, bottom & just (from a2)
bsr xOnSameLine ; skip the vector code since it wipes out a4 <27>
movem.l (sp)+,a1/a2
move.w 2(a1),d2 ; end of d3's line
cmp.w (a2),d2 ; end of d3's line = beginning of last line?
bne.s @AnotherLine ; bra if another line to measure & hilite
bra.s @noMidRect ; otherwise done <16>
ENDIF ; <16>
;------------------------------------------- <16>
; set up selRect(a3)
@HiliteMiddle
move.w teSelRect+top(a3),teSelRect+bottom(a3) ; top of last rect = bottom of middle rect
move.w (sp)+,teSelRect+top(a3) ; bottom of 1st rect = top of middle rect
Move.W #UnboundLeft,teSelRect+left(a3) ; far left
Move.W #UnboundRight,teSelRect+right(a3) ; far right
Move.L teHiHook(a3),D0 ; do the inversion via hook if exists
Bsr InvertHook ; hilite it
bra.s @finis
@noMidRect
addq #2,a7 ; don't need saved pixelWidth for top edge
bra.s @finis
@unLinkFrame
; ********* Be sure to notice the unusual use of link/unlk here *******
; ********* due to multiple line highlighting! *******
unlk a6 ; unlink HiliteFrame
@finis
move.l (sp)+,a4 ; restore handle <26June89smb>
bra doBye
endWith
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RomanDoHilite
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 @done ; done... <C971/RWW102887>NO
Bsr 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 @done ; 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 @LastLine ; 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 #UnboundLeft,teSelRect+left(A3) ; far left
Move.W #UnboundRight,teSelRect+right(A3) ; far right
Move.L teHiHook(A3),D0
Bsr InvertHook ; hilite it
Move.W (SP)+,D0 ; restore line #
; hilite last line
@LastLine
Bsr NextLineRect ; get rectangle for last line <C971/RWW102887>NO
Move.W (A2),D3 ; for chkBounds
Bsr PrepLine ; get left and right
Bls.S @done ; done...
Bsr ChkBounds ; check far left and right <C971/RWW102887>NO
Move.L teHiHook(A3),D0 ; do the inversion via hook if
Bsr InvertHook ; there
@done
Bra doBye
;formFeed
;----------------------------------------------------------------------
;
; OnSameLine
;
; <12Oct88smb>
;
; Get the format ordering for the current line containing d3.
; Hilite appropriately in the style runs containing character
; offsets d3 & d4. Use the format ordering to hilite the
; necessary runs in between the two runs.
;
; Input:
; d0 = initial L edge of selection rectangle
; d1 = initial R edge of selection rectangle
; d3 = 1st character position to redraw
; d4 = 2nd character position to redraw
; d5 = 0; cleared to accumulate widths of style runs
;
; a0 = ptr to startChar for style of 1st character position
; a1 = lineStart of current line containing d4
; a2 = lineStart of current line containing d3
;
; Output:
; d5 = pixelWidth of the line, up to the 1st character position
;
;----------------------------------------------------------------------
OnSameLine
move.l ExpandMem,a4 ; <28June89smb>
move.l ExpandMemRec.vOnSameLine(a4),a4
jmp (a4)
xOnSameLine
SameLineRegs reg d3/d4/d7/a0-a1
with SharedFrame,TEFormatOrder
link a6,#SharedFrameSz
movem.l SameLineRegs,-(sp)
; initialize
moveq.l #0,d5 ; cleared to accumulate widths of style runs from MeasureWidth and PixelWidths
moveq.l #0,d2
clr.w totalWidth(a6)
clr.w hiliteInbetween(a6) ; set sameStyle and hiliteInbetween to F.
sf doneFlag(a6)
clr.w foundD4(a6) ; clear D3 and D4 index flag
clr.l d4FmtIndex(a6) ; clear D3 and D4 holders
clr.l hiliteREndFlag(a6) ; clear left and right end flags
Move.w teSelRect+left(A3),selRectL(a6) ; preserve initial L. edge
Move.w teSelRect+right(A3),selRectR(a6) ; preserve initial R. edge
Move.w selRectL(a6),anchorL(a6) ; initialize L. anchor
Move.w selRectR(a6),anchorR(a6) ; initialize R. anchor
; [d3,d4] are on the same line
tst.w teSize(a3)
bpl @oldStyle ; old style edit record
; get style runs for character offsets
move.w d3,d0
bsr GetCurStyle
; made d3StyleRun(a6) an offset - can't save the ptr! (the handle's not locked!) Oh-Dopey-Me!
move.l a0,-(sp) ; save <19Aug89smb>
move.l teStylesH(a3),a1 ; <19Aug89smb>
move.l (a1),a1 ; deref <19Aug89smb>
sub.l a1,a0 ; save posn as an offset <19Aug89smb>
move.l a0,d3StyleRun(a6) ; save offset to style run of lineStart
move.l (sp)+,a0 ; restore for FixFormatEnd call<19Aug89smb>
bsr FixFormatEnd ; get real end position of run <6Mar89smb>
cmp.w d0,d4
bhi.s @GetD4Style
; in same style run as d3
; made d4StyleRun(a6) an offset - can't save the ptr! (the handle's not locked!) Oh-Dopey-Me!
move.l teStylesH(a3),a1 ; <19Aug89smb>
move.l (a1),a1 ; deref <19Aug89smb>
sub.l a1,a0 ; save posn as an offset <19Aug89smb>
move.l a0,d4StyleRun(a6) ; save as offset
bra.s @GetDisplayOrder
@GetD4Style
move.w d4,d0
bsr GetCurStyle
cmp.w startChar(a0),d4 ; is d4 the start of this run? <29June89smb>
bne.s @SaveD4StyleRun ; bra if not. the style is correct. <29June89smb>
; Otherwise, want the previous style run since d4 is on a boundary, and it indicates the rightmost
; end of the hilite rectangle. d4StyleRun in this case, should be a pointer to the style run which
; ends w/ d4, not begins w/ d4. GetCurStyle doesn't give us what we need, so fix it! <29June89smb>
subq.l #stStartSize,a0
@SaveD4StyleRun
; made d4StyleRun(a6) an offset - can't save the ptr! (the handle's not locked!) Oh-Dopey-Me!
move.l teStylesH(a3),a1 ; <19Aug89smb>
move.l (a1),a1 ; deref <19Aug89smb>
sub.l a1,a0 ; save posn as an offset <19Aug89smb>
move.l a0,d4StyleRun(a6) ; save as offset
@GetDisplayOrder
move.w (a2),d0
move.w 2(a2),d1
Bsr teGetFormatOrder ; <4Jan88smb>
; Made d3StyleRun(a6) & d4StyleRun(a6) an offset - can't save the ptr! (unlocked handle!)
; Get to posn in styleRun array via the Style Handle and saved offset after moving memory
; in teGetFormatOrder <19Aug89smb>
move.l teStylesH(a3),a0 ; <19Aug89smb>
move.l (a0),a0 ; deref <19Aug89smb>
move.l a0,-(sp) ; <19Aug89smb>
adda.l d3StyleRun(a6),a0 ; <19Aug89smb>
move.l a0,d3StyleRun(a6) ; add in offset to desired posn in the array <19Aug89smb>
move.l (sp)+,a0 ; <19Aug89smb>
adda.l d4StyleRun(a6),a0 ; <19Aug89smb>
move.l a0,d4StyleRun(a6) ; add in offset to desired posn in the array <19Aug89smb>
; get the format order indexes for the character offsets (could be the same)
@Loop4Indexes
Bsr GetNextDisplayStyle ; <22Dec88smb>
addq #1,fmtOrderingIndex(a6) ; incr the format ordering array counter
SubQ #1,D2 ; dec the style counter
; is this the same style run as one of the character offsets?
cmpa.l d3StyleRun(a6),a0
bne.s @testD4
move.w styleRunIndex(a6),d3FmtIndex(a6)
tst.b foundD4(a6)
bne.s @MeasureNow ; have both offsets' indeces in the fmt array
st foundD3(a6)
@testD4
cmpa.l d4StyleRun(a6),a0
bne.s @Loop4Indexes
move.w styleRunIndex(a6),d4FmtIndex(a6)
tst.b foundD3(a6)
bne.s @MeasureNow ; have both offsets' indeces in the fmt array
st foundD4(a6)
bra.s @Loop4Indexes
; measure by style runs and highlight where appropriate based on character offsets
; and display ordering of format runs!
@MeasureNow
move.w numberOfRuns(a6),d2
clr.w fmtOrderingIndex(a6)
; test if [d3,d4] in same style run
move.w d3FmtIndex(a6),d0
cmp.w d4FmtIndex(a6),d0
bne.s @MeasureLoop
st sameStyle(a6)
@MeasureLoop
Bsr GetNextDisplayStyle ; <22Dec88smb>
Bsr MeasureWidth
tst.b doneFlag(a6)
bne.s @hiliteMore
addq #1,fmtOrderingIndex(a6) ; incr the format ordering array counter
tst.b WordRedraw ; <4Oct89smb>
bge.s @GetNext ; <4Oct89smb>
SubQ #1,D2 ; dec the style counter
beq.s @hiliteMore
bra.s @MeasureLoop
@GetNext
Addq.l #stStartSize,a0 ; get next style
SubQ #1,D2 ; dec the style counter
bne.s @MeasureLoop ; must be more than 1 line
bra.s @hiliteMore
@oldStyle
; old-style record: one style for the whole record. My code is expecting a0 to contain a ptr to
; the startChar for the current style so must fake the setup.
clr.l firstStyleRun(a6) ; startChar and style index (both 0)
clr.w secondStyleRun(a6) ; startChar of second style run (EO array)
move.w teLength(a3),secondStyleRun(a6)
lea firstStyleRun(a6),a0
Bsr teHiliteText
@hiliteMore
; test if there's more to hilite: either more style runs or line ends
tst.b hiliteInbetween(a6)
beq.s @testEnds
bsr HiliteMiddle ; hilite any remaining runs inbetween offsets
sf hiliteInbetween(a6)
@testEnds
tst.b hiliteLEndFlag(a6)
beq.s @testRightEnd
; hilite left end of display line
move.w selRectL(a6),teSelRect+right(a3)
move.w #UnboundLeft,teSelRect+left(a3)
; top and bottom edges should be the same
move.l a0,-(sp) ; <24Jan89smb> save for unstyled text
Move.L teHiHook(A3),D0 ; do the inversion via hook if exists
Bsr InvertHook ; hilite it
sf hiliteLEndFlag(a6)
move.l (sp)+,a0 ; <24Jan89smb> need for hiliting on right end of unstyled text
@testRightEnd
tst.b hiliteREndFlag(a6)
beq.s @finis
; hilite right end of display line
tst.w teSize(a3) ; <5Dec88smb>
bmi.s @UseAnchor
bsr MeasureWholeRun ; need length of line for unstyled <5Dec88smb>
move.w d0,teSelRect+left(a3) ; <5Dec88smb>
bra.s @addSelRect ; <5Dec88smb>
@UseAnchor
move.w anchorR(a6),teSelRect+left(a3) ; <25Oct88smb>
@addSelRect
move.w selRectL(a6),d0
add.w d0,teSelRect+left(a3) ; <25Oct88smb>
move.w #UnboundRight,teSelRect+right(a3)
; top and bottom edges should be the same
Move.L teHiHook(A3),D0 ; do the inversion via hook if exists
Bsr InvertHook ; hilite it
sf hiliteREndFlag(a6)
@finis
bsr FreeFmtOrderArray ; <18Jan89smb>
movem.l (sp)+,SameLineRegs
unlk a6
Rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; MeasureWidth
;
; <12Oct88smb>
;
; Get the width of each style run and hilite when appropriate.
; We never come in here if we have an old single style teRec!
;
; Input:
; d3 = 1st character position to redraw
; d4 = 2nd character position to redraw
;
; a0 = ptr to startChar for style of 1st character position
; a2 = lineStart of current line containing d3
;
; Output:
; d5 = pixelWidth of the measured style runs
;
;----------------------------------------------------------------------
MeasureWidth
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vMeasureWidth(a1),a1
jmp (a1)
xMeasureWidth
with SharedFrame,TEFormatOrder
; is this d3's style run?
move.w styleRunIndex(a6),d0
cmp.w d3FmtIndex(a6),d0
beq.s @MeasureD3Run
tst.b sameStyle(a6)
bne @justMeasure ; bra if [d3,d4] in same style
; is this d4's style run?
cmp.w d4FmtIndex(a6),d0
beq.s @MeasureD4Run
blt.s @inBetween ; bra to check if inbetween d3 & d4 runs
bra @justMeasure ; not to be hilited: just measure
@MeasureD3Run
; measure [d3,end of style]
move.w d3,saveD3(a6)
move.w d4,saveD4(a6)
tst.b sameStyle(a6)
bne.s @TestDirection ; when in RL text may need to measure the rest of the line <25Oct88smb>
bsr FixFormatEnd ; <6Mar89smb>
move.w d0,d4 ; <6Mar89smb>
bra.s @dontQuit
@MeasureD4Run
; measure [begin of style,d4]
move.w d3,saveD3(a6)
move.w d4,saveD4(a6)
move.w startChar(a0),d3
@TestDirection
tst.b teSysJust ; RL line direction (Roman, Kanji or Arabic)? <29Aug89smb>
bne.s @dontQuit ; yep, not done at this style run <29Aug89smb>
tst.b WordRedraw ; <4Oct89smb
blt.s @dontQuit ; <4Oct89smb
st doneFlag(a6) ; once hilited d4
@dontQuit
tst.b hiliteInbetween(a6)
beq.s @HiliteOffsetRun ; nothing inbetween: just hilite the offset's run
bsr HiliteMiddle ; hilite runs prior to offset run, then the offset run
bra.s @HiliteOffsetRun
@inBetween
; test if style run in between d3 and d4's style runs!
cmp.w d3FmtIndex(a6),d0
bhi.s @hiliteRun ; bra to be hilited <26June89smb> made unsigned
; not inbetween therefore, only measure. don't hilite
bsr.s MeasureWholeRun
add.w d0,totalWidth(a6)
tst.b hiliteInbetween(a6)
beq.s @exit
bsr HiliteMiddle ; hilite runs prior to non-hilited run
move.w totalWidth(a6),d0
add.w d0,anchorL(a6) ; new left anchor
bra.s @exit
@hiliteRun
; This run is between d3 and d4 and needs to be hilited at some later time.
; Test if this style run contains the lineStart or lineEnd and if so, then must extend the
; highlighting to the screen's edge!
move.w startChar(a0),d0 ; get the beginning of the style run
move.w stStartSize(a0),d1 ; get the end of the style run
Bsr HiliteLineEnds ; test and set a flag
tst.b hiliteInbetween(a6)
bne.s @addToAnchor
; new run of runs inbetween d3 and d4 to be hilited
st hiliteInbetween(a6)
move.w totalWidth(a6),anchorL(a6) ; new left anchor
move.w totalWidth(a6),anchorR(a6) ; new right anchor
@addToAnchor
bsr.s MeasureWholeRun
add.w d0,totalWidth(a6) ; accumulates the overall width
add.w d0,anchorR(a6) ; save for hiliting middle rectangle
bra.s @exit
@HiliteOffsetRun
; hilite the appropriate part of the offset's style run
bsr teHiliteText
move.w saveD3(a6),d3
move.w saveD4(a6),d4
; measure the length of the style run and add to overall line width
@justMeasure
bsr.s MeasureWholeRun ; add width of style run to total width of line
add.w d0,totalWidth(a6)
move.w totalWidth(a6),anchorR(a6) ; possible new Left anchor for next hilite region
@exit
Move.w totalWidth(a6),d5
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; MeasureWholeRun
;
; Input:
; a0: current style run
; a2: lineStart
; a3: pointer to TERecord
;
; Uses: a0/a1/d0/d1
; a4: textPtr for textWidth
;
; Output:
; d0: width of style run
;----------------------------------------------------------------------
MeasureWholeRun
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vMeasureWholeRun(a1),a1
jmp (a1)
xMeasureWholeRun
WholeRunRegs reg d2/a0/a4
movem.l d2/a0,-(sp) ; <27>
move.l a4,-(sp) ; separate out so can restore teHandle to a4 before hook call <27>
Movea.l a0,a1 ; save beginning posn of current style
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
Add.w (a1),a0 ; add beginning of the style run to get to desired line
move.l a0,a4
movea.l a1,a0 ; restore current style run
; If style run starts on previous line, then pin text pointer to start of current line
moveq #0,d1 ; used to adjust length
Move.w (a2),d0 ; beginning of line
cmp.w startChar(a0),d0
;;<21June89smb> bcs.s @getLength ; bra if lineStart is prior to the styleRun start
bls.s @getLength ; bra if lineStart is prior or equal to the styleRun start <21June89smb>
; Adjust text pointer and length for lineStart within styleRun
sub.w startChar(a0),d0 ; difference from start of styleRun to lineStart
add.w d0,a4 ; pin pointer to beginning of line
move.w d0,d1 ; save for length adjustment below
; If style run ends on next line, then use the current line's end for determining length!
@getLength
bsr FixFormatEnd ; <6Mar89smb> returns end of style run in d0
cmp.w 2(a2),d0 ; inside the line's end?
bls.s @UseStyleEnd ; <26June89smb> made unsigned
move.w 2(a2),d0 ; use the line's end
@UseStyleEnd
sub.w startChar(a0),d0
sub.w d1,d0 ; adjust for LineStart
tst.w teSize(a3) ; <1Dec88smb>
bpl.s @DontSet
movem.l d0/d1,-(sp) ; SetStyle mucks with this guy - not good!
bsr SetStyle ; set grafport style from current style in a0
movem.l (sp)+,d0/d1
@DontSet
;get PixelWidth of this style on this line
IF hasTextWidthHook THEN ; <18>
move.l a4,a0 ; wants text ptr here <18>
moveq #0,d1 ; wants offset here <18>
move.l (sp)+,a4 ; restore teHandle to a4 <27>
bsr TETextWidthHook ; hook out TextWidth <18>
ELSE ; <18>
subq.l #2,sp ; room for result
move.l a4,-(sp) ; ptr on stack
move.w #0,-(sp) ; offset to first char
move.w d0,-(sp) ; length of block
_TextWidth ; how wide is it?
moveq #0,d0
move.w (sp)+,d0 ; width
ENDIF ; <18>
movem.l (sp)+,d2/a0 ; already restored a4 before TETextWidthHook call <27>
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; HiliteMiddle
;
; Hilite measured runs between d3 and d4
;
; Input:
; a3: pointer to teRec
;
; Uses: d0 (preserved)
;
;----------------------------------------------------------------------
HiliteMiddle
with SharedFrame,TEFormatOrder
movem.l d0/d2/a0,-(sp)
; do middle rectangle
move.w selRectL(a6), teSelRect+left(a3) ; left edge
move.w anchorL(a6),d0
add.w d0,teSelRect+left(a3)
move.w selRectR(a6), teSelRect+right(a3) ; right edge
move.w anchorR(a6),d0
add.w d0,teSelRect+right(a3)
; top and bottom edges should be the same
move.l teHiHook(a3),d0 ; do the inversion via hook if exists
bsr InvertHook ; hilite it
sf hiliteInbetween(a6)
movem.l (sp)+,d0/d2/a0
Rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; HiliteLineEnds
;
;
; This routine tests if the regions to be highlighted on a line
; should include the visible screen at both ends of the line.
;
; The visible left end of the displayed line should be hilited if:
; 2(a2) is in a hilited region and TESysJust = RL
; (a2) is in a hilited region and TESysJust = LR
; The visible right end of the displayed line should be hilited if:
; 2(a2) is in a hilited region and TESysJust = LR
; (a2) is in a hilited region and TESysJust = RL
;
; Input
; a2 = ptr to lineStart of current line
; d0 = beginning of region to be highlighted
; d1 = end of region to be highlighted
;
;----------------------------------------------------------------------
HiliteLineEnds
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vHiliteLineEnds(a1),a1
jmp (a1)
xHiliteLineEnds
with SharedFrame,TEFormatOrder
; test if ends of line should be highlighted
; test line start
cmp.w (a2),d0
bhi.s @testLineEnd ; bra if outside region to be highlighted <26June89smb> made unsigned
cmp.w (a2),d1
bcs.s @testLineEnd ; bra if outside region to be highlighted
tst.b TESysJust ; beginning of line: hilite to display's edge <26June89smb> made unsigned
bne.s @lineStartIn
st hiliteLEndFlag(a6) ; left rect should be highlighted for LR flow
bra.s @testLineEnd
@lineStartIn
st hiliteREndFlag(a6) ; right rect should be highlighted for RL flow
@testLineEnd
; test line end
cmp.w 2(a2),d0
bhi.s @done ; <26June89smb> made unsigned
cmp.w 2(a2),d1
bcs.s @done ; bra if outside region to be highlighted <26June89smb> made unsigned
tst.b TESysJust
bne.s @lineEndIn
st hiliteREndFlag(a6) ; left rect should be highlighted for LR flow
bra.s @done
@lineEndIn
st hiliteLEndFlag(a6) ; right rect should be highlighted for RL flow
@done
Rts
;formFeed
;----------------------------------------------------------------------
;
; teHiliteText
;
; <27Sept88smb>
;
; Setup for and call to HiliteText (which works on a single format
; run). Returns offsets within a format run of character positions
; for highlighting.
;
; Identify runs of characters for highlighting between d3 & d4.
;
; Entry:
; d3 = 1st char posn to measure from
; d4 = 2nd char posn to measure to
; a0 = ptr to current style
; a2 = lineStart array
; Use:
; d0,d1 = scratch
; a4 = ptr to offsetPairs address, to be returned from HiliteText
; Exit:
; registers preserved from entry but, the offsetPairs values (ptr in a4)
; have been filled in.
;
;----------------------------------------------------------------------
teHiliteText
HiliteTxtRegs reg d2-d4/a0/a1
with SharedFrame,TEFormatOrder
tst.w teSize(A3) ; check style flag
bpl.S @DontSet ; don't set style: old-style edit record
bsr SetStyle ; set grafport style from current style in a0
@DontSet
; call HiliteText (which works on a single fmt run) on [d3,d4]
move.l a4,-(sp) ; preserve <22Dec88smb>
Lea offPairs(a6),a4
Movem.L HiliteTxtRegs,-(SP)
; the textPtr will be the beginning of the style run, and the offsets will be the distance from
; d3 and d4 to the start of the style run.
Movea.l a0,a1 ; temp
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; dereference
Add.w (a1),a0 ; add beginning of the style run to get to desired line
; test if style run starts on previous line, and if so adjust textptr <5Dec88smb>
moveq #0,d1
move.w (a2),d0 ; linestart
cmp.w startChar(a1),d0
bls.s @UseStyleStart ; <26June89smb> made unsigned
; pin to beginning of line <5Dec88smb>
sub.w startChar(a1),d0 ; |beginning of line - beginning of style run|
add.w d0,a0 ; fix text ptr
move.w d0,d1 ; save difference for length and offset adjustments
@UseStyleStart
move.l a0,-(sp) ; push text ptr parameter for _HiliteText
; test if style run ends on next line, and if so pin to end of this line & adjust length <5Dec88smb>
move.l a0,-(sp) ; <6Mar89smb>
move.l a1,a0 ; <6Mar89smb>
bsr FixFormatEnd ; <6Mar89smb> returns in d0
move.l (sp)+,a0 ; <6Mar89smb>
cmp.w 2(a2),d0
bls.s @UseStyleEnd ; <26June89smb> made unsigned
move.w 2(a2),d0 ; pin to line end
@UseStyleEnd
sub.w startChar(a1),d0 ; text length is overall style run length
sub.w d1,d0 ; adjust for lineStart
move.w d0,-(sp)
sub.w startChar(a1),d3 ; 1st offset within style run
sub.w d1,d3 ; adjust for lineStart
move.w d3,-(sp)
sub.w startChar(a1),d4 ; 2nd offset within style run
sub.w d1,d4 ; adjust for lineStart
move.w d4,-(sp)
move.l a4,-(sp) ; var offsets record
_HiliteText
Movem.L (sp)+,HiliteTxtRegs
; HiliteText returns 3 pairs of possibly disjoint char offsets within a style run for highlighting.
moveq #2,d7 ; set up dbra:counter for OffsetTable pairs
@tblLoop
move.w (a4)+,d0 ; get offset1 of pair
move.w (a4)+,d1 ; get offset2 of pair
cmp.w d0,d1 ; equal?
beq.s @nxtPair ; yes,skip: pair is empty
; process a pair from HiLiteText
Move.l a4,-(sp) ; preserve pairs counter and offset pairs
; want to restore a4 to contain the teHandle <27>
move.l 4(sp),a4 ; teHandle on the stack <27>
Bsr.s xInvrtRectangle ; skip the vector to avoid wiping out a4! <27>
Move.l (sp)+,a4
@nxtPair
dbra d7,@tblLoop ; loop thru record
move.l (sp)+,a4 ; restore original value <22Dec88smb>
Rts
;formFeed
;----------------------------------------------------------------------
;
; InvrtRectangle
; <21June88smb>
;
; Calls Char2Pixel to get the pixel widths for the left and right
; side of a rectangle needing highlighting, finishes setting
; up the rectangle and inverts it. Makes Char2Pixel calls for each
; element of pair.
;
; Input
; a0 = ptr to beginning of current style run
; a2 = lineStart of current line
;
; d0 = 1st offset position within current style run
; d1 = 2nd offset position within current style run
; d5 = pixel width from MeasureAndHilite routine
;
; Register Usage:
; d5 = pixel width of 1st character in pair
; d6 = pixel width of 2nd character in pair
;
; Output
; a0,d0,d1,d2 preserved
; d5 = incremented by last pixel width: total width of line so far
;
;----------------------------------------------------------------------
InvrtRectangle
move.l ExpandMem,a4 ; <28June89smb> use it since already saved!
move.l ExpandMemRec.vInvrtRectangle(a4),a4
jmp (a4)
xInvrtRectangle
InvrtRectRegs reg d0/d1/a0/a1
with SharedFrame,TEFormatOrder
Move.w d2,-(sp)
;; moved below since saved in PixelWidths <5Dec89smb> Movem.l InvrtRectRegs,-(sp)
Move.w d5,-(sp) ; save pixel width from MeasureAndHilite routine
move.w #smHilite,d2 ; 1st offset's direction param
swap d2
move.w #smHilite,d2 ; 2nd offset's direction param
Bsr.s PixelWidths ; Calls Char2Pixel for each element of hilite pair
; returns pixelwidths of both elements in d5 & d6
; Check pixel widths for stroke direction.
cmp.w d5,d6 ; which is true left/right edge of rectangle
bcs.s @rightLeft ; bra if right-left text
add.w selRectR(a6),d5 ; need dest rect right edge added on
add.w (sp),d5 ; add pixel width of previous runs on line
add.w selRectR(a6),d6 ; need dest rect right edge added on
add.w (sp),d6 ; add pixel width of previous runs on line
bra.s @edgesOK
@rightLeft
; right to left
add.w selRectL(a6),d5 ; need dest rect left edge added on
add.w (sp),d5 ; add pixel width of previous runs on line
add.w selRectL(a6),d6 ; need dest rect left edge added on
add.w (sp),d6 ; add pixel width of previous runs on line
exg d5,d6 ; swap for R-L text.
@edgesOK ; call InvertRect on pair (set up selRect)
Movem.l InvrtRectRegs,-(sp) ; <5Dec89smb>
move.w d5,teSelRect+left(A3) ; left edge of rectangle
move.w d6,teSelRect+right(A3) ; right
Move.L teHiHook(A3),D0 ; do the inversion via hook if exists
Bsr InvertHook ; hilite it
Movem.l (sp)+,InvrtRectRegs
Move.w (sp)+,d5 ; restore pixel width from MeasureAndHilite routine
; Test whether should also hilite visible (screen) line start and end. Must first determine
; whether style run should be pinned to the start of the line.
move.w (a2),d2 ; <22Dec88smb>
cmp.w startChar(a0),d2 ; <22Dec88smb>
bls.s @UseStyleStart ; <22Dec88smb> <26June89smb> made unsigned
; pin to lineStart to get buffer position of offsets
add.w d2,d0 ; <22Dec88smb>
add.w d2,d1 ; <22Dec88smb>
bra.s @TestEnds
@UseStyleStart
add.w startChar(a0),d0 ; buffer position of 1st offset in line
add.w startChar(a0),d1 ; buffer position of 2nd offset in line
@TestEnds
cmp.w d0,d1 ; <5Dec89smb>
bcc.s @OffsetsOK ; <5Dec89smb>
exg d0,d1 ; swap for R-L text <5Dec89smb>
@OffsetsOK
IF hasInlineInput THEN ; <16>
; if inline input is on then don't hilite to the end of the selRect! <16>
movem.l a0/d2,-(sp) ; must preserve <16>
move.l teDispatchH(a3),a0 ; <16>
move.l (a0),a0 ; <16>
move.l newTEFlags(a0),d2 ; move into reg for modulo 32 bit ops <16>
btst #teFInlineInput,d2 ; is this Inline Input feature desired? <16>
movem.l (sp)+,a0/d2 ; restore now <16>
bne.s @NoLineEnds ; yes, so don't hilite line ends! <16>
ENDIF ; <16>
Bsr HiliteLineEnds
@NoLineEnds ; <16>
Move.w (sp)+,d2
Rts
;formFeed
;----------------------------------------------------------------------
;
; PixelWidths
;
; Setup for and call to Char2Pixel
;
; Input
; a0 = ptr to beginning of current style run
; a2 = LineStart of current line
;
; d0 = offset of 1st element of hilite pair in style run
; d1 = offset of 2nd element of hilite pair in style run
; d2.l = direction params for C2P for both offsets (second offset/first offset: High/Low)
;
; Output
; d5 = pixel width from start of run to 1st element.
; d6 = pixel width from start of run to 2nd element.
;
; -------------------------------
; Need to set up...
; a0 = start of text to be measured
; a4 = direction values and teHandle! <27>
; d0 = overall style run length
; d1 = length from start of measured text to end
; d2 = slop & highlight
; -------------------------------
;----------------------------------------------------------------------
PixelWidths
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vPixelWidths(a1),a1
jmp (a1)
xPixelWidths
; remove a4 from these lists of registers <27>
PixelWidthRegs reg d0-d4/a0-a2 ; <27>
C2Pparams reg d0/a0/a1 ; length, direction, textPtr, styleRunPtr <27>
Movem.l PixelWidthRegs,-(sp)
move.l a4,-(sp) ; save the teHandle <27>
move.l ExpandMem,a4 ; <1Feb89smb>
move.l d2,ExpandMemRec.emDirection(a4) ; <27Oct88smb> direction for both offsets passed in
Movea.l a0,a1 ; save beginning posn of current style
Move.L teTextH(a3),a0 ; get text handle
Move.L (a0),A0 ; dereference
Add.w (a1),a0 ; add beginning of the style run to get to desired line
; 1st offset's width
move.w d1,-(sp) ; save 2nd offset
; test if style run starts on previous line, and if so adjust textptr & offset posn in run
move.w d0,d1 ; Char2Pixel wants the start offset here
moveq #0,d4
move.w (a2),d0 ; linestart
cmp.w startChar(a1),d0
bls.s @getLength ; bra if so => offset is ok <26June89smb> made unsigned
; pin to beginning of this line
sub.w startChar(a1),d0 ; |begin of line - begin of the style run|
add.w d0,a0 ; fix text ptr
move.w d0,d4 ; save difference for length adjustment
@getLength
; test if style run ends on next line, and if so pin to end of this line & adjust length
move.l a0,-(sp) ; <6Mar89smb>
move.l a1,a0 ; <6Mar89smb>
bsr FixFormatEnd ; <6Mar89smb> returns in d0
move.l (sp)+,a0 ; <6Mar89smb>
move.w teLength(a3),d2 ; <11>
cmp.w (a2),d2 ; at the end of the text? <11>
beq.s @UseStyleEnd ; yes -> use style end <11>
cmp.w 2(a2),d0 ; style contained in the line?
bls.s @UseStyleEnd ; yes -> use style end.
move.w 2(a2),d0 ; pin to end of line.
@UseStyleEnd
sub.w startChar(a1),d0 ; Char2Pixel wants the length here
sub.w d4,d0 ; adjust for lineStart
clr.l d2 ; <27Oct88smb>
move.l ExpandMem,a4 ; <1Feb89smb>
lea ExpandMemRec.emDirection(a4),a4 ; changed to lea <12July89smb>
move.w (a4)+,d2 ; <27Oct88smb>
swap d2 ; 1st offset's direction in high word; slop in low
move.l a4,-(sp) ; save direction values <27>
move.l 6(sp),a4 ; restore teHandle to a4 <27>
movem.l C2Pparams,-(sp) ; save to be used again
bsr TEWidthHook
move.w d1,d5 ; 1st element's pixel width
; 2nd offset's width
; restore params: length, direction, textPtr, styleRunPtr, direction locale
movem.l (sp)+,C2Pparams
move.l (sp)+,a4 ; restore direction values <27>
move.w (sp)+,d1 ; restore offset2
clr.l d2 ; <7Nov88smb>
move.w (a4),d2 ; <27Oct88smb>
swap d2 ; 2nd offset's direction in high word; slop in low
move.l (sp)+,a4 ; restore teHandle <27>
bsr TEWidthHook
move.w d1,d6 ; 2nd element's pixel width
movem.l (sp)+,PixelWidthRegs
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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:
; d3 start offset
; d4 end offset
; a2 ptr to the current line
; Output
; teSelRect
;
;----------------------------------------------------------------------
ChkBounds
with TextFrame,TEFormatOrder ; <16Nov88smb> for GetStyleInOrder call
Move.W (A2),D0 ; start of line
Move.W 2(A2),D1 ; end of line
useBounds: equ 0
IF useBounds THEN
; <7Dec89smb>
Tst.W teSize(A3) ; record with style?
Bpl.s @TestLineStart ; skip ahead if not
Tst.W TESysJust ; reverse order?
Beq.s @TestLineStart ; this is easy if not
; determine if display order is different from backin-store order <28Sept88smb>
tst.b WordRedraw ; $FF if a R->L directional script installed
bge.s @getStyleOld ; nope, only L->R directional text
; mixed directional text
bsr GetStylesInOrder ; <15Nov88smb>
beq.s @OneStyle ; <15Nov88smb>
Subq #1,D2 ; dec style count
move.w d2,fmtOrderingIndex(a6) ; set to next-to-last style
move.l a0,-(sp) ; save style ptr at start
; more than 1 style in mixed directional text, so get the first and next-to-last
; styles using the results from getFormatOrder
bsr GetNextDisplayStyle ; <4Jan89smb>
Move.W startChar(a0),D1 ; start of next-to-last style
move.l (sp)+,a0 ; restore style ptr at start
bra.s @CmpStarts
; only L->R text
@getStyleOld
Bsr GetCurStyle ; get its style <7Oct88smb>
Bsr GetNumStyles ; # of styles between offsets <7Oct88smb>
SubQ #1,D0 ; look for end of last style
Bne.S @ManyStyles
; Reset start and end of line if only 1 style
@OneStyle
Move.W (A2),D0 ; reset start of line
Move.W 2(A2),D1 ; end of line
Bra.S @TestLineStart
; more than 1 style in L->R directional text, so find actual start and end line offsets
@ManyStyles
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
@CmpStarts
Move.W (A2),D0 ; get start of line again
Cmp.W startChar(A0),D0 ; compare to start of style
Bhs.S @TestLineStart ; made this unsigned ** <C381/6nov86/MBK> **
Move.W startChar(A0),D0 ; else set to style start
ENDIF
; if block begins at start of line, make left a large negative number
; <7Dec89smb> Tried to fix boundaries for tesysjust conditions
@TestLineStart
Cmp.W D0,D3
Bne.S @TestLineEnd
tst.w teSysJust
bne.s @FixRightBoundAtStart
Move.W #UnboundLeft,teSelRect+left(A3) ; assume LR text
bra.s @TestLineEnd
@FixRightBoundAtStart
Move.W #UnboundRight,teSelRect+right(A3)
; if block ends at end of line, make right a large positive number
@TestLineEnd
Cmp.W D1,D4
Bne.S @EdgesSet
tst.w teSysJust
bne.s @FixLeftBoundAtEnd
Move.W #UnboundRight,teSelRect+right(A3)
bra.s @EdgesSet
@FixLeftBoundAtEnd
Move.W #UnboundLeft,teSelRect+left(A3) ; assume LR text
@EdgesSet
;;<7Dec89smb> bsr FreeFmtOrderArray ; <18Jan89smb>
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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 ; line # from A2 returned in d0 <C971/RWW102887>NO
Move.W D0,D1 ; save current line #
MoveQ #0,D0 ; from 0 to this line ** MBK 6/18/86 **
Bsr.S GetLineHites ; total height from 0->d1 returned in d0<C971/RWW102887>NO
Lea teDestRect+8(A3),A0 ; point past destRect
Lea teSelRect+8(A3),A1 ; and past stack rect
Move.L -(A0),-(A1) ; copying teDestRect to teSelRect
Move.L -(A0),-(A1) ; copying teDestRect to teSelRect
Add D0,(A1) ; add total height to top to get
; top bound of line rect
Move top(A1),bottom(A1) ; temporarily the same
Move.W D1,D0 ; current line ** MBK 6/18/86 **
Bsr GetHite ; height of this line returned in d1 ** MBK 6/18/86 **
Add D1,bottom(A1) ; add line height to get bottom bound of line rect
; 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 @NotLeftJust ; go process if not left** <C105/12aug86/MBK> **
Move.W TESysJust,(SP) ; check text direction ** <C105/12aug86/MBK> **
Beq.S @LRFLow ; do nothing if left->right text direction
@NotLeftJust
Cmp.W #teForceLeft,(SP)
Beq.S @LRFLow
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 @RLFlow ; bra if right->left text direction
AsR #1,D1 ; div by 2 for centering
@RLFlow
Add D1,teSelRect+left(A3) ; bump rect over
@LRFLow
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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; LineWidth
;
; Measures the width of the line at (A2)..2(A2). Trims break chars
; from the right side. Called from LineRect.
;
; Entry
; A2 = ptr to lineStart array
; A3 = dereferenced handle to TE object
;
; Exit
; leaves the width in D0
;
;----------------------------------------------------------------------
LineWidth
move (a2),d6 ; get lineStart as anchor
move 2(a2),d7 ; get line end as the other anchor
move.l ExpandMem,a0 ; <1Feb89smb>
st ExpandMemRec.emMeasureLine(a0) ; mark it for later measuring: measure whole line
MeasD6D7
Move.l TETrimMeasure,-(SP) ; push trimMeasure routine <EHB 01Oct85>
Rts ; and call it <EHB 01Oct85>
XTrimMeasure
;----------------------------------------------------------------------
;;<2Aug89smb> tst.b WordRedraw ; <18Jan89smb>
;;<2Aug89smb> bmi.s MeasureIt ; <18Jan89smb> don't use for RL text
; If a Roman system then use old TrimMeasure code rather than SMgr VisibleLength <2Aug89smb>
;;<31Oct89smb> tst.b teSysJust
;;<31Oct89smb> bne.s @VisLen ; use VisibleLength for RL line direction
;----------------------------------------------------------------------
; added <1Nov89smb>
; We need to strip off trailing spaces IF they are trailing in display order (on the L. in a
; R-L line and on the R. in a L-R line.)
; if the line direction = teJust (corrected for teSysJust), then go directly to MeasureIt.
; if teJust = teJustCenter OR teJust = teJustLeft, skip
cmp d6,d7 ; nothing to measure? <31Oct89smb>
bls zeroExit ; <31Oct89smb>
move.w teJust(a3),d0 ; <31Oct89smb>
bge MeasureIt ; <31Oct89smb>
; if teJust = teSysJust, skip
cmp.w teSysJust,d0 ; <31Oct89smb>
beq MeasureIt ; <31Oct89smb> implies teSysJust = RL
; ow, the line direction = LR and teJust = right
; OR (!!!) teJust = force left (the line direction = RL/LR) (!!!!!) new comment <10/10/90smb>
tst.b WordRedraw ; test if Arabic installed w/ line direction LR
beq @RomanTrim ; bra for Roman
;----------------------------------------------------------------------
; added <1Nov89smb>
; Adding call to GetStylesInOrder in order to call VisibleLength for a line's style runs.
; We need to traverse the style runs in display order but backwards! This is because it's
; possible to have style runs at the end of a line containing only blanks (silly but true!)
with TextFrame,TEFormatOrder
move.l d5,-(sp)
clr.w d5 ; flag that signifies we are done w/ VisibleLength
move.w d6,-(sp) ; save original lineStart
tst.w teSize(a3) ; do something different for unstyled! <7Nov89smb>
bmi.s @GetStyles ; bra if styled edit record
; old-style record: one style for the whole record. My code is expecting a0 to contain a ptr to
; the startChar for the current style so must fake the setup.
clr.l firstStyleRun(a6)
clr.l secondStyleRun(a6)
move.w teLength(a3),secondStyleRun(a6)
lea firstStyleRun(a6),a0
move.l a0,a2StyleRun(a6) ; save style run of lineStart as a ptr
;;<16Nov89smb> move.w #1,d2
;;<16Nov89smb> move.w d2,numberOfRuns(a6) ; save
; cleared since don't need to go thru initial @styleLoop code. <16Nov89smb>
clr.w d2 ;<16Nov89smb>
clr.w numberOfRuns(a6) ;<16Nov89smb>
lea.l fmtOrdering(a6),a1
move.l a1,fmtOrderingPtr(a6)
;;<16Nov89smb> move.w #1,fmtOrderingIndex(a6) ; decrement below @styleLoop
clr.w fmtOrderingIndex(a6) ;<16Nov89smb>
clr.w (a1)
;;<16Nov89smb> bra.s @styleLoop
bra.s @UnStyled ;<16Nov89smb>
@GetStyles
move.w d6,d0 ; start of selection
move.w d7,d1 ; end of selection
bsr teGetFormatOrder
move.w numberOfRuns(a6),d2
move.w d2,fmtOrderingIndex(a6) ; start w/ the last style run
;----------------------------------------------------------------------
@styleLoop
subq #1,fmtOrderingIndex(a6) ; decr the style run counter
bsr GetNextDisplayStyle
subq #1,d2 ; dec the style counter
;;<16Nov89smb> tst.w teSize(a3) ; record with style?
;;<16Nov89smb> bpl.s @UnStyled ; if not, go do it the old way
bsr SetStyle ; set current style
@UnStyled
; If we've already found the first (or visibly last) non-blank style run on the line, the flag
; will be set and we need to loop to determine if this is the greatest style run offset.
tst.b d5
bne.s @GetStyleEnd ; yep
; must be blanks on the line end
;----------------------------------------------------------------------
; call VisibleLength to correctly determine the text to measure
movem.l d2/a0/a2,-(sp)
; pin to style run boundaries
move.w startChar(a0),d6
bsr FixFormatEnd ; if last format run, must decrement end offset
move.l teTextH(a3),a0 ; get text handle
move.l (a0),a0 ; dereference
add.w d6,a0 ; set to LineStart
sub.w d6,d0
clr.l -(sp) ; longint return
move.l a0,-(sp) ; textPtr
swap d0 ; clear high word
clr.w d0
swap d0
move.l d0,-(sp) ; textLen
_VisibleLength
move.l (sp)+,d7 ; length of visible text
movem.l (sp)+,d2/a0/a2
beq.s @LoopExit ; if all blanks, keep looping
;----------------------------------------------------------------------
add.w d6,d7 ; non-blank => done; get real position
; set flag in high word saying done w/ VisibleLength
st d5
@GetStyleEnd
; Once we encounter a non-blank style run, we need to loop through all the previous style runs
; on the line, searching for the largest end offset that is larger then the VisibleLength offset.
; Get the maximum of the style run's end offset and the visibleLength offset.
; per Mark Davis. I'm a believer now! <6Dec89smb>
; d7 = visibleLength initially; is replaced by the end offset of a style run which is larger.
; a0 = ptr to current style run
bsr FixFormatEnd ; if last format run, must decrement end offset
cmp.w d0,d7
bge.s @LoopExit ; VisibleLength is the larger, keep looping
move.w d0,d7 ; prev style run is max.
;----------------------------------------------------------------------
; if all blanks, keep looping
@LoopExit
tst.w d2 ; more styles?<1Nov89smb>
bne.s @styleLoop ; yes, loop again
move.w (sp)+,d6 ; restore original lineStart
move.l (sp)+,d5
bra.s MeasureIt ; if all blanks on this line, will terminate in MeasureIt
;----------------------------------------------------------------------
; <2Aug89smb> end of VisibleLength changes
@RomanTrim
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
@TrimLoop
SubQ #1,D7 ; look to left
Cmp D6,D7
Beq.S @LoopXit ; assume done if = to left
Cmp.B #$20,0(A0,D7) ; if last char <= space then...
Bls.S @TrimLoop ; it's a break
@LoopXit
AddQ #1,D7 ; use next char
; fall into MeasureIt ; get width in [D6 to D7)
;formFeed
;----------------------------------------------------------------------
;
; 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
IF forLocalizability THEN ; <31l-YDS-8/27/91>
tst.b WordRedraw ; have L->R script ?
blt.s @1 ; yes, allow measure of zero char strings (skip zeroExit)
ENDIF
Cmp D6,D7 ; nothing to measure?
Bls.S zeroExit ; <C971/RWW102887>NO
@1 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 @Styled ; if not, go do it the old way
; unstyled text
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 @done
@Styled
; Record does have style; get # of styles within selection
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
@styleLoop
; Set the GrafPort to the current style
Bsr SetStyle ; set current style
bsr FixFormatEnd ; <19June89smb> if last format run, must decrement
AddQ #stStartSize,A0 ; pt to next style
; Get the width of this selection <27June88smb>
; At this point, d0 = start of next style run <20June89smb>
@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 @styleLoop ; more styles
Move.W D4,D0 ; return width in D0
@done
MoveM.L (SP)+,D2/D4/D6 ; restore stuff
; clear up the world
move.l ExpandMem,a1 ; <1Feb89smb>
sf ExpandMemRec.emMeasureLine(a1) ; restore old flag
Rts
zeroExit
MoveQ #0,D0 ; nothing to measure
Rts
;formFeed
;----------------------------------------------------------------------
;
; GetWidth
;
; Input
; a0 next style run
; d0 start of the text in the next style run
; d6 start of the text
; d7 end of the text
; a2 pointer to current lineStart
;
; Need to set up... <27June88smb>
; a0 = start of text to be measured
; d0 = overall style run length
; d1 = length from start of measured text to end
; d2 = slop & highlight
;
;----------------------------------------------------------------------
GetWidth
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vGetWidth(a1),a1
jmp (a1)
xGetWidth
tst.w teSize(A3) ; record with style?
bpl.s @Unstyled ; if not, A0 is nothing
; styled text
Move.L teStylesH(a3),a1 ; get style handle
Move.L (a1),a1 ; dereference
Sub.L a1,a0 ; save as offset
@Unstyled
Move.L a0,-(SP) ; save A0
Move.L teTextH(a3),a0 ; get text handle
Move.L (a0),a0 ; dereference
; get start of text into a0, max(d7,d0)-d6 into d1 <27June88smb>
; possible bug with > 32K
add.w d6,a0 ; point at real start of text
move.w d7,d1 ; get the end
; adjust the start of the next style run to max at the end of the line <22Sept88smb>
cmp.w 2(a2),d0 ; length > end of line
bls.s @GotStyleEnd ; ok
move.w 2(a2),d0 ; fix it.
@GotStyleEnd
; pick the min of the style run end and the text end <26Sept88smb>
sub.w d6,d0 ; sub start of text from end
sub.w d6,d1 ; sub start of text from offset
blt.s @FullStyleRun ; d1 outside of range <26Sept88smb>
cmp.w d0,d1 ; d1 higher than range,
IF forLocalizability THEN ; <31l-YDS-8/27/91>
bgt.s @FullStyleRun ; allow measure when equal too (for R->L)
ELSE
bcc.s @FullStyleRun ; bail: want to bra on equal too. <19June89smb> <26June89smb> made unsigned
ENDIF
; if drawing, then try this out! use textWidth for draw and C2P for caret. <21Sept88smb>
move.l ExpandMem,a1 ; <1Feb89smb> full line flag
tst.b ExpandMemRec.emMeasureLine(a1) ; line width flag set?
beq.s @UseChar2Pixel ; no, do real stuff <22Sept88smb>
; we are measuring the whole line, BUT we only want to measure up to visible length <6Nov89smb>
cmp.w d0,d1 ; take the minimum <6Nov89smb>
bhs.s @FullStyleRun ; d0 < d1, so skip <6Nov89smb>
move.w d1,d0 ; stuff the visibleLength <6Nov89smb>
@FullStyleRun
; don't test interior of style run
IF hasTextWidthHook THEN ; <18>
moveq #0,d1 ; wants offset here <18>
bsr TETextWidthHook ; hook out TextWidth <18>
ELSE ; <18>
clr.w -(sp) ; allocate return <21Sept88smb>
move.l a0,-(sp) ; pointer
move.w #0,-(sp) ; no first byte
move.w d0,-(sp) ; bytecount
_TextWidth ; go for it
move.w (sp)+,d1 ; got the width
ENDIF ; <18>
bra @Continue ; rejoin <21Sept88smb>
@UseChar2Pixel
MoveQ #smHilite,D2 ; hilite flag <27June88smb>
swap d2 ; hilite in high word; slop in low <27June88smb> ** <C139/22Sep86/MBK> **
Bsr TEWidthHook ; THIS LINE REPLACES C2P call <C971/RWW110387>
@Continue
Move.L (SP)+,A0 ; restore A0
Tst.W teSize(A3) ; record with style?
Bpl.S @done ; 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
@done
Rts
;formFeed
;----------------------------------------------------------------------
;
; OldChar2Pixel
;
; Using if the old WidthHook is preferred over the nWidthHook.
; Never come here for script systems; always use new Char2Pixel.
; See ScriptChar2Pixel and TEWidthHook dispatch code. <2/8/90smb>
; Also coming here as the default for TextWidthHook (see TETextWidthHook) <18>
;
; Entry: a0 ptr to text
; d0.w length of text to be measured
; d1.w offset into text
;
; Exit: d1.w width of measured text
;
;----------------------------------------------------------------------
OldChar2Pixel
subq #2,sp ; room for result
move.l a0,-(sp) ; pass pointer
move.w d1,-(sp) ; offset
move.w d0,-(sp) ; length
_TextWidth ; get width
move.w (sp)+,d1 ; resulting width
rts
;formFeed
;----------------------------------------------------------------------
;
; Char2Pixel
;
; new <27June88smb>
;
; Entry: A0: ptr to start of text to be measured
; D0.W length of text to be measured (TE version)
; overall style run length (SMgr version)
; D1.W start offset into text(TE version);
; length from start of measured text to end (SMgr version)
; : our offset w/in the style run (pinned to the lineStart)
; D2 slop (low word)
; add caret or hilite flag (high word)
; A2 pointer to current lineStart
;
; Exit: D1.W width of measured text
;
;----------------------------------------------------------------------
Char2Pixel
Move.L JChar2Pixel,-(SP) ; call the Char2Pixel Routine <EHB 01Oct85>
Rts
vChar2Pixel
; if LR text and RL line direction and (offset = SOL or EOL) then <4May89smb>
; if direction = smLeftCaret (0) then
; if offset = lineStart then
; return textWidth
; otherwise return 0 ; offset = lineEnd
; else ; direction = smRightCaret (-1)
; if offset = lineStart then
; return 0
; otherwise return textWidth ; offset = lineEnd
move.l d3,-(sp)
tst.b TESysJust
beq @UseC2P
; RL line direction
movem.l d0/d2/a0/a1,-(sp)
move.w d1,-(sp)
tst.b teSize(a3)
bpl.s @noStyle
move.L teTextH(a3),a1 ; source = text
move.L (a1),a1 ; dereference
suba.l a1,a0 ; offset to beginning of text to be measured
move.w a0,d0 ; length to beginning of style run
add.w (sp),d0 ; add in length to offset
move.w d0,d3 ; save
bsr GetCurStyle
bsr GetDirection ; <6June89smb>
bra.s @TestDir ; <6June89smb>
@noStyle
;; d3 must be an absolute position for comparing to line ends. <20June89smb>
move.w d1,d3 ; offset w/in line <20June89smb>
add.w (a2),d3 ; absolute position <20June89smb>
; get the script direction from the font in the grafport for unstyled text <6June89smb> <11>
bsr GetDirection ; input is a3 - handle to teRec <11>
;; sub.w #6,sp ; allocate return, 1 long, 1 int <11>
;; _FontScript ; returns script; leave on stack as param <11>
;; move.w #smScriptRight,-(sp) ; pass verb <11>
;; _GetScript <11>
;; move.l (sp)+,d1 ; get byte = line direction <11>
@TestDir
cmp.b TESysJust,d1
beq.s @fixStack ; not equal=> LR script
; RL line and LR script
; compare current position to line ends
;; <20June89smb> Bsr GetLine ; returns ptr to line in a2
move.w (sp)+,d1
movem.l (sp)+,d0/d2/a0/a1
; test if called for R-to-L highlighting rather than hit-testing <31July89smb>
move.l d2,-(sp) ; save <1Aug89smb>
swap d2 ; direction in high word <31July89smb>
cmp.w #smHilite,d2 ; bug fix for Arabic highlighting <31July89smb>
movem.l (sp)+,d2 ; restore (w/o affecting CCs) <1Aug89smb>
beq.s @UseC2P ; using for hilighting! <31July89smb>
;;<2/1/90smb> bne.s @Use4HitTest ; <31July89smb>
;;<2/1/90smb> bra.s @UseC2P ; using for hilighting! <31July89smb>
;;<2/1/90smb>@Use4HitTest
; use for hit testing
cmp.w (a2),d3 ; same as lineStart?
beq.s @OnAnEnd
cmp.w 2(a2),d3 ; same as lineEnd?
bne.s @UseC2P
@OnAnEnd
; RL line and LR script and on a lineEnd so process w/o calling C2P.
swap d2 ; direction in high word
cmp.w #smLeftCaret,d2
bne.s @RightCaret
cmp.w (a2),d3 ; same as lineStart?
beq.s @TextWidth ; yep, start
bra.s @ZeroWidth ; nope, end
@RightCaret
cmp.w (a2),d3 ; same as lineStart?
beq.s @ZeroWidth ; yep, start
@TextWidth
IF hasTextWidthHook THEN ; <18>
moveq #0,d1 ; wants offset here <18>
bsr TETextWidthHook ; hook out TextWidth <18>
ELSE ; <18>
subq.l #2,sp ; room for result
move.l a0,-(sp) ; ptr on stack
;;<20June89smb> move.w d1,-(sp) ; offset to first char
move.w #0,-(sp) ; offset to first char <20June89smb>
move.w d0,-(sp) ; length of block
_TextWidth ; how wide is it?
clr.l d1
move.w (sp)+,d1 ; this wide
ENDIF ; <18>
bra.s @done
@ZeroWidth
moveq #0,d1
bra.s @done
;****************************
@fixStack
move.w (sp)+,d1
movem.l (sp)+,d0/d2/a0/a1
@UseC2P
; <4May89smb> end of additions
clr.w -(sp) ; room for Char2Pixel return
move.l a0,-(sp) ; pass text ptr to buffer
move.w d0,-(sp) ; pass text len
move.w d2,-(sp) ; here's the slop
move.w d1,-(sp) ; pass the offset
swap d2 ; direction in high word
;;<22June89smb> move.b d2,-(sp) ; actually,in lower byte
move.w d2,-(sp) ; move word since AIS tests word not byte <22June89smb>
_Char2Pixel
move.w (sp)+,d1 ; returns the pixel width
@done move.l (sp)+,d3 ; restore <4May89smb>
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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 NOT ForROM THEN ; <9Dec88smb>
BTst #14,ROM85 ; are we on a color system? (as per Jerome) <C971/RWW112487>
Bnz.S @2 ; Nope <C971/RWW112487>
EndIf
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
_MoveTo ; compatibility shit
Rts
;formFeed
;----------------------------------------------------------------------
;
; DoMeasure
; ** <C139/22Sep/86> MBK **
;
; DoMeasure was added to handle reverse justification.
; DoMeasure measures from the display start of the line
; to the given offset. MeasureIt is still called directly
; when the distance between 2 offsets is desired.
;
; Input
; d7 = left or right side to measure
; a2 = line start
; Output
; d0 = total width
; Use:
; d5 = accumulated width
; d0 = end of style run
; d3 = haven't found a style run containing d7 yet
; d2 = number of style runs on the line
;----------------------------------------------------------------------
DoMeasure
with TextFrame,TEFormatOrder ; <16Nov88smb> added for GetStylesInOrder call
MoveM.L D3/D5-D6,-(SP)
MoveQ #0,D5 ; width accumulator
Move.W (A2),D6 ; line start
sf d3 ; not found yet
Cmp D6,D7 ; nothing to measure?
Blo @MeasureDone ; made this unsigned ** <C381/6nov86/MBK> **
IF forLocalizability THEN ; <31i-YDS-8/27/91> - see <31i-YDS-8/27/91> below>
Tst.b WordRedraw ; reverse order? if <0 then RL script present
Bge @PlainMeasure ; just do normal roman measure if not
Tst.W teSize(A3) ; style record?
Bpl @LRPlainMeasure ; just do normal L->R measure if not
ELSE
Tst.W teSize(A3) ; style record?
Bpl @PlainMeasure ; just do normal measure if not
Tst.b WordRedraw ; reverse order? if <0 then RL script present
Bpl @PlainMeasure ; just do normal measure if not
ENDIF
sf useOldMethod(a6) ; flag for getting style runs <28Sept88smb>
Move.W (A2),D0 ; start of line <12July8smb> moved up here
Move.W 2(A2),D1 ; end of line <12July8smb> moved up here
; determine if display order is different from backin-store order <28Sept88smb>
tst.b WordRedraw ; $FF if a R->L directional script installed
;;<17July89smb> bge.s @getStyleOld ; nope, only L->R directional text
blt.s @RLStyledLine ; RL text in record <17July89smb>
; moved next 4 lines here to cleanup branching <17July89smb>
st useOldMethod(a6)
Bsr GetCurStyle ; get its style <7Oct88smb>
Bsr GetNumStyles ; # of styles between offsets <7Oct88smb>
bra.s @MeasureLoop ; <17July89smb>
@RLStyledLine
bsr GetStylesInOrder ; initialize style run array
; tests whether any styles to process
bge.s @MeasureLoop
bra.w @MeasureDone
@getStyleNew
; get next style using the results from getFormatOrder
bsr GetNextDisplayStyle ; <4Jan89smb>
addq #1,fmtOrderingIndex(a6) ; incr the style run counter
SubQ #1,D2 ; dec the style counter
bge.s @MeasureLoop
bra.w @MeasureDone ; done
;; removed label <17July89smb> @getStyleOld
@MeasureLoop
; get the style run in d6,d0
Move.W startChar(A0),D6 ; store actual start of line
bsr FixFormatEnd ; <6Mar89smb> returns end of style run in d0
; pin d6 (start of the style run) to start of the line
Cmp.W (A2),D6 ; should not be greater than
Bhi.S @D6Pinned2Start ; made this unsigned ** <C381/6nov86/MBK> **
Move.W (A2),D6 ; the selection start
@D6Pinned2Start
; pin d0 (end of style run) to the end of the line
Cmp.W 2(A2),D0 ; style start
Bls.S @D0Pinned2End ; made this unsigned ** <C381/6nov86/MBK> **
Move.W 2(A2),D0 ; line's end
@D0Pinned2End
; now have a valid style run, limited to the line we are on
; this checks for a boundary condition, where d7 is between style runs
tst.b d3 ; found already?
bne.s @PlainMeasure ; exit and measure the last one
; if searchpoint not in current style run, then keep measuring
Cmp.W D6,D7 ; if less than selection start
Blo.S @DontExit ; then searchPoint is not in this style
Beq.S @CheckDirection ; check for boundary condition
Cmp.W D0,D7 ; if greater than selection end
Bhi.S @DontExit ; then searchPoint is not in this style
Bne.S @PlainMeasure ; exit & measure (firmly inbetween)
; at this point, on a boundary. Measure & Exit if style direction = TESysJust
@CheckDirection
Bsr GetDirection ; returns script dir in d1
cmp.b TESysJust,d1 ; TESysJust = 0, -1, so top byte set
beq.s @PlainMeasure ; exit & measure this last run
st d3 ; found at least one style run
bra.s @GetTheWidth ; already set style, so go for it.
; if searchPoint (d7) on boundary of previous style run and this style run must adjust it to
; be at the end of the style run to get the full measure of the style run. Rather than adjust
; it we force GetWidth to use TextWidth by setting tempVar to true! <27Sept88smb>
@DontExit
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> **
@GetTheWidth
move.l ExpandMem,a1 ; <1Feb89smb>
st ExpandMemRec.emMeasureLine(a1) ; full line flag: measure full style run <27Sept88smb>
move.w d2,-(sp) ; save style count
Bsr GetWidth ; get string width
Add.W D1,D5 ; accumulate width
move.w (sp)+,d2 ; restore style count
tst.b useOldMethod(a6) ; <28Sept88smb>
beq.s @getStyleNew ; use formatOrder array
SubQ.L #stStartSize,A0 ; pt to prev style
Bra.S @MeasureLoop ; keep measuring
IF forLocalizability THEN ; Fix to support correct mesure for unstyled L->R
@LRPlainMeasure ; text <31i-YDS-8/27/91>>
MoveM.l a0-a1/d0-d2, -(sp) ;
Move.l teTextH(A3),A0 ; get text handle
Move.l (a0),a0 ; derefrence it
move.w teLength(a3), d0 ; take lext length to d0
cmp.w (a2),d0 ; are we at the start of the empty last line ?
beq.s @1 ; yes !!
move.w 2(a2), d0 ; take next line start to d0
@1 move.w d7,d1 ; offset
Tst.W TESysJust ; check text direction, we want tha max rect !!!
bne @3 ; push direction
move.w #smRightCaret, d2 ; we allways push the oposite direction
bra.w @4 ; in that way we get tha max mesurement
@3 move.w #smLeftCaret, d2 ; in that way we get tha max mesurement
@4 swap d2
clr.w d2 ; slop = 0
add.w d6,a0 ; point to beginning of current line <46>
sub.w d6,d0 ; want length from current line start <46>
sub.w d6,d1 ; want offset on current line <46>
;Need:
; textPtr in a0.l, textLen in d0.w, offset in d1.w;
; d2.l = slop (low word), hilite flag (high word)
bsr TEWidthHook
move.w d1,d5 ; mesure result in d5
MoveM.L (sp)+,a0-a1/d0-d2
bra.s @MeasureDone
ENDIF
@PlainMeasure
move.l ExpandMem,a1 ; <1Feb89smb>
sf ExpandMemRec.emMeasureLine(a1) ; <27Sept88smb>
Bsr MeasureIt ; last measurement
Add.W D0,D5 ; final width
@MeasureDone
Move.W D5,D0 ; return width in D0
bsr FreeFmtOrderArray ; <18Jan89smb>
MoveM.L (SP)+,D3/D5-D6
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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 in d0
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
;formFeed
;----------------------------------------------------------------------
;
; 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
; special check for negative, return negative! <1/30/90smb>
tst.l d0 ; before start of rect? <1/30/90smb>
blt.s @4 ; yes, return above top line <1/30/90smb>
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
;formFeed
;----------------------------------------------------------------------
;
; InvertHook
;
; 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 NOT ForROM THEN ; <9Dec88smb>
; 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 hasCQD THEN ; <9Dec88smb>
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 hasCQD|(NOT ForROM) THEN ; <9Dec88smb>
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
;formFeed
;----------------------------------------------------------------------
; StdEntry (or "entries" as it is!)
;
; Standard Entry for procs, saves registers and pops handle
; argument into A4 and dereferences it into A3. Points A2 to
; first parameter AFTER the handle.
;----------------------------------------------------------------------
TEKeyStdEntry
; Added new entry point for TEKey since need to save/clear textBuffering flag around this routine.<18Sept89smb>
moveq #0,d0 ; not a style trap
move.l (sp)+,a0 ; save return address
move.l (sp)+,a1 ; save newTEFlags
link a6,#stdLink ; stack frame
movem.l d2-d7/a2-a4,-(SP)
move.l a1,-(sp) ; newTEFlags to restore
move.l a0,-(sp) ; push return address back on stack
bra.s NotStyleTrap
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 NotStyleTrap ; 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 StyleTrap
NotStyleTrap
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> **
StyleTrap
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. AFTER saving the grafport information! <20>
move.l teGrafPort(a3),a0 ; pt to GrafPort
move.w txFont(a0),saveFont(a6) ; save current font
bclr #7,txFace+1(a0) ; in case direction set here <30May89smb>
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> **
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 teMode(A3),txMode(A0) ; do set the mode ** <C815/13feb87/MBK **
_GetForeColor ; for Ikki ** <C182/6oct86/MBK> **
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
IF &TYPE('&RWWDebug') = 'UNDEFINED' THEN
Bsr.s SelSort ; I wish i could fall into it
ELSE
Bsr SelSort ; I wish i could fall into it
ENDIF
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
; dump text buffer before processing any calls <14Sept89smb>
move.l a0,-(sp)
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops <15Sept89smb>
btst #teFTextBuffering,d0 ; <15Sept89smb>
beq.s @noBuffer
bsr DumpBuffer ; dump text from buffer
@noBuffer
move.l (sp)+,a0
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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 ; see OS:DispTable.a
FindEntry vPixel2Char ; see OS:DispTable.a
FindEntry XTrimMeasure ; see OS:DispTable.a
FindEntry XFindWord ; see OS:DispTable.a
FindEntry XFindLine ; see OS:DispTable.a
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 iTECustomHook
FindEntry iTEContinuousStyle
FindEntry iSetStylScrap
FindEntry iTENumStyles
FindEntry iTEFeatureFlag
DC.L -1
EndIf
; ***************************************************************************
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE CopyGuts
;
; ** Separated out from CopyStyle 1/22/87 by MBK **
;
; CopyGuts is called by CopyStyle and GetStylScrap to save the
; styles corresponding to the current text selection.
;
; Entry:
; A3: Pointer to TERec
; D0: selStart
; D1: selEnd
; Exit:
; A4: handle to style scrap
; Modifies:
; A0-A4,D0,D2,D4,D5
;
;----------------------------------------------------------------------
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> **
_BlockMoveData ; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
tst.w teSize(A3) ; is this a styled record? <24July89smb>
bpl.S outGuts ; if so, no need to concat - only 1 run <24July8smb>
bsr ConcatStyles ; <21July89smb>
bsr ConcatRuns ; <25June89smb>
outGuts
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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
_BlockMoveData
@2 MoveM.L (SP)+,D0/D2-D6/A2 ; restore stuff
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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 #UnboundLeft,left(A0) ; large negative left
Move #UnboundRight,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
;formFeed
;-------------------------------------------------------------------------------
; Function: GetCurScript // <DGO 881004>
;
; This function determines the "script run" (comprising one or more style runs)
; that contains the character position contained on entry in register d0. Note
; that this routine should only be called for styled TERecs.
;
; Inputs:
;
; d0 = Absolute char position for which script run is to be found
;
; Outputs:
;
; a0 = Address of the first style run in the script run
; a1 = Index of the first style run in the script run
; d0 = Total length (in chars) of all style runs comprising this script run
; d1 = Script number of this script run
;
; General register usage (as usual, a6 is local frame pointer):
;
; d4 = On-the-fly index into array of StyleRuns
; d5 = Cumulative character length of runs
; d6 = Offset into STElement array of the (a2) element
; d7 = Script number for this run
;
; a2 = On-the-fly address of StyleRuns array element
; a4 = Base address of STElement[0]
; a5 = Base address of TEStyleRec
;
; Assumptions made about input state:
;
; a3 = Dereferenced pointer to TERecord
;
; CHANGE LOG
;
; <4-Oct-88 DGO> Corrected bug whereby I was using the styleRun index rather than the
; styleIndex for the styleRun **arrgghhh**
;
;-------------------------------------------------------------------------------
GetCurScript
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vGetCurScript(a0),a0
jmp (a0)
xGetCurScript
; Initial housekeeping
;
link a6,#gcsLink
movem.l d2-d7/a2/a4/a5,-(sp)
;
; Since d0 is already set to the char position, we start the ball rolling by calling
; GetCurStyle. This returns a pointer to the style run in a0, and the style run index
; in d0.
;
bsr GetCurStyle
movea.l a0,a2
move.w d0,d4
;
; Set up our utility registers.
;
movea.l teStylesH(a3),a5
movea.l (a5),a5 ; Pointer to TEStyleRec now in a5
movea.l styleTab(a5),a4
movea.l (a4),a4 ; Pointer to STElement[0] now in a4
moveq.l #0,d5 ; Zero cumulative script length counter
moveq #0,d6 ; must clear for shift logic <29June89smb>
move.w styleIndex(a2),d6
;; mulu #stRecSize,d6 ; Offset from a4 of STElement[d4]
add.w d6,d6 ; replace mulu w/ shift logic <28June89smb>
move.w d6,d1 ; save <28June89smb>
lsl.w #3,d6 ; <28June89smb>
add.w d1,d6 ; sum <28June89smb>
;
; Now determine to which script this style run belongs. The result will be the script value
; that all other contiguous style runs must match in order to be added to this script run.
;
clr.w -(sp)
move.w stFont(a4,d6.l),-(sp) ; Font for this style run
_Font2Script
move.w (sp)+,d7 ; Script number for this script run in d7
;
; We now start traversing the style runs. We'll first traverse the earlier runs, and then
; the later ones. Before we start the first traverse, we save the state of several of the
; registers for restoration when starting the second traverse, below.
;
movem.l d4/a2,-(sp)
;
; Add the length of this style run to the cumulative length for the script run. Remember
; that the length of a style run can be determined by adding the startChar of the
; following style run and subtracting the startChar of this style run. (Note
; that we fall into this code the first time through, which adds the length of the
; initial style run). This is complicated by the following ugliness: If we're in the
; last style run in the TERecord, we need to decrement the count by one, since the
; dummy entry at the end of the StyleRun table has a startChar value that is one
; *greater* than the total count of characters in the record. *Sigh*
;
@1 add.w stStartSize(a2),d5 ; Note that any overflows will
sub.w startChar(a2),d5 ; automagically sort themselves out...
move.l a2,gcsTemp(a6) ; Save earliest script start
move.w d4,gcsIndex(a6) ; and index of earliest start
addq.w #1,d4 ; These 4 lines are the ugly code
cmp.w nRuns(a5),d4 ; that handle the case of the
bne.s @2 ; final style run's extra
subq.w #1,d5 ; count...
@2 subq.w #1,d4 ; Balance the addq in the above ugly code
beq.s @3 ; If we just did 0th, first traverse is done
subq.l #stStartSize,a2 ; Set pointer to previous styleRun
subq.w #1,d4 ; Set index to previous styleRun
moveq #0,d6 ; must clear for shift logic <29June89smb>
move.w styleIndex(a2),d6
;; mulu #stRecSize,d6 ; Move to previous STElement
add.w d6,d6 ; replace mulu w/ shift logic <28June89smb>
move.w d6,d1 ; save <28June89smb>
lsl #3,d6 ; <28June89smb>
add.w d1,d6 ; sum <28June89smb>
clr.w -(sp) ; Convert font
move.w stFont(a4,d6.l),-(sp) ; into script
_Font2Script
cmp.w (sp)+,d7 ; If this new script matches ours,
beq.s @1 ; continue with first traverse
;
; We're done with the earlier traverse. Restore the registers that were saved above,
; and start essentially the same operation for the later traverse.
;
@3 movem.l (sp)+,d4/a2 ; Restore on-the-fly values
addq.w #1,d4 ; Set index to next styleRun
@4 addq.l #stStartSize,a2 ; Set pointer to next styleRun
moveq #0,d6 ; must clear for shift logic <29June89smb>
move.w styleIndex(a2),d6
;; mulu #stRecSize,d6 ; Move to next STElement
add.w d6,d6 ; replace mulu w/ shift logic <28June89smb>
move.w d6,d1 ; save <28June89smb>
lsl #3,d6 ; <28June89smb>
add.w d1,d6 ; sum <28June89smb>
cmp.w nRuns(a5),d4 ; If the new style run index is equal to
beq.s @5 ; the nRuns count, we're done!
clr.w -(sp) ; Convert font
move.w stFont(a4,d6.l),-(sp) ; into script
_Font2Script
cmp.w (sp)+,d7 ; If this new script doesn't match ours,
bne.s @5 ; then we've found the script run's end
add.w stStartSize(a2),d5 ; Note that any overflows will
sub.w startChar(a2),d5 ; automagically sort themselves out...
addq.w #1,d4 ; These 4 lines are the ugly code
cmp.w nRuns(a5),d4 ; that handle the case of the
bne.s @4 ; final style run's extra
subq.w #1,d5 ; count...
;
; We're done! Set up the return values into their registers, restore state, and return.
;
@5 movea.l gcsTemp(a6),a0
movea.w gcsIndex(a6),a1
move.w d5,d0
move.w d7,d1
movem.l (sp)+,d2-d7/a2/a4/a5
unlk a6
rts
;formFeed
;----------------------------------------------------------------------
;
; 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
fwRegs REG d3-d5/a0-a2
XFindWord
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Look for an overriding FindWord routine.
;; move.l d0,-(sp) ; preserve
;; move.l teWordBreak(a3),d0
;; _StripAddress ; does return in d0
;; move.l ExpandMem,a0
;; cmp.l ExpandMemRec.emCleanWordBrk(a0),d0 ; same?
;; beq.s @NoOverride ; Branch around wordBreak cleanup stuff
;; move.l (sp)+,d0 ; restore
;; bra WBOverid ; Handle via old logic if an override exists
; If we get here, there's no wordBreak override
;;@NoOverride
;; move.l (sp)+,d0 ; restore <21Dec88smb>
; test if RomanFindLine calling; if so, use old FindWord. added new identifier (see d2). <8June89smb>
;; cmpi.w #teFromFind,d2 ; only called by Roman FindLine.
;; beq WBOverid
; Roman line wrapping should use old FindWord <7Aug89smb>
;; cmpi.w #teFromRecal,d2 ; is line wrapping desired? (recalLines)
;; bne.s UseSMgrFW
; If a Roman system then use old FindWord code <19July89smb>
;; move.l ExpandMem,a0 ; <19July89smb>
;; cmpi.b #1,ExpandMemRec.emScriptsInstalled(a0) ; number of installed scripts <19July89smb>
;; beq WBOverid ; use old FindWord <19July89smb>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Redone to be compatible with applications using incorrect char breaking algorithms for Script Systems
; <1/16/90smb>
; If a non-Roman system then use new FindWord code
move.l ExpandMem,a0
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a0) ; number of installed scripts
bne.s UseSMgrFW ; use new FindWord
; Roman-only system
; test if line breaking calling; if so, use old FindWord.
cmpi.w #teFromFind,d2 ; called by Roman FindLine or teRecal?
bge WBOverid ; changed to 'bge' instead of 'bgt' <1/23/90smb>
; Otherwise, look for an overriding FindWord routine.
move.l d0,-(sp) ; preserve
move.l teWordBreak(a3),d0
_StripAddress ; does return in d0
move.l ExpandMem,a0
cmp.l ExpandMemRec.emCleanWordBrk(a0),d0 ; same?
beq.s @NoOverride ; Branch around wordBreak cleanup stuff
move.l (sp)+,d0 ; restore (and not earlier since StripAddress returns here!)
bra WBOverid ; Handle via old logic if an override exists
; If we get here, there's no wordBreak override
@NoOverride
move.l (sp)+,d0 ; restore (and not earlier since StripAddress returns here!)
UseSMgrFW
with FindWordFrame
link a6,#fwLink ; This version uses the Script Manager // <DGO 880819>
movem.l fwRegs,-(sp)
; The value of fwLeadingEdge is determined by which routine called FindWord.
; If RecalLines called (teFromRecal (16)), we want to look back to determine the word so
; leadingEdge is False, implying we hit on the trailing edge of a character.
; If RomanFindLine called (teFromFind (12)), we want to move forward so, leadingEdge is True.
; If FindLine called (teFromFind (12)), leadingEdge is arbitrary since we're on a character
; break when FindWord is called. (so I set it to True for consistency).
; If ClickExpand called (teWordSelect (4) or teWordDrag (8)), leadingEdge can be taken from
; teLftClick in the teRecord. <23May89smb>
clr.w fwLeadingEdge(a6) ; initialize (for bra to @GetSelWrap) <26Oct89smb>
cmpi.w #teFromRecal,d2 ; is it RecalLines calling? <28Aug89smb>
beq.s @GetSelWrap ; yep.
; if ClickExpand calling, get leadingEdge from teLftClick in teRecord. Use teLftClick rather than
; teLftCaret since DoSearch sets teLftClick. <28Aug89smb>
move.b teLftClick(a3),d1
; if calling for WordDrag then simulate Kanji code. <25Aug89smb>
cmpi.w #teWordDrag,d2 ; <25Aug89smb>
bne.s @StuffIt ; <25Aug89smb>
; at this point a2 is still equal to the Left Anchor for teClick so compare the offset to it <25Aug89smb>
cmp.w d0,a2 ; compare L. anchor to char offset <25Aug89smb>
scc d1 ; set leadingEdge flag accordingly <25Aug89smb>
@StuffIt
ext.w d1
move.w d1,fwLeadingEdge(a6)
@GetSelWrap
moveq #0,d1
cmpi.w #teFromRecal,d2 ; <28Aug89smb>
bne.s @3 ; bra if ClickExpand calling
not.l d1 ; RecalLines calling
@3 move.l d1,fwSelWrap(a6)
swap d2
move.w d0,d2
move.l d2,fwSavedD2(a6)
move.w d0,d5
tst.w teSize(a3)
bpl.s FWStyle2 ; If unstyled, set values specially
; First, we determine the script run to which d0 belongs. On return, a0 contains the
; address of the 1st style run in this script run, a1 contains the index of that style
; run, d0 contains the total length of all style runs comprising the script run, and
; d1 contains the script number of this script run.
FWStyle
bsr GetCurScript ; Remember copy of original d0 is in d5, which gets saved
move.w d5,d3 ; Copy of absolute input offset
sub.w startChar(a0),d3 ; Now d3 has script run offset
; If the script run offset is zero (i.e. we're at the very first character in the script run),
; then we need to determine the previous script run as well, unless we're at the very start
; of the whole TERec. <12June89smb>
bne.s SaveScriptVars
; ... at a script run boundary
tst.w d5
beq.s SaveScriptVars
; ... beyond the start of the teRec
tst.w fwLeadingEdge(a6)
bne.s SaveScriptVars
; ... and leading edge is False, so get the previous script run
move.w d5,d0 ; Set d0 to be the absolute index of
subq.w #1,d0 ; the byte *before* the current one
bsr GetCurScript ; Determine that byte's script run
move.w d5,d3 ; Copy of absolute input offset
sub.w startChar(a0),d3 ; Now d3 has script run offset
SaveScriptVars
; Now determine the values of the script run local variables and store them in the local frame.
;<12June89smb> end of mods
move.w d3,fwSROffset(a6) ; Save script run offset
move.w d0,fwSRLength(a6) ; Save script run byte length
movea.l teTextH(a3),a2 ; Handle to actual text
movea.l (a2),a2 ; Pointer to actual text
adda.w startChar(a0),a2 ; Pointer to first byte in the script run
move.l a2,fwSRTxtPtr(a6) ; Save pointer to start of script run text
move.w a1,fwSRIndx(a6) ; Save style run index
move.w startChar(a0),fwSRStrtCh(a6) ; Save abs posn of script run start
; Save the txFont in the current grafPort.
move.w styleIndex(a0),d0
bsr GetStyle
move.w stFont(a0),fwSRFont(a6)
bra.s FWDoIt
FWStyle2
; Set the variables for the unstyled , non-overridden case.
clr.w fwSRStrtCh(a6)
move.w d5,fwSROffset(a6)
move.w teLength(a3),fwSRLength(a6)
movea.l teTextH(a3),a2
move.l (a2),fwSRTxtPtr(a6)
; Save the txFont in the current grafPort for unstyled text. <1Dec88smb>
movea.l teGrafPort(a3),a0 ; GrafPtr for current GrafPort
move.w txFont(a0),fwSRFont(a6) ; Save it for now
; Clear some of the local frame variables
FWDoIt movea.l teGrafPort(a3),a0 ; GrafPtr for current GrafPort
move.l fwSRTxtPtr(a6),-(sp) ; Start address of this script run
move.w fwSRLength(a6),-(sp) ; Length of this script run
move.w fwSROffset(a6),-(sp) ; Offset within this script run
move.w fwSRFont(a6),txFont(a0) ; Set the font for this script run
move.w fwLeadingEdge(a6),-(sp) ; Correctly determined leftSide value
move.l fwSelWrap(a6),-(sp) ; Set appropriate word selection/word wrap value
pea fwOffTab(a6) ; Output buffer
_FindWord
movea.l teGrafPort(a3),a0 ; GrafPtr for current GrafPort
move.w fwSRFont(a6),txFont(a0) ; Faster to always reset than to selectively reset
;
; Now unpack the return values and set up for our return.
;
move.l fwOffTab(a6),d0
move.l d0,d1
swap d1
cmp.w d0,d1
bcc.s @3
exg d0,d1
@3 add.w fwSRStrtCh(a6),d0
add.w fwSRStrtCh(a6),d1
FWReturn
move.l fwSavedD2(a6),d2
movem.l (sp)+,fwRegs
unlk a6
rts
; forced here from RomanFindLine; mask off flag in low bit of d2 <8June89smb>
WBOverid ; 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-d1/a0-a1,-(sp) ; save regs - also save d1! <4/17/90smb>
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-d1/a0-a1 ; restore regs - also restore d1! <4/17/90smb>
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
endwith ; with FindWordFrame <23May89smb>
if 0 then ; unneeded
; 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
endif
;formFeed
;------------------------------------------------------------------
; FindLine <18Nov88smb>
;
; This routine breaks a line on a word boundary. It uses the SMgr
; version of StyledLineBreak. It returns whether the routine broke on a word or
; character boundary, or the display width extended beyond the edge of the text.
; If the width extends beyond the edge of the text and we have multi-formats
; then we must look for the line break within the next format run.
;
; Function StyledLineBreak (textPtr:Ptr; textLen:LongInt; textStart:LongInt; textEnd:Longint;
; flags:LongInt; Var textWidth:Fixed; Var textOffset:Longint)
; :LineBreakCode;
;
; Input:
; a3: ptr to edit record
; d6: lineStart of line containing selStart
; Output:
; d0: line end after d6
; Register Usage:
; a0: current style run
; a1: nextStyleRun
; a2: textPtr
; d0,d1: scratch
; d7: mult styles flag
;------------------------------------------------------------------
FindLine Move.L TEFindLine,-(SP) ; push current FindLine routine <EHB 01Oct85>
Rts ; and call it <EHB 01Oct85>
XFindLine
FindLineRegs reg d1-d7/a0-a2
; left this test here rather than move to RecalLines since it would be duplicated 4x in RecalLines <12july89smb>
; If a Roman system then use old FindLine code: performance improvement <5May89smb>
move.l ExpandMem,a0 ; <1Feb89smb>
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a0) ; total number of installed scripts
beq NewRomanFindLine ; use new Roman FindLine <20>
Movem.l FindLineRegs,-(sp) ; preserve whether use new or old FindLine
with LineBreakFrame
link a6,#localFrame
; initializations
moveq #0,d7 ; flag multiple styles: init to single style
move.w d6,lineStart(a6)
move.w d6,EOLCharPosn(a6) ; start for new EOL position calculation
clr.w textPtrOffset(a6)
; set up textWidth: pixel width for displaying the text
moveq #0,d0
move.w teDestRect+right(a3),d0 ; right edge
sub.w teDestRect+left(a3),d0
swap d0 ; width is FIXED
move.l d0,width(a6) ; textWidth
; textLength: is necessary for CR test and unstyled text
moveq #0,d1 ; longize
move.w teLength(a3),d1 ; doc length
sub.w d6,d1 ; adjusted to lineStart position
move.l d1,length(a6)
; textPtr: pointer to current lineStart position.
movea.l teTextH(a3),a2 ; handle to start of text
movea.l (a2),a2 ; dereference
add.w d6,a2 ; begin search for CR here <17Nov88smb>
; if we are in CR only mode, just search for a CR
;; addq.w #1,d1 ; incr for initial decr below in dbeq test <17Nov88smb> <16>
tst.b teCROnly(a3)
bge.s @StyleCheck ; changed from beq to bge <2May89smb>
; notice: CCs are set to not equal AT THIS POINT based on test of CROnly.
bra.s @CheckLength ; zero check
@CRLoop
move.b (a2)+,d0 ; is it a CR? changed to byte <28Jan89smb>
Bsr TEEOLHook
@CheckLength
dbeq d1,@CRLoop
beq.s @GotCR
move.w teLength(a3),d0 ; return end of text if CR not found
bra @finis ; <17Mar89smb>
@GotCR
move.w teLength(a3),d0 ; doc length <15Mar89smb>
sub.l d1,d0 ; - characters left
;; addq #1,d0 ; go one beyond the CR <15Mar89smb> <16>
bra @finis ; <17Mar89smb>
; End of CR check
@StyleCheck
;; subq.w #1,d1 ; decr from CR test above <17Nov88smb> <16>
move.l a2,textPtr(a6)
move.l a2,initlTextPtr(a6)
; test for new style edit record
tst.w teSize(a3) ; check style flag
bpl @noStyle ; don't set style: old-style edit record
; test for single or multiple format runs in the text
movea.l teStylesH(a3),a1 ; handle to teStyleRec
movea.l (a1),a1
cmpi.w #1,nRuns(a1)
beq.s @OneStyle ; bra if one style
moveq #1,d7 ; flag multiple styles to process
@OneStyle
moveq #0,d0
move.w d6,d0
bsr GetCurStyle ; a0: ptr to current style, d0: style index
addq.w #1,d0 ; index returned is 0 based but nRuns isn't
move.w d0,styleIndex(a6)
; test for last style run <5Dec88smb>
movea.l teStylesH(a3),a1 ; handle to teStyleRec <5Dec88smb>
movea.l (a1),a1 ; <5Dec88smb>
cmp.w nRuns(a1),d0 ; <5Dec88smb>
bcs.s @StyleLoop ; <5Dec88smb> <26June89smb> made unsigned
moveq #0,d7 ; on last style run <5Dec88smb>
; Only one run so set up real length of run. The last entry in the styleRun table has
; a startChar posn equal to teLength+1. Must subtract the extra 1 to get the real length
; of the run. <28Nov88smb>
@StyleLoop
lea stStartSize(a0),a1
move.l a0,currStyle(a6) ; save for StyledLineBreak result test
move.l a1,nextStyle(a6)
Bsr SetStyle ; set grafport style from current style in a0
; Set up textPtr & length to the beginning of the script run. Call GetCurScript which returns
; the address of 1st style run in the script run in a0 and the length in d0 of all style runs
; comprising this script run. The script run may begin prior to this lineStart so must
; adjust the textPtr and length accordingly. Also use the script run to determine the offset
; value, on input, to StyledLineBreak. This value tells the routine if this is the first script
; run on the line, which affects the returned result and offset.
move.w d6,d0
bsr GetCurScript
; returns d0 = total length of script run, a0 = addr of first style run in script run
move.l #0,offset(a6) ; assume it's not the 1st script run <12June89smb>
; pin beginning of script run to beginning of line
move.w startChar(a0),d1 ; 1st style run of script run
cmp.w lineStart(a6),d1
blo.s @AdjustLength ; bra if textPtr ok
beq.s @AdjustOffset
sub.w lineStart(a6),d1 ; offset from lineStart to beginning of script run
move.l initlTextPtr(a6),a0 ; initial ptr at beginning of line
add.w d1,a0 ; adjust to beginning of script run <21Mar89smb>
move.l a0,textPtr(a6)
move.w d1,textPtrOffset(a6) ; need for adjusting textStart and End
bra.s @LengthOK
@AdjustLength
move.w lineStart(a6),d2
sub.w d1,d2 ; distance from start of script run to lineStart
sub.w d2,d0 ; adjust to current line start
@AdjustOffset
; Set the offset parameter to non-zero since this is the 1st script run on the line.
move.l #1,offset(a6) ; necc for corrections to SMgr routine <8June89smb>
@LengthOK
; not the last run yet so use real length of run
;; replaced next 3 lines <17July89smb>
;; move.w d0,-(sp) ; longize - (can't use 'ext' since SMgr expects
;; moveq #0,d0 ; 0s in the high word!)
;; move.w (sp)+,d0
swap d0 ; <17July89smb>
clr.w d0 ; clear high word for SMgr call <17July89smb>
swap d0 ; restore <17July89smb>
move.l d0,length(a6)
; set up textStart (beginning of style run) and textEnd (end of style run) as offsets from textPtr
; get the textStart, offset from textPtr
moveq #0,d1 ; longize
move.l currStyle(a6),a0
move.w startChar(a0),d1 ; get start of this format run
cmp.w lineStart(a6),d1 ; must pin to this LineStart!
bhs.s @UseStyleStart ; bra if should use start of style run
move.w d6,d1 ; use beginning of line
@UseStyleStart
move.l d1,start(a6)
; offset start and end from current textPtr posn
move.w lineStart(a6),d0
add.w textPtrOffset(a6),d0
sub.l d0,start(a6) ; adjust textStart to textPtr's offset
; get the textEnd, offset from textPtr
move.w stStartSize(a0),d1 ; end of style run
sub.l d0,d1
move.l d1,end(a6) ; adjust textEnd to end of format run
tst.w d7 ; test for one or last style
bne.s @SetUp ; multiple styles so can use next style run for length
sub.l #1,end(a6)
bra.s @SetUp
@noStyle
move.w #0,currStyle(a6) ; needed for a termination test
; set up textStart and textEnd for non-styled text
move.l #0,start(a6) ; absolute posn from beginning of text
move.l length(a6),end(a6)
; Set the offset parameter to non-zero since this is the 1st script run on the line (AND THE ONLY ONE!) <15Dec89smb>.
move.l #1,offset(a6) ; necc for corrections to SMgr routine <15Dec89smb>
; call StyledLineBreak
@SetUp
move.w #0,-(sp) ; allocate return
move.l textPtr(a6),-(sp) ; textPtr
move.l length(a6),-(sp) ; textLength
move.l start(a6),-(sp) ; textStart
move.l end(a6),-(sp) ; textEnd
move.l #0,-(sp) ; no slop
pea width(a6) ; var textWidth: pass @width
pea offset(a6) ; var textOffset: pass @offset
_StyledLineBreak ; call SMgr
clr.w d1
move.b (sp)+,d1 ; word, char, or overflow break?
cmpi.w #smBreakOverflow,d1
beq.s @noLineBreak ; overflow!
bra.s @FindLineDone ; broke on a char or word boundary in this fmt run (or
; possibly the previous one for word breaks)
@noLineBreak
; if the routine returns an overflow break (the display rectangle width was > the text width)
; then the text width is returned in width(a6). If another style exists, call StyledLineBreak
; again with the width returned.
tst.w d7
beq.s @FindLineDone ; only one or last style to process
; test if we just processed the second to last format run
movea.l teStylesH(a3),a1 ; handle to teStyleRec <24Nov88smb>
movea.l (a1),a1
move.w styleIndex(a6),d0
addq.w #1,d0 ; for next style run
move.w d0,styleIndex(a6)
cmp.w nRuns(a1),d0 ; at last style run? <24Nov88smb>
bne.s @DoFmtRun
; last format run: last entry of style run table is a dummy entry = teLength + 1
moveq #0,d7 ; flag no more runs after this one
; special test for case of dummy RUN of 1 char, which is 1 longer than the teLength, as found
; in KanjiTalk. <9June89smb> test here to save some other processing.
move.l nextStyle(a6),a0
move.w stStartSize(a0),d6
sub.w startChar(a0),d6
subq.w #1,d6
beq.s @FindLineDone
@DoFmtRun
; use the next format to continue searching for a line break position.
; accumulate style offsets on line for line end
moveq #0,d0
move.w offset+2(a6),d1
sub.l start(a6),d1 ; get the offset relative to the text start
add.w d1,EOLCharPosn(a6)
move.l nextStyle(a6),a0
lea stStartSize(a0),a1
move.w startChar(a0),d6
bra @StyleLoop
@FindLineDone
; return d0 = length
moveq #0,d0
move.w offset+2(a6),d0 ; offset mod 64K
sub.l start(a6),d0 ; get the offset relative to the text start
add.w EOLCharPosn(a6),d0 ; absolute position
@finis
unlk a6
movem.l (sp)+,FindLineRegs ; restore
rts
endWith
;formFeed
;----------------------------------------------------------------------
; PROCEDURE NewRomanFindLine
;
; Entry
; d6 start of line search assumed to be at 1st word?
; a3 dereferenced handle
; Exits
; d0 with line end after d6
; Register usage
; d4 width to measure
; d7 flag to indicate multiple styles in record
;----------------------------------------------------------------------
NewRomanFindLine
Movem.l FindLineRegs,-(sp) ; preserve whether use new or old FindLine
with LineBreakFrame
link a6,#localFrame
; textLength: is necessary for CR test and unstyled text
moveq #0,d1 ; longize
move.w teLength(a3),d1 ; doc length
sub.w d6,d1 ; adjusted to lineStart position
move.l d1,length(a6)
; textPtr: pointer to current lineStart position.
movea.l teTextH(a3),a2 ; handle to start of text
movea.l (a2),a2 ; dereference
add.w d6,a2 ; begin search for CR here
tst.b teCROnly(a3) ; do we only want to break on CRs?
bne @CROnlyMode ; yup.
; more initializations
move.l a2,textPtr(a6)
moveq #0,d7 ; flag multiple styles: init to single style
move.w d6,lineStart(a6)
move.w d6,EOLCharPosn(a6) ; start for new EOL position calculation
; set up textWidth: pixel width for displaying the text
moveq #0,d4
move.w teDestRect+right(a3),d4 ; right edge
sub.w teDestRect+left(a3),d4
;; subq #1,d4 ; reduce for caret indent <28>
move.l d4,width(a6) ; textWidth
; test for new style edit record
tst.w teSize(a3) ; check style flag
bpl @CallP2C ; old-style edit record
; test for single or multiple format runs in the text
movea.l teStylesH(a3),a1 ; handle to teStyleRec
movea.l (a1),a1
cmpi.w #1,nRuns(a1)
beq.s @DoStyle ; bra if one style
moveq #1,d7 ; flag multiple styles to process
@DoStyle
moveq #0,d0
move.w d6,d0
bsr GetCurStyle ; a0: ptr to current style, d0: style index
addq.w #1,d0 ; index returned is 0 based but nRuns isn't
move.w d0,styleIndex(a6)
; test for last style run
movea.l teStylesH(a3),a1 ; handle to teStyleRec
movea.l (a1),a1
cmp.w nRuns(a1),d0 ; is styleIndex < nRuns?
bcs.s @StyleLoop ; yes
moveq #0,d7 ; on last style run
; only one run so set up real length of run. The last entry in the styleRun table has
; a startChar posn equal to teLength+1. Must subtract the extra 1 to get the real length
; of the run.
@StyleLoop
move.l a0,currStyle(a6)
lea stStartSize(a0),a1
move.l a1,nextStyle(a6)
Bsr SetStyle ; set grafport style from current style in a0
; set up textStart (beginning of style run) and pin to lineStart
moveq #0,d1 ; longize
move.l currStyle(a6),a0
move.w startChar(a0),d1 ; get start of this format run
cmp.w lineStart(a6),d1 ; must pin to this LineStart!
bhs.s @GetLength ; bra if should use start of style run
move.w d6,d1 ; use beginning of line
@GetLength
; get the length
moveq #0,d0 ; longize
move.w stStartSize(a0),d0 ; end of style run
sub.w d1,d0 ; minus the style start
move.l d0,length(a6)
; test for one or last style to adjust length
tst.w d7
bne.s @CallP2C ; multiple styles so can use next style run for length
sub.l #1,length(a6)
;-----------------------------------------------
@CallP2C
; call Pixel2Char
move.l textPtr(a6),a0 ; textPtr
move.w length+2(a6),d0 ; textLength (style run length)
move.w width+2(a6),d1 ; width
clr.l d2 ; no slop
bsr TEHitTestHook ; call Pixel2Char
; returns:
; d0 (low word) pixel width to character offset in block
; (high word) boolean = TRUE (0001) if offset corresponding to
; the given pixel width was found (ONLY when hook is used!)
; d1.w character offset
; d2.w flagged (0001) if hit on leading edge of char (but not used here)
move.w d1,d3 ; save char offset until after CR test
sub.w d0,d4 ; update pixel width
bls.s @CRTest ; got a hit (width <= 0)
; if at the last style, and pixel width > 0, and the TEHitTestHook is replaced, then
; must check the high word of d0 to see if we REALLY got a hit! <2/16/90smb>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l HitTestHook(a0),a0
pea Pixel2Char
cmpa.l (sp)+,a0
beq.s @NotAHit
; we've been hooked out so test per the old interface specs for a hit.
swap d0
tst.b d0
bne.s @CRTest
;----------------------------------------------------------------------
@NotAHit
; test for CR
move.l textPtr(a6),a2
move.w length+2(a6),d1
bsr TestForCR
tst.b d0 ; did we find a CR?
beq.s @NoCR ; no, just measure
; found a CR
move.w length+2(a6),d0 ; style run length
sub.l d1,d0 ; - characters left (should make this .w) <27>x
add.w EOLCharPosn(a6),d0 ; new break posn
bra @finis
@NoCR
move.l d4,width(a6) ; and save as long.
add.w d3,EOLCharPosn(a6) ; update char offset
tst.w d7
beq @setResult ; only one style or last style to process
; test if we just processed the second to last format run
movea.l teStylesH(a3),a1 ; handle to teStyleRec
movea.l (a1),a1
move.w styleIndex(a6),d0
addq.w #1,d0 ; for next style run
move.w d0,styleIndex(a6)
cmp.w nRuns(a1),d0 ; at last style run?
bne.s @DoNextRun
; last format run: last entry of style run table is a dummy entry = teLength + 1
moveq #0,d7 ; flag no more runs after this one
; special test for case of dummy RUN of 1 char, which is 1 longer than the teLength, as found
; in KanjiTalk. Test here to save some other processing.
move.l nextStyle(a6),a0
move.w stStartSize(a0),d6
sub.w startChar(a0),d6
subq.w #1,d6
; MathCad creates a 0 length style run at the end of the StyleRun array of teLength->teLength, <24>
; instead of teLength->teLength+1, so we're testing for their bug here! <24>
ble @setResult ; problem of 0 length style run in MathCad <24>
;; beq @setResult ; change branching condition <24>
@DoNextRun
; use the next format to continue searching for a line break position.
; accumulate style offsets on line for line end
move.l nextStyle(a6),a0
move.w startChar(a0),d6
moveq #0,d0 ; clear high word before add <30>
move.w length+2(a6),d0
add.l d0,textPtr(a6) ; update textPtr to the next style run
bra @StyleLoop
;----------------------------------------------------------------------
; on the way out nowÉ
;----------------------------------------------------------------------
@CRTest
; test for CR
move.l textPtr(a6),a2
move.w d3,d1 ; offset of char hit is length to use when searching for CR
bsr TestForCR
tst.b d0 ; did we find a CR?
bne.s @GotCR ; yes, done earlier than hit!
; no CR found, so use char offset but back up to word boundary
add.w d3,EOLCharPosn(a6) ; update char offset
move.w EOLCharPosn(a6),d0
; Must test if at a blank since FindWord will backup before testing if not @ posn. 0. <23>
; the problem this introduces is that we will not use an appications hook to teWordBreak if
; there is a blank or non-graphic character in this position.
tst.b d0 ; <23>
beq.s @CallFW ; <23>
@WrdBrkLoop
move.w d0,a1 ; CallBreak wants offset here <23>
bsr CallBreak ; calls Roman wordbreak hooked routine <23>
beq.s @CallFW ; CCs set if char<=$20 & d0 = wordstart <23>
; point past the break character and look for another break character until at EOD <23>
cmp.w teLength(a3),d0 ; is this break character at the EOD <23>
beq @HaveWordSt ; yes, so done <23>
; check if the break character is a CR! don't look ahead if so! <26>
movea.l teTextH(a3),a2 ; handle to start of text <26>
movea.l (a2),a2 ; dereference <26>
move.w d0,-(sp) ; save wordStart <26>
addq.w #1,(sp) ; incr beyond this break character <26>
move.b 0(a2,d0.w),d0 ; fetch the char to test <26>
Bsr TEEOLHook ; <26>
movem.w (sp)+,d0 ; don't change CCs <26>
; now bra based on result of TEEOLHook <26>
beq.s @finis ; found a CR so done <26>
; is a break char but not a CR so, try again <26>
;; addq #1,d0 ; no, so look ahead for next break character <23><26>
bra.s @WrdBrkLoop ; <23>
@CallFW
MoveQ #teFromFind,d2 ; say findLine is calling
bsr FindWord ; word start in d0, word end in d1
@HaveWordSt
; must pin word start to lineStart for the case that it breaks across a word
cmp.w lineStart(a6),d0 ; d6 changes for styled so use actual lineStart <23>
bls @setResult
; test for case of 0 returned if line has no blanks
; (XX) these two lines seem to be redundant!!! (XX)
tst.w d0 ; non-zero word start is ok
bne.s @finis
move.w EOLCharPosn(a6),d0 ; assume P2C result is less than word end found
cmp.w d1,d0 ; use smaller of two
bls @finis ; use P2C result
; (XX) we should never come here! (XX)
move.w d1,d0 ; use word end found
bra @finis
@GotCR
move.w d3,d0 ; style run length
sub.l d1,d0 ; - characters left (should make this .w) <27>x
add.w EOLCharPosn(a6),d0 ; new break posn
bra @finis
;-----------------------------------------------
@CROnlyMode
; since we are in CR only mode, just search for a CR
bsr TestForCR
tst.b d0 ; did we find a CR?
bne.s @FoundCR ; yes
move.w teLength(a3),d0 ; no, return end of text
bra @finis
@FoundCR
move.w teLength(a3),d0 ; doc length <15Mar89smb>
sub.l d1,d0 ; - characters left
bra @finis
; End of CR check
;-----------------------------------------------
@setResult move.w EOLCharPosn(a6),d0 ; want result in d0
@finis
unlk a6
movem.l (sp)+,FindLineRegs ; restore
rts
endWith
;----------------------------------------------------------------------
; PROCEDURE TestForCR
; Called by NewRomanFindLine to search for a carriage return.
; Entry
; d1.w = length to search
; a2.l = text pointer
; Exit
; d0.b = TRUE (FF) if CR found
; d1.w = characters left
; Uses d0,d1
;----------------------------------------------------------------------
TestForCR
tst.w d1 ; is the initial length 0?
beq.s NoCR
; notice: CCs are set to NOT EQUAL at this point.
bra.s @TestLength
@CRLoop
move.b (a2)+,d0 ; is it a CR? changed to byte
Bsr TEEOLHook
@TestLength
dbeq d1,@CRLoop
beq.s GotCR
bra NoCR ; no CR in this run, just measure
NoCR
sf d0 ; return F
rts
GotCR
st d0 ; return T
rts
;formfeed
;----------------------------------------------------------------------
;
; 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
; teLength(a3) reflects the new length (at least for deletion)
; Exit
; dispStart(D2) now set to redraw start
; dispEnd(D4) set to redraw end
; Uses
; d2 redraw start position (aka savedD2)
; d3 initialized to word boundary at selStart(a3)
; d4 redraw end position (aka savedD4)
; d5 for handle size
; a2 ptr to current lineStarts(a3) position
;----------------------------------------------------------------------
;
; ** <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
ReCalLinesRegs reg D3/D5-D6/A2
Link A6,#RecalLink
movem.l ReCalLinesRegs,-(SP) ; save regs
; initialize
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 ClrLineSts ; <19Mar89smb> if not, nothing to recal
;; Beq.S ReCalDone ; if not, nothing to recal <C971/RWW102887>NO
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 comparison <C971/RWW102887>NO
Move D0,D3 ; returned word boundary
; D3 contains the start point to recal from, so find the line containing D3
InitLineStLoop
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 FoundLineBounds ; if inclusive (d3 contained between savedD2 & a2)
Beq.S AtNextLineStart ; if at next line start
AddQ #1,teNLines(A3) ; one more line, keep looking for
Bra.S InitLineStLoop ; line containing selStart(D3)
; The redraw start is in savedD2, which reflects the lineStart of d3.
;------------------------------------------------
AtNextLineStart
; d3 is on the boundary of the next lineStart
Bsr FindLine ; get line end after D6 <C971/RWW102887>NO
Cmp D0,D3 ; did the line break change? (ie - different from current a2)
Bne.S DrawWholeLine ; if so, must redraw whole thing<C971/RWW102887>NO
Move D3,savedD2(A6) ; "next" line OK if at beginning
Bra.S TestRedraw ; <C971/RWW102887>NO
;------------------------------------------------
FoundLineBounds
; d3 is contained between the lineStarts of this line
Bsr FindLine ; get line end after D6 <C971/RWW102887>NO
Cmp D0,D3 ; did the line break change? (is d3 beyond this line end?)
Bhs.S DrawWholeLine ; if so, must redraw whole thing
TestRedraw ; <EHB 05-Nov-85>
Tst.B WordRedraw ; should we redraw the whole word? <EHB 31-Oct-85>
Bgt.S DrawWholeLine ; => yes, app wants whole word <EHB 31-Oct-85>
Blt.S DoRecal ; => app wants whole line <EHB 01-Nov-85>
; final determination of redraw start position
Move teSelStart(A3),D3 ; reset d3 from word boundary to selStart
DrawWholeLine
IF forLocalizability THEN ; <40-YDS-2/5/92>
Cmp.w #teForceLeft,teJust(A3) ; are we forcing left ?
Beq.S @1 ; if so, skip the TESysJust test.
ENDIF
Tst.W teJust(A3) ; see what format: for right or
Bne.S DoRecal ; centered, must use linestart (not selStart)
Tst.W TESysJust ; check text direction ** <C105/14aug86/MBK> **
Bne.S DoRecal ; not left ** <C105/14aug86/MBK> **
; Special case: redraw line didn't work because FoundLineBounds jumped here w/o checking the redraw flag.
@1 Tst.B WordRedraw ; should we redraw the whole word? ** <C454/21nov86/MBK> **
Blt.S DoRecal ; => app wants whole line ** <C454/21nov86/MBK> ** <19>
; restored to original state <19>
;; Bne.S DoRecal ; => app wants whole line for double-byte as well! <12/14/88smb><19>
; if here, then teJust = teSysJust = 0 AND wordRedraw = 0 or 1.
Move D3,savedD2(A6) ; return word start-1
Beq.S DoRecal
; must call DoubleByte here to backup to the correct position <25>
subq #1,savedD2(a6)
tst.b wordRedraw ; if Roman then don't call DoubleByte <25>
beq.s DoRecal ; <25>
movem.l d0-d4/d6/d7/a2,-(sp) ; save regs across call (better safe than sorry!) <25>
move.w d3,d6 ; DoubleByte wants offset here <25>
move.w #-1,d3 ; incremental direction to move <25>
bsr DoubleByte ; <25>
move.w d6,savedD2(a6) ; <25>
movem.l (sp)+,d0-d4/d6/d7/a2 ; <25>
;; Bra.S DoRecal <16> unnecessary
DoRecal
; d3 reflects the start position for the recalibration of the line
Move.W D0,D3 ; save next 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
IF &TYPE('&RWWDebug') = 'UNDEFINED' THEN
Bsr.s InsertRecal ; recal for insertions
ELSE
Bsr InsertRecal ; recal for insertions
ENDIF
Bra.s ReCalDone ; <19Mar89smb>
ClrLineSts ; <19Mar89smb> clear first two words of lineStarts array
move.l #0,teLines(a3)
;------------------------------------------------
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)+,ReCalLinesRegs ; restore regs
Unlk A6
Rts ; see you later
;formFeed
;------------------------------------------------------------------
; PROCEDURE InsertRecal
;
; Only called from ReCalLines.
;
; Entry
; d3 line start of next line
; d6 lineStart(a3) of line containing savedD2(a6) (redraw start position)
; d7 delta = oldLength-newLength
; a2 line starts array
; savedD2(a6) redraw start position
;
; Uses
; d4 loop terminator for determining next line end; initialized to selEnd
; d5 lineStart counter
; ** <C105/3Sep86/MBK> ** Stages 2 and 3 for insertion only
;------------------------------------------------------------------
InsertRecal
MoveM.L D2/D4,-(SP) ; save stuff
MoveQ #0,D5 ; size of temp line start array
Move.W teSelEnd(A3),D4
If &TYPE('&RWWDebug') = 'UNDEFINED' Then
Tst.W D7 ; Only do "subtraction" if negative <PMAB381/RWW020488>
Bpl.S @PosDeltaLength ; <PMAB381/RWW020488>
EndIf
Sub.W D7,D4 ; new terminator: selEnd + delta
@PosDeltaLength
; ** <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
;------------------------------------------------
iLineLoop
; 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 @CharWidthOK ; ok if not ** <C440/18nov86/MBK> **
AddQ #1,D3 ; else advance to next char ** <C440/18nov86/MBK> **
@CharWidthOK
Cmp D4,D3 ; beyond selEnd?
Bls.S SaveLineSt ; if not, save lineStart and fetch next one
; have calculated all necessary lineStarts: proceed!
; test for CR
Move.L teTextH(A3),A0 ; get text handle
Move.L (A0),A0 ; deref
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) <not always!>
; find the old value of this line start for moving down remaining line starts
@OldLineStLoop
Cmp.W (A0)+,D0
Bhi.S @OldLineStLoop ; made this unsigned ** <C381/6nov86/MBK> **
SubQ #2,A0 ; got over-incremented
Move.L A0,savePtr(A6) ; save it
Bra iStage3 ; on to stage 3 <SM7> CSS
@3
; D5 (temp lineStart array) 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 SaveLineSt ; 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 SaveLineSt ; keep trying if not same
Add.L D5,savePtr(A6) ; set old start for move down
Bra.S iStage3
SaveLineSt
; 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 @FindNextLine ; 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> **
@FindNextLine
Bsr FindLine ; get line after D6 <C971/RWW102887>NO
Move D0,D3 ; findline returns in D0
Bra iLineLoop ; <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
;formFeed
;------------------------------------------------
If &TYPE('&RWWDebug') <> 'UNDEFINED' Then
;------------------------------------------------------------------
; PROCEDURE DeleteRecal
;
; Called only by ReCalLines, although it appears that
; Russ has removed it from ever being used ever again....
; hmmmm.....
;
; ** <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 #returnChar,-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>
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE SetLineHite
;
; ** Added 6/18/86 by MBK **
;
; Called only by ReCalLines
;
; 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
; a6 stack frame of RecalLink
;----------------------------------------------------------------------
SetLineHite
MoveM.L D2-D6/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 @GetStyles ; 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 ; style index to 1st style (in runs array) ** <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> **
@GetStyles
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 @CmpStarts ; 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 @SetEntry ; just set it if so
Tst.W (A4) ; else, see if it should be set
Bmi.S @CmpStarts ; if neg don't reset (high bit set indicates user set entry)
@SetEntry
Move.W D1,(A4) ; else set height
Move.W stAscent(A0,D0.L),2(A4) ; set ascent ** <C381/6nov86/MBK> ** made D0 long
@CmpStarts
Move.W 2(A2),D0 ; get next line start
Cmp.W stStartSize(A1),D0 ; cmp to next style start
Blo.S @GetNxtLine ; multiple lines of a style; made this unsigned ** <C381/6nov86/MBK> **
Beq.S @GetNxtStyle ; next style (style end = line end)
AddQ.L #stStartSize,A1 ; pt to next style (multiple styles on a line)
Bra.S setLoop ; keep checking this line
@GetNxtStyle
AddQ.L #stStartSize,A1 ; pt to next style
@GetNxtLine
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-D6/A2/A4 ; restore registers
Rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE ShowCaret
; PROCEDURE HideCaret
; PROCEDURE DrawCaret
; PROCEDURE EraseCaret
;
; Entry:
; A3 contains dereferenced handle
;
;----------------------------------------------------------------------
ShowCaret
Tst.B teActive(A3) ; do nothing if not active
Beq noDrawIt ; <C971/RWW102887>NO
Move teSelStart(A3),D0 ; see if should be turned on
Cmp teSelEnd(A3),D0
Bne 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 #teCaret,D7 ; does nothing except moves pen
Bsr DoText ; draw the caret
@Cursor2
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 NOT ForROM THEN ; <9Dec88smb>
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 hasCQD THEN ; <9Dec88smb>
Bsr CaretHook ; <C971/RWW102887>NO
Else
Bsr InvertHook ; <C971/RWW102887>NO
EndIf
; test if a second cursor must be drawn <28Oct88smb>
tst.w teSize(a3)
bmi.s @Test4Cursor2 ; bra if styled text
tst.b WordRedraw
;; bpl.s @done ; bra if Roman/double-byte old style edit record
bmi.s @Test4Cursor2 ; <6July89smb>
tst.b teSysJust ; <6July89smb>
; bra if Roman/dbl-byte, unstyled and lineDir = LR <6July89smb>
beq.s @done ; <6July89smb>
@Test4Cursor2
move.l ExpandMem,a0 ; <1Feb89smb>
tst.b ExpandMemRec.emTwoCursorsFlag(a0)
beq.s @done
; draw a 2nd rectangle for split cursors:Top,Left,Bottom,Right
;;unnecc <26Nov89smb> move.l ExpandMem,a0 ; <1Feb89smb>
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right <12July89smb>
move.l (a0)+, teSelRect+top(a3)
move.l (a0), teSelRect+bottom(a3)
move.l ExpandMem,a0 ; <1Feb89smb>
sf ExpandMemRec.emTwoCursorsFlag(a0)
;;???<26Nov89smb> sf (a0)
bra.s @Cursor2
@done
MoveM.L (SP)+,D0-D7
noDrawIt
Rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEActivate( h: TEHandle )
; PROCEDURE TEDeActivate( h: TEHandle )
;
;----------------------------------------------------------------------
TEActivate
with OutlineFrame
bsr StdEntry ; <C971/RWW102887>NO
link a6,#OutlineFrameSz ; only link if outlining
tst.b teActive(A3) ; see if already active
bne.s goGoHome
; fix the selection when inactive
bsr.s InitOutline
move teSelStart(a3),d0 ; Only enable the caret
cmp teSelEnd(a3),d0
bne.s @notSelPt
st teCarAct(a3) ; activate caret
; hide the caret when outline highlight on <2Oct89smb>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFOutlineHilite,d0
beq.s @notSelPt ; no outlining desired
bsr DrawIt ; hide the caret
@notSelPt
st teActive(a3) ; flag as active
bsr HiLite
bra.s DoneActivate ; rejoin flow of control
;----------------------------------------------------------------------
TEDeactivate
with OutlineFrame
bsr StdEntry ; <C971/RWW102887>NO
link a6,#OutlineFrameSz ; only link if outlining
tst.b teActive(a3)
beq.s goGoHome
move teSelStart(a3),d0 ; is this a selection point?
cmp teSelEnd(a3),d0
bne.s @drawRegion ; fall through for caret processing
; is outlining desired?
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFOutlineHilite,d0
beq.s @drawRegion ; outline bit not on
; if caret on invert it
tst.b teCarOn(a3)
beq.s @noDraw
bsr DrawIt
@noDraw
; turn on flag in case off - want to display an outlined caret
st teCarOn(a3) ; will be turned off in HideCaret
@drawRegion
bsr.s InitOutline
bsr HideCaret ; hide the caret
bsr HiLite ; Remove old selection
sf teActive(A3) ; flag as inactive
; drop through to common exit
;-----------------------------------------
DoneActivate
bsr.s TEOutlineHilite ; outline hilite now
goGoHome
unlk a6
bra goHome
;----------------------------------------------------------------------
; PROCEDURE InitOutline
; <20Sept89smb>
; Test for outline highlighting after setting up teRec
;----------------------------------------------------------------------
InitOutline
with OutlineFrame
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFOutlineHilite,d0
beq.s @RegHilite
_OpenRgn
move.l teHiHook(a3),oldHighHook(a6) ; save
move.l teCarHook(a3),oldCaretHook(a6) ; save
lea FrameHook,a0 ; just frame it
move.l a0,teHiHook(a3) ; stuff it!
move.l a0,teCarHook(a3) ; stuff it!
st paintFlag(a6) ; init to always paint region <16Oct89smb>
@RegHilite
rts
;-----------------------------------------
FrameHook
_FrameRect
Rts
;----------------------------------------------------------------------
; PROCEDURE TEOutlineHilite
; <20Sept89smb>
;----------------------------------------------------------------------
TEOutlineHilite
with OutlineFrame
; do we need anything fancy
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFOutlineHilite,d0
beq @DoneTEOutlineHilite ; don't do fancy stuff!
; now do the outlining <20Sept89smb>
move.l a4,-(sp) ; save TE handle
subq.l #4,sp ; handle to outline region
_NewRgn
; handle to outline region still on stack
move.l (sp),a2 ; save outline region
_CloseRgn
subq.l #4,sp ; handle to view region
_NewRgn
; handle to view region still on stack
move.l (sp),a4 ; save view region
pea teViewRect(a3) ; view Rectangle
_RectRgn
move.l a4,-(sp) ; view region
move.l a2,-(sp) ; outline region
move.l a2,-(sp) ; intersection of view and outline regions
_SectRgn
move.l a4,-(sp) ; view region
_DisposRgn
; set up for drawing
pea oldPenState(a6)
_GetPenState
move.w #1,-(sp)
move.w #1,-(sp)
_PenSize
move.l GrafGlobals(a5),a0 ; get graf globals
move.w teSelStart(a3),d0
cmp.w teSelEnd(a3),d0
bne.s @NoCaret
; got a caret
lea gray(a0),a4 ; modified a bit <2Oct89smb>
move.w #PatXOr,d2
bra.s @doPen
@NoCaret
lea black(a0),a4 ; @black pattern
; test if color QD available
move.w #PatXOr,d2 ; assume no color QD
move.l #gestaltQuickdrawVersion,d0
_Gestalt ; result returned in a0
tst.w d0 ; OSErr result returned here
bne SysErr
move.l a0,d0 ; test result in a0!
beq.s @doPen ; no color QD available
move.w #50,d2 ; hilite
@doPen
move.w d2,-(sp)
_PenMode
move.l a4,-(sp)
_PenPat
; draw
move.w teSelStart(a3),d0
cmp.w teSelEnd(a3),d0
beq.s @Caret
; no caret so outline
move.l a2,-(sp)
_FrameRgn
tst.b paintFlag(a6) ; don't paint for Updating <16Oct89smb>
beq.s @NoPaint
@Caret
move.l a2,-(sp)
_PaintRgn
@NoPaint
move.l a2,-(sp)
_DisposRgn
move.l (sp)+,a4 ; restore TE handle
pea oldPenState(a6)
_SetPenState
move.l oldHighHook(a6),teHiHook(a3) ; restore
move.l oldCaretHook(a6),teCarHook(a3) ; restore
@DoneTEOutlineHilite
rts
;formFeed
;----------------------------------------------------------------------
;
; 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 forLocalizability THEN ; <31p-YDS-8/27/91>
Not.B teCarOn(A3) ; flip the flag
Bsr DrawIt ; flip the caret
ELSE
Bsr DrawIt ; flip the caret
Not.B teCarOn(A3) ; flip the flag
ENDIF
goHome
Bra epilog4
;formFeed
;----------------------------------------------------------------------
;
; 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 PasteGuts ; go paste the scrap <C971/RWW102887>NO <SM7> CSS
@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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEStylPaste( 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.
;
;----------------------------------------------------------------------
;iTEStylePaste ; comment out for now <45>
iTEStylPaste
MoveQ #1,D7 ; flag says normal paste
Bsr.S DoPaste ; <C971/RWW102887>NO
MoveQ #6,D0
Bra StdExit2
;formFeed
;----------------------------------------------------------------------
;
; 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 TESetStyle. 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
;formFeed
;----------------------------------------------------------------------
;
; 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
Bsr ConcatRuns ; <25June89smb>
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
;formFeed
;----------------------------------------------------------------------
;
; 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 for locking & call to PstStylGuts
Move.L A0,-(SP) ; save the handle for disposing later
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
_StripAddress ; clean up high byte of length <5June89smb>
_BlockMoveData ; make room
MoveM.L (SP)+,D2-D3/A2
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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
move.w d0,d2 ; temp storage <5July89smb>
; if in the last style run in the record, the real end of the run is really one char back. <5July89smb>
move.w (a0),d0 ; <5July89smb>
cmp.w teLength(a3),d0 ; <5July89smb>
bls.s @NotLastRun ; <5July89smb>
sub.w #1,d0 ; at the last run: fix the end <5July89smb>
;;<5July89smb> Cmp.W startChar(A0),D0 ; does a new style start here?
@NotLastRun
exg d0,d2 ; restore <5July89smb>
cmp.w d0,d2 ; does a new style start here? <5July89smb>
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
;formFeed
;----------------------------------------------------------------------
;
; 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 <24July89smb> changed to nStyles
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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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 <24July89smb> changed to nStyles
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 <24July89smb> changed to nStyles
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
_BlockMoveData ; 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)
;formFeed
;----------------------------------------------------------------------
;
; 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 TESetStyle. 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/a1/a4,-(SP) ; added a1 for unlocking later <20>
Move.L A1,A4 ; put scrap handle in A4
; Gotta lock down null scrap! <20>
move.l a1,a0 ; <20>
_HLock ; <20>
MoveQ #0,D3 ; clear whole register
Move.W teSelStart(A3),D3 ; PstStylGuts wants this
Bsr PstStylGuts ; go paste it
movem.l (sp)+,d3/a1/a4 ; added a1 for unlocking <20>
; Unlock previously locked null scrap <20>
move.l a1,a0 ; <20>
_HUnlock ; <20>
Bsr ClearRsrved ; selection is different now
; text already inserted by InsGuts so okay to call ConcatRuns now
bsr ConcatRuns ; <25June89smb>
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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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 selection 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEKey( key: CHAR; h: TEHandle );
;
; ** Modified 6/18/86 by MBK **
;
;----------------------------------------------------------------------
TEKey
; turn off textBuffering bit before calling StdEntry since want to process below <17Sept89smb>
move.l 4(sp),a1 ; teHandle (before the return address)
move.l (a1),a1 ; need the ptr to the teRec
move.l teDispatchH(a1),a1
move.l (a1),a1
move.l newTEFlags(a1),-(sp)
move.l #0,newTEFlags(a1)
Bsr TEKeyStdEntry
;; Bsr StdEntry ; <C971/RWW102887>NO
; reset textBuffering bit <17Sept89smb>
move.l teDispatchH(a3),a1
move.l (a1),a1
move.l (sp)+,newTEFlags(a1)
_ObscureCursor ; nice knowing you cursor
Move.W (A2),D1 ; store char away
move.b d1,d0 ; get char for comparison
MoveQ #1,D2 ; assume going down
; 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
IF 0 THEN ; bye bye for now <29>
cmp.b #forwardDeleteChar,d0 ; is this the extended keyboard function key? <20>
bne.s @CursorKeys ; <20>
st teLftCaret(A3) ; jam caret to left cause its nota cursor key <20>
; be sure d6 is not used in any subroutines called from here!!!!
st d6 ; tell backspace that we are going forward <20>
bra backspace ; do common backspace code <20>
@CursorKeys
ENDIF ; <29>
subi.b #downArrowChar,d0
Beq.S downArrow
bhi.s normalChar ; optimize normal characters
subi.b #upArrowChar-downArrowChar,d0
Beq.S upArrow
subi.b #rightArrowChar-upArrowChar,d0
Beq rightArrow
subi.b #leftArrowChar-rightArrowChar,d0
Beq leftArrow
st teLftCaret(A3) ; jam caret to left, UNLESS a cursor key <7Aug89smb>
IF 0 THEN ; bye bye for now <29>
; be sure d6 is not used in any subroutines called from here!!!!
sf d6 ; tell backspace that we are going backward <20>
ENDIF ; <29>
subi.b #backspaceChar-leftArrowChar,d0
Beq backSpace
normalChar
; test if want text buffering <12June89smb>
st teLftCaret(a3) ; jam caret to left, UNLESS a cursor key <7Aug89smb>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0
btst #teFTextBuffering,d0
beq PasteChar ; little mod <15June89smb>
;; Bra.S PasteChar ; => go paste in the character
bsr TEBufferText ; <30Jan89smb>
bra Epilog6 ; <30Jan89smb>
upArrow
;; subtract 2 rather than 1 <1/25/90smb> MoveQ #-1,D2 ; going up
MoveQ #-2,D2 ; going up
downArrow
Move D2,-(SP) ; save D2
; dump text buffer before processing cursor key <14Sept89smb>
Move.L teDispatchH(a3),a0
Move.L (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops <15Sept89smb>
btst #teFTextBuffering,d0 ; <15Sept89smb>
beq.s @noBuffer
bsr DumpBuffer ; dump text from buffer
@noBuffer
; Call HideCaret to fix problems with old and new teLftClick <1/25/90smb>
bsr HideCaret ; erase old caret <1/25/90smb>
Move teSelStart(A3),D3 ; pass selStart=selEnd
Move D3,D4
moveq #teCaret,d7 ; position pen to caret <03July89smb>
bsr DoText ; the port ret. in A0
move (sp)+,d2 ; restore D2
;-------------------------------------------------------------------------------------
; In order to go down from a line end position to a line whose line height is less than the current
; line height, must back up one position to get the hite for the correct line (when FindLineHite
; calls GetLine and the current position is at the end of a line, it thinks it's at the
; beginning of the next line so the wrong height is returned. <1/30/90smb>
movem.l a2/d3,-(sp)
tst.b teLftCaret(a3)
bne.s @OffsetOK
move.w d3,d0 ; offset
beq.s @OffsetOK
lea teLines(a3),a2
bsr GetLine ; get line that d3 is on
cmp.w (a2),d3 ; cmp offset position to line start found
bne.s @OffsetOK
subq.w #1,d3 ; backup to get correct line in FindLineHite
@OffsetOK
bsr FindLineHite ; get current line hite in d1 ** MBK 6/18/86 **
movem.l (sp)+,a2/d3
; end of changes <1/30/90smb>
;-------------------------------------------------------------------------------------
;; <1/25/90smb> muls d1,d2 ; get delta -- a SIGNED 16-bit value<09Dec85 JTC>
; if we are going down (d2 = 1), then add linehite (d1) <1/25/90smb>
; if we are going up (d2 = -2), then subtract 2, just enough to get into the previous line's Rect <1/25/90smb>
tst.w d2 ; up or down <1/25/90smb>
blt.s @DeltaOk ; up = -1 <1/25/90smb>
move.w d1,d2 ; move in delta <1/25/90smb>
@DeltaOk
; assume whole caret or high caret in teSelRect <26Nov89smb>
move.l teSelRect(a3),teSelPoint(a3) ; pass caret point
;-------------------------------------------------------------------------------------
; set teSelPoint(a3) from the high caret position! <26Nov89smb>
move.l ExpandMem,a0 ; <26Nov89smb>
cmpi.w #$FFFF,ExpandMemRec.emTwoCursorsFlag(a0) ; <26Nov89smb>
bne.s @UseSelRect ; bra if high caret loc in teSelRect <26Nov89smb>
; use rect stored in emCursor2Rect: this is the high caret location. <26Nov89smb>
lea ExpandMemRec.emCursor2Rect(a0),a0 ; <26Nov89smb>
move.l (a0),teSelPoint(a3) ; pass high caret point <26Nov89smb>
@UseSelRect
;-------------------------------------------------------------------------------------
add d2,teSelPoint(a3) ; adjust v value
bsr DoFind ; the port ret. in A0
;; <5Aug89smb> screws up DoCaret! ST teLftCaret(A3) ; force clean clicks
move.b teLftClick(a3),teLftCaret(a3) ; <10Aug89smb>
Bra.w leftRight ; setselect'll force autoscroll
rightArrow
Move teSelEnd(A3),D6 ; get start
MoveQ #1,d3 ; if 2byte char, incr posn <27June88smb>
bra.s HorizArrows ; <6Mar89smb>
leftArrow
Move teSelStart(A3),D6 ; get start
beq.s HorizArrows ; <13Mar89smb> special case at 0th position
MoveQ #-1,d3 ; if 2byte char, decr posn <27June88smb>
HorizArrows
; dump text buffer before processing cursor key <14Sept89smb>
Move.L teDispatchH(a3),a0
Move.L (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops <15Sept89smb>
btst #teFTextBuffering,d0 ; <15Sept89smb>
beq.s @noBuffer
bsr DumpBuffer ; dump text from buffer
@noBuffer
tst.b WordRedraw ; <9Jan89smb>
blt.s @RLText ; <22June89smb> includes RL directional text
tst.b teSysJust ; <22June89smb>
beq.s @LRLineDir ; <22June89smb> LR text on a LR line
@RLText
; may be RL text on any directioned line OR LR text on a RL line
bsr CursorMovement ; <9Jan89smb>
; <31k-YDS-8/27/91>
; supports the single carret corect display
IF forLocalizability THEN ; when on cluster boundry, syncronize allways to the
; style with the that his just = teSysJust
tst.b WordRedraw ; have L->R script ?
bge.s leftRight ; no, do the old way
tst.w teSize(a3) ; if unstyled ?
bpl.s leftRight ; do the old way for unstyled
move.w d6,d0 ; GetCurStyle needs offset in d0
bsr GetCurStyle ; get the current style
cmp.w startChar(a0),d6 ; are we on a boundry ?
bne.s leftRight ; if not do it the old way
move.l a0,-(sp) ; keep a0 (the style) from being trashed
Bsr HideCaret ; hide caret
Bsr HiLite ; unhilite
Move d6,teSelEnd(A3) ; set set start
Move d6,teSelStart(A3) ; set sel end
move.l (sp)+,a0 ; restore style ptr (in a0)
bsr GetDirection ; get style direction
cmp.b TESysJust,d1 ; same as TESysJust ?
beq @setStyle ; yes ! set the style for it.
move.w d6,d0 ; no ! get the prev style, put offset into d0
sub.w #1,d0 ; be in prev
bsr GetCurStyle ; get this style
@setStyle bsr SetStyle ; set the font/style in the grafport
move.w d6,d0 ; char offset in d0 needed by SetKeyboard2Font
bsr SetKeyboard2Font ; sync keyboard to font
Bsr HiLite ; Hilite
Bsr SelView ; insure selection is visible
Bsr ShowCaret ;
Bra epilog6
ELSE
bra.s leftRight ; <9Jan89smb>
ENDIF
@LRLineDir
Bsr DoubleByte ; middle of char? Fix starting point <27June88smb>
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
IF 0 THEN ; bye bye for now <29>
Bra epilog6 ; <29>
ELSE ; <29>
Bra.w epilog6
ENDIF ; <29>
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
Bsr BufferChar ; buffer if 2 byte character <27June88smb>
IF 0 THEN ; bye bye for now <29>
blt epilog6 ; the result isn't unsigned! <31Aug89smb> <29>
ELSE ; <29>
blt.w epilog6 ; the result isn't unsigned! <31Aug89smb>
ENDIF ; <29>
moveq #0,D7 ; want to call ExtendStyle
bsr PasteGuts
;; <1/9/90smb> move.l ExpandMem,a0 ; <1Feb89smb> finished w/ character
;;<6Nov89smb> clr.w ExpandMemRec.emBufferPtr(a0) ; empty buffer; temp use of space <2Feb89smb>
;; <1/9/90smb> clr.w ExpandMemRec.emBufferLen(a0) ; empty buffer <6Nov89smb>
move.l teDispatchH(a3),a0 ; <1/9/90smb> finished w/ character so empty storage
move.l (a0),a0
IF forLocalizability THEN ; <31b-YDS-8/27/91>
move.w #0,TwoByteCharBuffer(a0)
ELSE
move.l #0,TwoByteCharBuffer(a0)
ENDIF
bra.w epilog6
backSpace
; dump text buffer before backspacing <14Sept89smb>
Move.L teDispatchH(A3),A0
Move.L (A0),A0
move.l newTEFlags(a0),d0
btst #teFTextBuffering,d0
beq.s @noBuffer
bsr DumpBuffer ; <30Jan89smb> dump text from buffer
@noBuffer
Move teSelStart(A3),D0 ; see if null selection
Cmp teSelEnd(A3),D0
Bne.S cutit
;------------------------
IF 0 THEN ; bye bye for now <29>
; add support for the forward delete key <7jan91 fjs><20>
tst.b d6 ; is this forward delete ? <20>
beq.s @normalBS ; if 0 do normal backspace work <20>
; since there is no selection, eat characters to the right
; first, check if we are at the extreme right already
cmp.w teLength(a3),d0 ; at extreme right of text? (really, the endÉ think R-L)<20>
bge.s epilog6 ; yes, skip this <20>
bsr HideCaret ; remove the caret <20>
; check for double-byte characters and fix starting point
move.w teSelEnd(a3),d6 ; current position <20>
moveq #1,d3 ; direction to move <20>
bsr DoubleByte ; middle of char? Fix starting point. <20>
move.w d6,teSelEnd(a3) ; adjust selection <20>
bra.s cutit ; fall into the cut case <7jan91 fjs><20>
@normalBS
ENDIF ; <29>
;------------------------
; since there's no selection eat characters to the left.
Tst D0 ; see if at extreme left (really, the beginningÉ think R-L)
Beq.w epilog6 ; skip if so
Bsr HideCaret ; remove the caret
;; SubQ #1,teSelStart(A3) ; adjust selection
; check for double-byte characters and fix starting point. <27June88smb>
move.w teSelStart(a3),d6 ; current position <27June88smb>
moveQ #-1,d3 ; direction to move <27June88smb>
Bsr DoubleByte ; middle of char? Fix starting point <27June88smb>
move.w d6,teSelStart(A3) ; adjust selection
cutit
; Need to synchronize keyboard to the font <2/28/90smb>; moved here from DelGuts.
; This must be done before the call to TEDelete in order to synchronize the kbd to
; the style that corresponds to the current selStart.
tst.w teSize(a3) ; if unstyled, try synch keyboard to font anyway>
IF forLocalizability THEN ; even if we dont have all info
bpl.s @syncUnStyled ; sync for unstyled <31n-YDS-8/27/91>.
ELSE
bpl.s @JustCut ; <2/28/90smb>
ENDIF
move.w teSelStart(a3),d0 ; use current offset position <2/28/90smb>
bsr GetCurStyle ; <2/28/90smb>
bsr SetStyle ; <2/28/90smb>
bsr SetKeyboard2Font ; synch keyboard to font <2/28/90smb>
IF forLocalizability THEN ; synch for unstyled too <31n-YDS-8/27/91>
bra @JustCut ; go to the cut if didn't come with a bpl.s
@syncUnStyled
IF 0 THEN ; now using 'itlb' flag in CubeE <45>
;; tst.b WordRedraw ; is it a R->L script ? <34>
;; bge.w @JustCut ; don't synch. <34>
; Really want to synchronize for unstyled text in ALL scripts. However, this will cause problems for <34>
; input methods, so we will skip this code in this case. (WordRedraw only indicates the <34>
; types of scripts installed and not the current oneÉ) <34>
subq #2,sp ; result space for Font2Script & GetScript <34>
move.w teFont(a3),-(sp) ; app font id <34>
_Font2Script ; it's a non-roman char so get script font <34>
move.w (sp)+,d0 ; <34>
beq @UseFont ; if Roman then always synchronize <34>
cmp.w #smEastEurRoman,d0 ; Extended Roman? <38>
beq @JustCut ; If so, never synchronize <38>
subq #4,sp ; result space <34>
move.w d0,-(sp) ; script <34>
move.w #smScriptRedraw,-(sp) ; <34>
_GetScript ; <34>
move.l (sp)+,d1 ; <34><37>
tst.b d1 ; leave in d1 for later <34><37>
bgt @JustCut ; if double-byte script don't synchronize <34>
; otherwise, we have a single-byte non-Roman font <34>
; IF SysVers > $610 THEN
; move.l teDispatchH(a3),a0 ;
; move.l (a0),a0
; move.l newTEFlags(a0),d0 ; move into reg the flags
; btst #teFInlineInput,d0 ; are we in an inline input window ?
; bne.w @JustCut ; yes, don't synch keyboard.
; ENDIF
ELSE ; now using 'itlb' flag in CubeE <45>
; optimize for Roman-only: do not have to synch font & kbd <50>
with smgrRecord ; <50>
GetSMgrCore a0 ; load SMgr globals pointer. <50>
cmp.b #1,smgrEnabled(a0) ; how many scripts enabled? <50>
beq @JustCut ; skip synchronization for Roman-only system <50>
endwith ; <50>
subq #6,sp ; result space for Font2Script & GetScript <45>
move.w teFont(a3),-(sp) ; app font id <45>
_Font2Script ; get script font <45>
; script left on stack ; <45>
move.w #smScriptFlags,-(sp) ; now get script-specific flags <45>
_GetScript ; <45>
move.l (sp)+,d0 ; <45>
and.l #(1<<smsfSynchUnstyledTE),d0 ; leave only the synchronize bit <45>
beq @JustCut ; 0=> do not synchronize <45>
; otherwise synchronize
ENDIF ; now using 'itlb' flag in CubeE <45>
Move.w teSelStart(a3), d6 ; <33-YDS-10/1/91> d6 was set only for a one char delete, not for a selection delete
; Check char to determine how to synch
move.l teTextH(a3),a2 ; handle to text <37>
move.l (a2),a0 ; ptr to text <37>
move.b 0(a0,d6.w),d0 ; get character <37>
cmp.b #$20,d0 ; control char? <37>
blo.s @JustCut ; if so, don't synch <37>
move.b d1,-(sp) ; save scriptRedraw <37>
subq #2,sp ; room for return
move.l a0,-(sp) ; push text ptr on stack <37>
move.w d6,-(sp) ; offset on stack
_CharType ; what char is it
move.w (sp)+,d0 ; take result
move.b (sp)+,d1 ; recover scriptRedraw <37>
; Mask off what interested in: the Type ($000F) and the Direction ($2000) <34>
; Want a char whose Direction is LR (smCharLeft, $0000) and whose Type is Roman <34>
; which can be smCharAscii (1) or smCharEuro (7) or smCharPunct (0). <34>
;
; New approach. Different behavior for bidi and non-bidi scripts, because of caret <37>
; requirements for bidi scripts. <37>
bne.s @doBidi ; check scriptRedraw for bidi <37>
; For non-bidirectional scripts, set keyboard to Roman for Roman letters, <37>
; sync to font for script letters, dont sync for anything else. <37>
and.w #smcTypeMask,d0 ; isolate info we need <37>
cmp.w #smCharPunct,d0 ; non-letter? <37>
beq.s @JustCut ; if so, don't synch keyboard <37>
cmp.w #smCharAscii,d0 ; low-ASCII Roman? <37>
beq.s @isRoman ; if so, go set keyboard <37>
cmp.w #smCharEuro,d0 ; Extended ASCII Roman? <37>
beq.s @isRoman ; if so, go set keyboard <37>
bra.s @UseFont ; otherwise, sync keyboard to font <37>
; For bidirectional scripts, don't synch control chars (stripped out above) or low-ASCII <37>
; (L-R) digits; synch other L-R chars to Roman, and everything else to font script. <37>
@doBidi ; <37>
and.w #smcTypeMask+smcClassMask+smcRightMask,d0 ; isolate info we need <37>
cmp.w #smCharPunct+smPunctNumber+smCharLeft,d0 ; is char a low-ASCII digit? <37>
beq.s @JustCut ; if so, don't synch <37>
and.w #smcRightMask,d0 ; now just check direction <37>
beq.s @isRoman ; if left-right, sync to Roman <37>
; Otherwise, synch the font to the script of the character <34>
@UseFont
subq #2,sp ; room for return
move.w teFont(a3),-(sp) ; app font id
_Font2script ; it's a non-roman char so get app font
; leave script on stack
bra.s @SetKbd
@isRoman move.w #smRoman,-(sp) ; we think it is roman
@SetKbd
move.w (sp), d0 ; script param on the stack
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0 ;
move.b d0, lastScript(a0) ; push script numberused to highligt (d0) to lastScript
_KeyScript ; set keyboard
ENDIF
@JustCut
Move.L A4,-(SP) ; pass the handle
_TEDelete ; and cut it (A3 no good after)
epilog6 MoveQ #6,D0
Bra StdExit
;formFeed
;----------------------------------------------------------------------
;
; TEBufferText
; <30Jan89smb>
;
; Buffer input characters (graphic). This is to help performance for
; Asian systems.
;
; Input
; (a2) character (or half a character in the case of double-byte chars)
; to be buffered
;
; Uses a0,a1,d0
;----------------------------------------------------------------------
TEBufferText
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vTEBufferText(a0),a0
jmp (a0)
xTEBufferText
; does a pointer to a buffer already exist?
move.l ExpandMem,a1 ; <1Feb89smb>
;; tst.w ExpandMemRec.emBufferLen(a1) ; <14Sept89smb> test for zero len <18>
tst.l ExpandMemRec.emBufferHandle(a1) ; test for no buffer (using handle now for consistency) <18>
bne.s @HaveBuffer
@GetBuffer
moveq #BufferSize,d0 ; longize <18>
bsr.s GetHandle ; allocate handle for buffer; in a0
; dereference the handle and save
move.l ExpandMem,a1 ; <1Feb89smb>
move.l a0,ExpandMemRec.emBufferHandle(a1) ; save handle
@HaveBuffer
; if keybd changes in the middle of buffering must dump the buffer and synch the font to the keybd. <1/26/90smb>
; must set d0 to the current position before calling SetFont2Keyboard<2/28/90smb>
tst.w teSize(a3) ; check style flag
bpl.S @DontSet ; don't set style
move.w teSelStart(a3),d0 ; pass current position <2/28/90smb>
beq.s @SynchUp ; skip test if zero <2/28/90smb>
sub.w #1,d0 ; backup one to get previous style <2/28/90smb>
@SynchUp
bsr SetFont2Keyboard ; <1/26/90smb>
IF hasBufferingFix THEN ; <18>
move.l ExpandMem,a1 ; reload ExpandMem ptr <18>
; SetFont2Keyboard may have called DumpBuffer so test for a deallocated handle <18>
tst.l ExpandMemRec.emBufferHandle(a1) ; is this zero? <18>
beq.s @GetBuffer ; if so, then get another storage handle <18>
ENDIF ; <18>
@DontSet
move.l ExpandMemRec.emBufferHandle(a1),a0 ; get handle of storage space <13Nov89smb>
move.l (a0),a0 ; get to storage space <13Nov89smb>
IF hasBufferingFix THEN ; <18>
moveq #0,d0 ; longize <18>
ENDIF ; <18>
move.w ExpandMemRec.emBufferLen(a1),d0 ; <1Feb89smb> length = number of bytes already in buffer
; have we maxed out on the buffer?
cmpi.w #BufferSize,d0
bne.s @MoreRoom
bsr.s DumpBuffer
IF hasBufferingFix THEN ; <18>
tst.l ExpandMemRec.emBufferHandle(a1) ; the high byte of a char may be in the buffer <18>
beq.s @GetBuffer ; if empty then ok to get another handle <18>
ELSE ; <18>
bra.s @GetBuffer
ENDIF ; <18>
@MoreRoom
move.b 1(a2),(a0,d0.l) ; char in lower byte
addq.w #1,ExpandMemRec.emBufferLen(a1)
rts
;formFeed
;----------------------------------------------------------------------
;
; GetHandle
; <30Jan89smb>
; Allocate a handle.
;
; Input
; d0.l = number of bytes to allocate
; Output
; a0 = handle allocated
; Used by TEBufferText and GetStyleStorage.
;----------------------------------------------------------------------
GetHandle
_NewHandle ,SYS,CLEAR ; allocate and clear a block and return handle in a0 <21>
bne.s sysErr ; exit if system error
_HLock
bne.s CleanUp
rts
; OH NO!!!! can't get no memory!
CleanUp
; deallocate handle in a0
move.l d0,-(sp) ; save initial error
_DisposHandle
move.l (sp)+,d0 ; restore initial error
sysErr
_SysError ; go bye-bye with error in d0
;formFeed
;----------------------------------------------------------------------
;
; DumpBuffer
; <30Jan89smb>
;
; Dump the text buffer. Either it's full or we've
; encountered a condition for dumping (teIdle, control char, etc.)
;----------------------------------------------------------------------
DumpBuffer
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vDumpBuffer(a0),a0
jmp (a0)
xDumpBuffer
dumpRegs reg d0-d7/a1-a2 ; don't save a3/a4! creating a dangling ptr w/ a3 <21>
movem.l dumpRegs,-(sp)
moveq.l #0,d3
move.l ExpandMem,a2 ; <1Feb89smb> buffer is 0 -> n-1
lea ExpandMemRec.emBufferLen(a2),a2 ; changed to lea <12July89smb>
move.w (a2),d2 ; buffer length, n
; test if buffer is empty
beq @Empty ; nothing to dump
; test last (n-1) character in buffer to see if is double-byte char
subq.w #1,d2
move.l ExpandMem,a1 ; <1Feb89smb> pointer to buffer of chars
move.l ExpandMemRec.emBufferHandle(a1),a1 ; <13Nov89smb>
move.l (a1),a1 ; deref for pointer <13Nov89smb>
; <12Sept89smb> we want the font of the last character in the buffer to be set in the grafport before calling CharByte.
movem.l a1/d2,-(sp) ; preserve, for unstyled too!<17Nov89smb>
tst.w teSize(a3) ; if unstyled, can't synch font to keyboard <12Sept89smb>
bpl.s @NoSynch ; <12Sept89smb>
move.w teSelStart(a3),d0 ; pass current position <12Sept89smb>
beq.s @ZeroOffset ; skip test if zero <12Sept89smb>
sub.w #1,d0 ; backup one to get previous style <12Sept89smb>
@ZeroOffset
; just need to use the current position's font: no need to call SetFont2Keyboard! <1/29/90smb>
;; <1/29/90smb> bsr SetFont2Keyboard ; <12Sept89smb>
bsr GetCurStyle ; <1/29/90smb>
bsr SetStyle ; <1/29/90smb>
movem.l (sp),a1/d2 ; restore but don't pop yet <13Nov89smb>
@NoSynch
clr.w -(sp) ; room for return
move.l a1,-(sp) ; use a1 now not the contents of it! <13Nov89smb>
move.w d2,-(sp) ; offset in buffer
_CharByte
move.w (sp)+,d7 ; pop result
movem.l (sp)+,a1/d2 ; restore <13Nov89smb>
tst.w d7 ; high byte of character?
bge.s @GoDump ; no
; yep, gotta save it
move.b (a1,d2.w),d3 ; changed to d2.w <7Dec89smb>
subq.w #1,(a2) ; new length to paste
beq.s @Only1Char ; short cut <13Nov89smb>
@GoDump
; must turn off buffering bit since PasteGuts calls TEPinScroll which calls StdEntry.
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),-(sp)
bclr #teFTextBuffering,newTEFlags+3(a0)
; setUp for buffer dump
move.l a1,d6 ; pointer to text to insert (for PasteGuts) <13Nov89smb>
moveq #0,d5 ; need high word cleared (for PasteGuts) <14Sept89smb>
move.w (a2),d5 ; length of text to insert
movem.l d3/a1/a2,-(sp)
moveq #0,d7 ; want to call ExtendStyle
bsr PasteGuts
movem.l (sp)+,d3/a1/a2
; restore buffering bit
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l (sp)+,newTEFlags(a0)
; test if need to rebuffer 1st byte of double-byte character.
tst.b d3 ; place holder for character
beq.s @DeleteHandle
; last byte in buffer was 1st byte of a double-byte charaacter. Rebuffer it.
move.b d3,(a1) ; <13Nov89smb>
@Only1Char
move.w #1,(a2) ; incr length for byte
bra.s @Empty
@DeleteHandle
; deallocate the handle
move.l ExpandMem,a0
move.l ExpandMemRec.emBufferHandle(a0),a0 ; get to handle! <19Sept89smb>
_DisposHandle
bne SysErr ; <19Sept89smb>
move.w #0,(a2) ; set buffer length to zero. Used as a flag.
IF hasBufferingFix THEN ; <18>
move.l ExpandMem,a0 ; length is initially zero so clear storage for handle <18>
clr.l ExpandMemRec.emBufferHandle(a0) ; flags a disposed handle <18>
ENDIF ; <18>
@Empty
movem.l (sp)+,dumpRegs
rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE CursorMovement();
; <10Jan89smb>
;
; For mixed directional text, must do extensive testing to
; determine the next position for the cursor ( and to have the
; high caret in the position corresponding to the cursor
; movement) based on the arrow key struck. On entry we know that
; the teRecord has mixed-directional text.
;
; Entry
; d1 = arrow key
; d6 = teSelStart (current position of cursor)
; a2 = pointer to arrow key
; a3 = pointer to teRec
; Exit
; d6 = modified to reflect new character offset
;
; Register Usage
; d0 = scratch
; d1 = p, initially: m[p], where p = 0/1
; = r, finally: (previous) format run index
; d2 = q: m[q], where q = 1/0 (opposite of p)
; m[0] = 0: index to leftmost format on line (in fmtOrderingArray)
; m[1] = n: index to rightmost format on line (in fmtOrderingArray)
; d3 = start = 0/1 (opposite of end)
; d4 = end = 1/0 (opposite of start)
; d5 = character delta = -1/1
; d6 = character offset (input/output)
; d7 = format index delta = -1/1
;
; Assumptions for basis of conditions:
; m[0] = 0: index to leftmost format on line (in fmtOrderingArray)
; m[1] = n: index to rightmost format on line (in fmtOrderingArray)
; l[0] = lineStart
; l[1] = lineEnd
; f[i] = format run i
; f[i,0] = start offset for format run i
; f[i,1] = end offset for format run i
; cd = cursor direction; ld = line direction, c = char offset (d6)
;----------------------------------------------------------------------
CursorMovement
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vCursorMovement(a1),a1
jmp (a1)
xCursorMovement
CursorMoveRegs reg d2-d5/d7/a2
with CursorFrame,TEFormatOrder
link a6,#CursorFrameSz
movem.l CursorMoveRegs,-(sp)
; Initializations
sf FormatEndFlag(a6) ; <17Jan89smb>
; ***** cd = left? *****
cmpi.b #leftArrowChar,d1 ; left arrow? <2Aug89smb> cmp byte not word
beq.s @SetLeftCD
; right arrow
move.b #$FF,d0 ; cursor direction = right
move.w #1,d7 ; fmt run index delta (in cursor direction [R])
move.b #1,d2 ; q: m[q] = m[1] = n = rightmost fmt index boundary
moveq #0,d1 ; p: m[p] = m[0] = 0 = leftmost fmt index boundary
bra.s @GetLineDir
@SetLeftCD
moveq #0,d0 ; cursor direction = left
move.w #-1,d7 ; fmt run index delta (in cursor direction [L])
moveq #0,d2 ; q: m[q] = m[0] = 0 = leftmost fmt index boundary
move.b #1,d1 ; p: m[p] = m[1] = n = rightmost fmt index boundary
; ***** cd = ld? *****
@GetLineDir
; get line direction
cmp.b TESysJust,d0
beq.s @CDequalsLD
; CD <> LD: cursor direction <> line direction (left arrow, RL line dir; right arrow, LR line dir)
move.w #-1,d5 ; character delta
move.b #1,d3 ; start
moveq #0,d4 ; end
bra.s @NeedLine
@CDequalsLD
; CD = LD: cursor direction = line direction (left arrow, LR line dir; right arrow, RL line dir)
move.w #$1,d5 ; character delta
moveq #0,d3 ; start
move.b #1,d4 ; end
@NeedLine
; need to test line ends so get current line containing character offset
move.w d6,d0
lea teLines(a3),a2
movea.l a2,a0
bsr GetLine
; special case! if at end of document (test if on last line) and cd <> ld don't
; want to add charDelta<17Jan89smb>
move.w teNLines(a3),d0 ; number of lines
lsl.w #1,d0
add.w d0,a0 ; want end of last line
cmpa.l a0,a2 ; on last line?
bne.s @OtherLineStuff
tst.b d5
blt @done ; at EOD, done.
@OtherLineStuff
; yet another special case! If at the lineStart, and cd = ld, then want to be on
; previous line. <16Jan89smb>
cmp.w (a2),d6
bne.s @OnCorrectLine ; not at lineStart
cmpi.w #0,d6
beq.s @OnCorrectLine ; not beginning of text
tst.b d5
blt.s @OnCorrectLine ; cd <> ld
subq #2,a2 ; previous line
@OnCorrectLine
movem.w d1/d2,-(sp)
bsr GetFormatOrdering ; <8Mar89smb>
movem.w (sp)+,d1/d2 ; restore
; ***** if c = l[s] then c = c *****
; if s = 0, then l[s] = lineStart
; if s = 1, then l[s] = lineEnd
move.b d3,d0 ; start
bsr TestLineEnds
bne @done ; c = c. done
; ***** if c = l[e] then r1 = m[p] *****
; if e = 0, then l[e] = lineStart
; if e = 1, then l[e] = lineEnd
move.b d4,d0 ; end
bsr TestLineEnds
beq.s @FindRun
; ***** r1 = m[p] *****
; d1 = p as input
bsr SetRun ; returns d1.w = r1: leftmost or rightmost format
; ***** d(r1) = ld? *****
bsr TestRunDirection ; d1 = r1 (format index)
bne @CSubDelta ; True: equal
bra @OneCharacterTest
@FindRun
; find r s.t. f[r,0]<c<f[r,1] OR
; ((f[r,0]=c or f[r,1]=c) AND IF on a cluster boundary then d(r)=ld
; Else find r s.t. c = f[r,e])
bsr FindStyleRun ; returns a0 pointing to style run of d6, d1 = r
cmp.w startChar(a0),d6
beq.s @OnBoundary
bsr FixFormatEnd ; <17Jan89smb> if last format run, must decrement
cmp.w d0,d6 ; <17Jan89smb>
bcs.s @InMiddle ; <17Jan89smb> <26June89smb> made unsigned
st FormatEndFlag(a6) ; <17Jan89smb> on end of style run
@OnBoundary
; on boundary: test for cluster boundary <17Jan89smb>
; get this style run's script direction
movem.l d1/d2,-(sp) ; save r (d1) and style
bsr GetDirection
move.b d1,d0
movem.l (sp)+,d1/d2 ; <20Jan89smb>
cmp.b TESysJust,d0 ; <20Jan89smb>
beq @TakeRightBranch ; <20Jan89smb>
move.b d0,RunDirection(a6) ; <20Jan89smb>
; get other boundary style run
tst.b FormatEndFlag(a6) ; test if at start or end of style run
bne.s @GetNextRun ; at end of this style run
; at start of this style run so get previous style run in backing-store order
subq.l #stStartSize,a0
bra.s @GetScriptDir
@GetNextRun
; get next style run in backing-store since at end of this style run
addq.l #stStartSize,a0
@GetScriptDir
; get the other style run's script direction
movem.l d1/d2,-(sp) ; save r (d1) and style
bsr GetDirection
move.b d1,d0
movem.l (sp)+,d1/d2
; compare script directions to see if on a cluster boundary
cmp.b RunDirection(a6),d0
bne.s @ClusterBoundary
; On a style run boundary with both runs of the same script <17Jan89smb>
; ***** d(r) = ld? *****
; d(r) <> ld so find r s.t. c = f[r,e]
; get original boundary style again <25June89smb>
tst.b FormatEndFlag(a6) ; test if at start or end of style run
bne.s @GetPrevRun ; at end of this style run
; at start of this style run so get previous style run in backing-store order
add.l #stStartSize,a0
bra.s @TestStylEnd
@GetPrevRun
; get next style run in backing-store since at end of this style run
subq.l #stStartSize,a0
@TestStylEnd
move.w d1,-(sp) ; save original r
move.b d4,d1 ; end
move.w d6,d0 ; save d6
bsr GetStyleEnd ; returns style start or end in d6
move.w (sp)+,d1 ; restore r
exg d6,d0 ; want original char offset in d6
cmp.w d0,d6 ; does c = f[r,e]?
beq.s @GetNewIndex ; yep
bsr FindStyleRun ; d1 = r s.t. c = f[r,e]
@GetNewIndex
; ***** r1 = r + fmtDelta *****
add.w d7,d1 ; format delta
bra.s @NewFmtIndex ; <20Jan89smb> must check for 1 char in style run
@ClusterBoundary
; find r s.t. (f[r,0]=c or f[r,1]=c) AND d(r)=ld <17Jan89smb>
; Since the character is on a cluster boundary, we want the style run with it's
; direction = the line direction (LD).
; ***** d(r) = ld? *****
bsr FindStyleRun ; find other boundary run with d(r) = ld; d1 = r
bra.s @TakeRightBranch ; True: d(r) = ld
@InMiddle
; firmly in the middle. Test the line direction to determine the branch to take <17Jan89smb>
; ***** d(r) = ld? *****
bsr TestRunDirection ; does the direction of the run = line direction?
bne.s @TakeRightBranch ; True: d(r) = ld
; d(r) <> ld
; ***** c <> f[r,e] - charDelta? ***** are we one away from a style boundary?
move.w d1,-(sp)
move.b d4,d1 ; end
move.w d6,d0 ; save d6
bsr GetStyleEnd ; returns style start or end in d6
move.w (sp)+,d1
; must adjust for double-byte characters <2Sept89smb>
movem.l a0/d0-d3,-(sp) ; save <2Sept89smb>
move.w d5,d3 ; <2Sept89smb>
neg.w d3 ; <2Sept89smb>
; f[r,e] - charDelta (where the delta may be -2/2 rather than -1/1)
Bsr DoubleByte ; <2Sept89smb>
movem.l (sp)+,a0/d0-d3 ; <2Sept89smb>
exg d6,d0 ; want original char offset in d6
;;<2Sept89smb> sub.w d5,d0 ; character delta
cmp.w d0,d6
;------------------------------------------------------------------------------------
; must pin to line end to get correct offset, so to truly be done: <22Nov89smb>
; c <> l[e] - charDelta
beq.s @TstFmtIndeces ; <22Nov89smb>
; if e = 0, then l[e] = lineStart
; if e = 1, then l[e] = lineEnd
move.w 2(a2),d0 ; assume e=1 so use lineEnd ; <22Nov89smb>
cmpi.b #0,d4 ; end ; <22Nov89smb>
beq.s @IsLineStart ; <22Nov89smb>
bra.s @SubDelta ; <22Nov89smb>
@IsLineStart
move.w (a2),d0 ; <22Nov89smb>
@SubDelta
sub.w d5,d0 ; - charDelta <22Nov89smb>
cmp.w d6,d0 ; <22Nov89smb>
bne @CAddDelta ; done
;-----------------------------------------------------------------------------------
@TstFmtIndeces
; ***** r = m[q]? *****
; in the leftmost or rightmost format? test format indeces
move.w d1,d0 ; save r(n)
move.b d2,d1 ; q
bsr SetRun ; returns m[q] in d1.w (0/n)
cmp.w d0,d1
beq.s @CUseLineSt ; yep, r = m[q]: c = l[s]
; ***** r1 = r + fmtDelta *****
add.w d7,d0 ; format delta
move.w d0,d1 ; want r1 in d1
; ***** d(r1) = ld? *****
@NewFmtIndex
bsr TestRunDirection ; does the direction of the run = line direction?
beq.s @CAddDelta ; False: d(r1) <> ld ; c = c + CharDelta ; True: d(r1) = ld
; ***** c = f[r1,e] *****
move.b d4,d1 ; end
bsr GetStyleEnd ; returns new char offset in d6
bra.s @done
@TakeRightBranch
; (either on a boundary or firmly in the middle) AND d(r) = ld
; ***** c <> f[r,s]? *****
tst.b d3 ; start
bne.s @EndOffset ; s = 1
; c <> f[r,0]? => start offset for format run r
cmp.w startChar(a0),d6
bne.s @CSubDelta
bra.s @TestFmtArrayEnds
@EndOffset
; c <> f[r,1]? => end offset for format run r
bsr FixFormatEnd ; <17Jan89smb> if last format run, must decrement
cmp.w d0,d6
bne.s @CSubDelta
@TestFmtArrayEnds
; ***** r = m[q]? *****
; in the leftmost or rightmost format? test format indeces
move.w d1,d0 ; save r(n)
move.b d2,d1 ; q
bsr.s SetRun ; returns m[q] in d1.w (0/n)
cmp.w d0,d1
beq.s @done ; yep, r = m[q]: c = c
; ***** r1 = r + fmtDelta *****
add.w d7,d0 ; format delta
move.w d0,d1 ; want r1 in d1
; ***** d(r1) = ld? *****
bsr.s TestRunDirection ; does the direction of the run = line direction?
bne.s @CSubDelta ; True: equal
@OneCharacterTest
; no, style run direction <> line direction
; ***** f[r1,1] - f[r1,0] <> 1? *****
; test if there is only one character in the run.
; move.w stStartSize(a0),d0 ; <17Jan89smb>
bsr FixFormatEnd ; <17Jan89smb> if last format run, must decrement
sub.w startChar(a0),d0
cmpi.w #1,d0
bhi.s @CUseStartDelta ; c = f[r1,s] + charDelta <26June89smb> made unsigned
; ***** r1 = m[q]? *****
; in the leftmost or rightmost format? test format indeces
move.w d1,d0 ; save r(n)
move.b d2,d1 ; q
bsr.s SetRun ; returns m[q] in d1.w (0/n)
cmp.w d0,d1
beq.s @CUseStart ; terminator is direction test
; ***** r2 = r1 + fmtDelta *****
add.w d7,d0 ; format delta
move.w d0,d1 ; want r1 in d1
; ***** d(r2) = ld? *****
bsr.s TestRunDirection ; does the direction of the run = line direction?
beq.s @CUseStartDelta ; d(r2) <> ld: c = f[r1,s] + charDelta
@CUseStart
; ***** c = f[r1,s] ******
move.b d3,d1 ; start
bsr GetStyleEnd ; returns new char offset in d6
bra.s @done
@CUseStartDelta
;***** c = f[r1,s] + charDelta *****
move.b d3,d1 ; start
bsr.s GetStyleEnd ; returns new char offset in d6
bra.s @CAddDelta
@CUseLineSt
; ***** c = l[s] *****
; sf teLftCaret(A3) ; set so will go to previous line in DoCaret
move.b d3,d1 ; start
tst.b d1
bne.s @UseLineEnd
; c = l[0] = lineStart
move.w (a2),d6
bra.s @done
@UseLineEnd
; c = l[1] = lineEnd
move.w 2(a2),d6
bra.s @done
;;@CSubDelta
;;<2Sept89smb> sub.w d5,d6 ; c = c-charDelta(a6)
;;<2Sept89smb> bra.s @done
;;@CAddDelta
;;<2Sept89smb> add.w d5,d6 ; c = c+charDelta(a6)
; if double-byte character fix the offset posn.<2Sept89smb>
@CSubDelta
neg.w d5 ; <2Sept89smb>
@CAddDelta
move.w d5,d3 ; DoubleByte wants charDelta here <2Sept89smb>
Bsr DoubleByte ; <2Sept89smb>
@done
movem.l (sp)+,CursorMoveRegs
unlk a6
rts
endWith
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TestLineEnds();
; Test whether the character offset is the lineStart or lineEnd.
; Entry
; d0.b = start or end
; a2 = line containing character offset (d6)
; Exit
; d0.b = T/F
; condition codes set accordingly
;----------------------------------------------------------------------
TestLineEnds
; ***** test if c = l[s] or c = l[e] *****
cmpi.b #0,d0 ; l[0] = lineStart; l[1] = lineEnd
bne.s @testEnd
; test lineStart now
cmp.w (a2),d6
bne.s @done
st d0
bra.s @done
@testEnd
clr.b d0
; test lineEnd now
cmp.w 2(a2),d6
bne.s @done
st d0 ; c = c. done.
@done
tst.b d0 ; <6Mar89smb>
rts
;----------------------------------------------------------------------
;
; PROCEDURE SetRun();
; Set the format run index from the first or last format on the
; line.
; Entry
; d1.b = format index boundary (0 = leftmost, 1 = rightmost)
; Exit
; d1.w = 0 or n, where n = number of runs
;----------------------------------------------------------------------
SetRun
; r = m[d1]
tst.b d1
bne.s @RightMost
; r = m[0] = 0 = first (leftmost) format
moveq #0,d1 ; r1 = 0
bra.s @done
@RightMost
; r = m[1] = n = last (rightmost) format
move.w numberOfRuns(a6),d1 ; r1 = n
subq.w #1,d1
@done
rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TestRunDirection();
; Determine if the direction of the style run is equal to the
; direction of the line.
; Entry
; d1 = format index
; Exit
; d0.b = T/F
; condition codes set accordingly
;----------------------------------------------------------------------
TestRunDirection
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vTestRunDirection(a1),a1
jmp (a1)
xTestRunDirection
; ***** d(r) = ld? *****
movem.w d1/d2,-(sp)
move.w d1,fmtOrderingIndex(a6) ; d1 = r
bsr GetNextDisplayStyle ; r is index into FmtOrderingArray
; does the direction of this style run = line direction?
clr.w d0 ; result register
bsr GetDirection
cmp.b TESysJust,d1
bne.s @done ; not equal
st d0 ; T
@done
movem.w (sp)+,d1/d2 ; restore
tst.b d0 ; <6Mar89smb>
rts
;----------------------------------------------------------------------
;
; PROCEDURE GetStyleEnd();
; Set the new character offset as the format's start or end
; offset, depending on value in d0.
;
; Entry
; d1 = indicator for start or end position of format run
; a0 = ptr to current style run
; Exit
; d6 = f[r1,d1]
; d0 preserved
;----------------------------------------------------------------------
GetStyleEnd
move.w d0,-(sp) ; <17Jan89smb>
tst.b d1
bne.s @UseEnd
; f[r1,0] = start offset for format run at format index r1.
move.w startChar(a0),d6
; must pin style run to lineStart! <26Nov89smb>
cmp.w (a2),d6
bhs.s @done ; style start on this line <26Nov89smb>
move.w (a2),d6 ; use lineStart <26Nov89smb>
bra.s @done
@UseEnd
; f[r1,1] = end offset for format run at format index r1.
; move.w stStartSize(a0),d6 ; new character offset
bsr.s FixFormatEnd ; <17Jan89smb> if last format run, must decrement
move.w d0,d6 ; <17Jan89smb>
; must pin style run to line end if it breaks across the line! <26Nov89smb>
cmp.w 2(a2),d6 ; <26Nov89smb>
bls.s @done ; <26Nov89smb>
move.w 2(a2),d6 ; <26Nov89smb>
@done
move.w (sp)+,d0 ; restore <17Jan89smb>
rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE FixFormatEnd()
; <17Jan89smb>
; If in the last format run in the record want the real end
; of the run, which is style end - 1.
;
; Input:
; a0 = pointer to style run
; Output:
; d0 = correct end to use
;----------------------------------------------------------------------
FixFormatEnd
move.w stStartSize(a0),d0 ; check for last format run in record
cmp.w teLength(a3),d0
bls.s @done ; not in last format run so use style end <26June89smb> made unsigned
move.w teLength(a3),d0 ; in last format: use real end of run
@done
rts
;----------------------------------------------------------------------
;
; PROCEDURE FindStyleRun();
; <17Jan89smb>
; Find r s.t. f[r,0] <= c <= f[r,1]
;
; Input
; d6 = character offset
; Output
; a0 = pointer to style run containing d6
; d1 = r = fmtOrderingIndex(a6) - 1
;----------------------------------------------------------------------
FindStyleRun
with CursorFrame,TEFormatOrder
@RunLoop
bsr GetNextDisplayStyle
move.w fmtOrderingIndex(a6),d1
addq #1,fmtOrderingIndex(a6) ; incr the style run counter
cmp.w startChar(a0),d6
bhi.s @CheckUpperBound ; in middle? <26June89smb> made unsigned
beq.s @done
bra.s @RunLoop
@CheckUpperBound
bsr.s FixFormatEnd ; <17Jan89smb> if last format run, must decrement
cmp.w d0,d6 ; <17Jan89smb>
bhi.s @RunLoop ; <26June89smb> made unsigned
@done
rts
endwith
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE BufferChar();
; Test if inputing a double-byte character; if so, buffer the first byte,
; get the next byte, and then insert as a double-byte character
;
; On input,
; A2 points to word containing character (char in lower half)
; D6 points to character to insert (differs from A2 by +1)
; D5 contains the length of the character
; If processing a double-byte char, TwoByteCharBuffer in TEDispatchRec
; may contain the high byte of the character.
; On output,
; A2 unchanged
; If processing a double-byte character,
; - and have the first byte, D5 and D6 unchanged
; - if the second byte,
; D6 - points to the address of emBufferHandle
; D5 - set to 2, length of character.
; Condition codes set for test upon return.
;
; A0, D0 used as scratch.
;
; ** Created 3May88 by SMB **
;
;----------------------------------------------------------------------
BufferChar
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vBufferChar(a0),a0
jmp (a0)
xBufferChar
;----------------------------------------------------------------------
; now buffering a double-byte character in the newTEFlags space off the dispatch record. <1/9/90smb> move.l teDispatchH(a3),a0
move.l teDispatchH(a3),a0
move.l (a0),a0
lea TwoByteCharBuffer(a0),a0 ; move into reg for modulo 32 bit ops
tst.b (a0) ; test for existance of first byte
beq.s Empty
; have 2nd byte now - paste!
move.b 1(a2),1(a0) ; 2nd byte of double byte char
move.l a0,d6 ; pointer to 2byte character (f. PasteGuts)
add.w #1,d5 ; length = 2 bytes (f. PasteGuts), sets cc for rts
bra.s GoPaste
Empty ; possible first byte of 2 byte char
move.b 1(a2),(a0) ; buffer character; 2 byte?
tst.w teSize(A3) ; check style flag
bpl.S @DontSet ; don't set style
move.w teSelStart(a3),d0 ; pass current position
beq.s @1 ; skip test if zero
sub.w #1,d0 ; backup one to get previous style
@1
; On a Kanji script system when the styled teRec is created, the current grafport's font is
; the font in the initial style run of 0 characters. If it's created with a Roman
; font and then the keyboard is switched to Japanese to enter Kanji, via the input window
; (different unstyled teRec), the font for the 0th posn is still Roman, rather than Kanji,
; when it's used here. Hence must set the grafport via the SetFont2Keyboard code. <2Sept89smb>
bsr.s SetFont2Keyboard ; <2Sept89smb>
@DontSet
; now test with charbyte
clr.w -(sp) ; room for return
move.l d6,-(sp) ; pointer to character
move.w #0,-(sp) ; offset in buffer
_CharByte
tst.w (sp)+ ; high byte of character?
GoPaste
rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE DoubleByte();
; on input,
; d3 contains a value (1, -1) that represents the incremental
; direction to move
; d6 current position in selection range (teSelStart or teSelEnd)
;
; ** Created 2May88 by SMB **
;
;----------------------------------------------------------------------
DoubleByte
; check for double-byte characters and fix starting point. <27June88smb>
; find the font!
add.w d3,d6 ; fix position
tst.w teSize(A3) ; check style flag
bpl.S @DontSet ; don't set style
move.w d6,d0 ; pass current position
bsr GetCurStyle ; current style ptr in a0
bsr SetStyle ; set grafport style from current
@DontSet
; now test with charbyte
clr.w -(sp) ; room for return
move.l teTextH(a3),a0 ; get handle
move.l (a0),-(sp) ; pointer to start of text
move.w d6,-(sp) ; offset in text
_CharByte
tst.w (sp)+ ; middle of character?
ble.s @Done ; no, continue
add.w d3,d6 ; fix position
@Done
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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 from selStart+1 -> selEnd
@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
;formFeed
;----------------------------------------------------------------------
;
; SetFont2Keyboard
;
; <5Sept89smb>
;
; When get a key and keyboard is different from font @ teSelStart
; change the font to match the keyboard. Will never come here
; for an unstyled teRecord.
;
; Entry:
; d0 = teSelStart (or one posn before it)
; Uses:
; d0,d1,a0,a1. Preserves d4,a2
;----------------------------------------------------------------------
SetFont2Keyboard
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vSetFont2Keyboard(a0),a0
jmp (a0)
xSetFont2Keyboard
bsr GetCurStyle
; if only 1 script installed none of this is necessary
move.l ExpandMem,a1 ; <1Feb89smb>
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a1)
beq @Done ; only one script => keyboard set just fine!
movem.l d4/a2,-(sp) ; save
; get the keyboard script
move.l a0,a2 ; save style ptr
clr.l -(sp)
move.w #smKeyScript,-(sp) ; verb
_GetEnvirons
move.l (sp)+,d4 ; actually only a word
;---------------------------------------------------------------------------------
; If have an unsynchronized font & keyboard, and the KeyScript is not Roman, then synchronize
; the font and keyboard. <3Dec89smb>
move.l ExpandMem,a0
tst.b ExpandMemRec.emUnsynchedFlag(a0)
beq.s @TstNullStyle ; bra if synched up
; we are unsynchronized but are the keyScripts different?
sf ExpandMemRec.emUnsynchedFlag(a0) ; assume will synch up
cmp.w #smRoman,d4 ; if unsynchronized, the keyScript was Roman
bne.s @TstNullStyle ; bra if want to synch up ?
st ExpandMemRec.emUnsynchedFlag(a0) ; don't synch up
move.w styleIndex(a2),d0 ; get index to styleRec
bsr GetStyle ; get the styleRec in a0
move.l a0,-(sp) ; temp save
move.l a2,a0 ; restore current style ptr
bsr SetStyle ; set the grafport; preserves a0
move.l (sp)+,a0 ; restore styleRec
move.w stFont(a0),d0 ; want current font here when branch!
bra.s @SetFont ; bra if equ: want to stay unsynched
; the new keyScript is non-Roman and we're currently unsynchronized so synch up
@TstNullStyle
;---------------------------------------------------------------------------------
IF NOT hasBufferingFix THEN ; <18>
; before synchronizing dump the text buffer: could change the keyboard in the middle of buffering <1/26/90smb>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFTextBuffering,d0
beq.s @noBuffer
bsr DumpBuffer ; dump text from buffer
@noBuffer
ENDIF ; <18>
; if a null style exists and it's font corresponds to the keyScript, use it!
bsr AnyNullStyle ; returns a0 pointing to the null scrap record; cc's set
beq.s @styleLoop ; nope
lea scrpStyleTab(a0),a0 ; point to start of table
; must test if font is of the same script before using it
move.l a0,-(sp) ; save scrpStyleTab
sub.w #2,sp ; allocate return, 1 int
move.w scrpFont(a0),-(sp) ; scrpFont
_Font2Script ; get script from font
move.w (sp)+,d1 ; fontScript
move.l (sp)+,a0 ; restore scrpStyleTab
move.w scrpFont(a0),d0 ; want current font here when branch!
cmp.w d1,d4 ; is the scrpFont's script = the keyscript?
beq.s @SetFont ; already rsrved but must write to grafport
IF hasBufferingFix THEN ; <18>
; before synchronizing dump the text buffer: could change the keyboard in the middle of buffering <1/26/90smb>
; Dump here rather than inside the styleLoop below and after we are sure that things aren't synched.<18>
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d0 ; move into reg for modulo 32 bit ops
btst #teFTextBuffering,d0
beq.s @noBuffer
bsr DumpBuffer ; dump text from buffer
@noBuffer
ENDIF ; <18>
; no null style exists or bad font
; d4.b = the keyScript
; a2.l = the current style ptr.
; Test if the current font is the correct script If not, use the keyScript to determine
; a font to use. Will find the font by looking back in the styleRun array until we find
; a font whose script corresponds to the keyScript. If none exist, we'll use the script
; system's default font.
@styleLoop
move.w styleIndex(a2),d0 ; get index to styleRec
bsr GetStyle ; get the styleRec in a0
move.l a0,-(sp) ; temp save
; set the grafport now since in the case of a selection SetRsrved does nothing (must set for BufferChar).
move.l a2,a0 ; restore a0
bsr SetStyle ; preserves a0
sub.w #2,sp ; allocate return, 1 int
_FontScript ; get script from font in grafport
move.w (sp)+,d1 ; fontScript
move.l (sp)+,a0 ; restore styleRec
move.w stFont(a0),d0 ; want current font here when branch!
; test if the keyboard script is the same as the fontScript
cmp.w d1,d4 ; is the font's script = the keyscript?
beq.s @SetFont ; yep, use it.
cmpi.w #0,startChar(a2) ; are we at the start of the styleRun array yet?
beq.s @UseKbdScript ; yes.
subq #stStartSize,a2 ; no, next!
bra.s @styleLoop
@UseKbdScript
; no more styles to check, use script system's application font
clr.l -(sp) ; allocate return
move.w d4,-(sp) ; script
;; move.w #smScriptSysFond,-(sp) ; verb
move.w #smScriptAppFond,-(sp) ; verb: use application font <3Dec89smb>
_GetScript
move.l (sp)+,d0 ; font is only a word
@SetFont
; are we replacing a selection? <6Sept89smb>
move.w teSelStart(a3),d1 ; get selection start
cmp.w teSelEnd(a3),d1 ; same as selEnd?
beq.s @notSelection
; is a selection so delete selection and then set
move.l d0,d4 ; save the font
move.l a4,-(sp) ; pass the handle
_TEDelete
move.l d4,d0 ; restore the font and set it!
@notSelection
; load new font as in textStyle.tsFont
; d0 = font to use
move.l ExpandMem,a0 ; textStylePtr: actually only font attribute
move.w d0,ExpandMemRec.emNewFont(a0)
move.l a0,a2
lea ExpandMemRec.emNewStyle(a2),a2
lea ExpandMemRec.emNewFont(a0),a0
; redraw flag and mode already set at init time above
move.l a0,2(a2) ; only stuffed the font: need address of emNewFont
bsr SetRsrved ; call this routine, which TESetStyle calls
movem.l (sp)+,d4/a2
@Done
Rts
;formFeed
;----------------------------------------------------------------------
;
; ClickKeyboard2Font
;
; <3Dec89smb>
;
; When click in Roman text (whether as an insertion point or selection),
; in a non-Roman font, set the keyboard to Roman. This is the only
; time we will allow an unsynchronized font and keyboard. Used by TEClick
; and TESetSelect since for hit-down or cursor movement.
; This is only used for styled text.
;
; ENTRY
; The font must have been set in the grafport upon entry
; d0 = the current char offset or teSelStart
; USES
; a1,d0-d2
; preserves a0/d3/d4
;----------------------------------------------------------------------
ClickKeyboard2Font
; if only 1 script installed none of this is necessary
movem.l a0/a2/d3/d4,-(sp) ; save style ptr <34> added a2 for text ptr
move.l ExpandMem,a1 ; <1Feb89smb>
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a1)
beq @done ; only one script => keyboard set just fine!
move.w d0,d3 ; char offset to use for synching <3Dec89smb>
; get the script (the font must have been set in the grafport already)
sub.w #2,sp ; allocate return, 1 int
_FontScript ; get script from font in grafport
;---------------------------------------------------------------------
; Will now allow a Roman keyboard and a non-Roman font for hit-down; KanjiTalk wants
; to be able to input Roman text from a Kanji font <3Dec89smb>
; if we're in single-byte Roman text, and the font is non-Roman then
; want keyboard to be Roman <3Dec89smb>
move.l ExpandMem,a0 ; initialize to false <3Dec89smb>
sf ExpandMemRec.emUnsynchedFlag(a0) ; <3Dec89smb>
; if the font script = Roman then synch keyboard to the font
move.w (sp)+,d4 ; font script
beq.s @UseFont
; Always synchronize the keyboard & font unless a double-byte script. <34>
subq #4,sp ; <34>
move.w d4,-(sp) ; <34>
move.w #smScriptRedraw,-(sp) ; <34>
_GetScript ; <34>
move.l (sp)+,d0 ; <34>
tst.b d0 ; result is a byte <34>
ble @UseFont ; 0 = single byte LR script, -1 = RL script, 1 = double-byte script <34>
; If we're not in single-byte Roman text then synch keyboard to the font
; now test with CharByte to see if we're in Roman text
subq #2,sp ; room for return
move.l teTextH(a3),a2 ; get handle
move.l (a2),a2 ; save text ptr to re-use <34>
move.l a2,-(sp) ; pointer to start of text <34>
move.w d3,-(sp) ; offset in text
_CharByte
tst.w (sp)+ ; high byte of character?
bne.s @UseFont ; if not single byte text, synch to font script
; Is a single byte characterÉ
; Is this Roman text?
subq #2,sp ; room for return
move.l a2,-(sp) ; pointer to start of text
move.w d3,-(sp) ; offset in text
_CharType
move.w (sp)+,d0 ; now let's see what "type" of char we have!
; Mask off what interested in: the Type ($000F) and the Direction ($2000)
; Want a char whose Direction is LR (smCharLeft, $0000) and whose Type is Roman letter
; which can be smCharAscii (1) or smCharEuro (7). smCharPunct (0) should not synch to Roman.
and.w #smcTypeMask+smcRightMask,d0
;; beq.s @UseFont ; smCharPunct = 0
cmp.w #smCharAscii,d0
beq.s @Set2Roman
cmp.w #smCharEuro,d0 ; not really necc f. 2-byte scriptsÉ <34>
bne.s @UseFont ; otherwise, must use the font script
@Set2Roman
; want the keyboard to be Roman rather than synchronized to the font script <3Dec89smb>
move.w #smRoman,d4
move.l ExpandMem,a0 ; indicate that we have an anamoly now! <3Dec89smb>
st ExpandMemRec.emUnsynchedFlag(a0) ; <3Dec89smb>
@UseFont
move.w d4,-(sp)
;---------------------------------------------------------------------
; change the keyboard to match the current selection's script.
IF forLocalizability THEN ; <31f-YDS-8/27/91>
Move.w (sp), d0 ; script param on the stack from FontScript call !!!
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0 ;
move.b d0, lastScript(a0) ; push script numberused to highligt (d0) to lastScript
ENDIF
_KeyScript ; script param on the stack from FontScript call
@done
movem.l (sp)+,a0/a2/d3/d4 ; restore style ptr <34> added a2
Rts
;formFeed
;----------------------------------------------------------------------
;
; SetKeyboard2Font
;
; <10Nov88smb>
;
; When click in text (whether as an insertion point or selection),
; synch keyboard to font. Will never come here for an
; unstyled teRecord. <10Nov88smb>
;
; ENTRY
; The font must have been set in the grafport upon entry
; USES
; a1,d0-d2
; preserves a0
;----------------------------------------------------------------------
SetKeyboard2Font
move.l ExpandMem,a1 ; <28June89smb>
move.l ExpandMemRec.vSetKeyboard2Font(a1),a1
jmp (a1)
xSetKeyboard2Font
; if only 1 script installed none of this is necessary
move.l a0,-(sp) ; save style ptr
move.l ExpandMem,a1 ; <1Feb89smb>
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a1)
beq.s @done ; only one script => keyboard set just fine!
; turn off the flag set when TE creates an unsynchronized font & keyboard situation <3Dec89smb>
sf ExpandMemRec.emUnsynchedFlag(a1) ; <3Dec89smb>
; get the script (the font must have been set in the grafport already)
sub.w #2,sp ; allocate return, 1 int
_FontScript ; get script from font in grafport
; change the keyboard to match the current selection's script.
IF forLocalizability THEN ; <31f-YDS-8/27/91>
Move.w (sp), d0 ; script param on the stack from FontScript call !!!
move.l teDispatchH(a3),a0 ; get teDispatchH addres
move.l (a0),a0 ;
move.b d0, lastScript(a0) ; push script numberused to highligt (d0) to lastScript
ENDIF
_KeyScript ; script param on the stack from FontScript call
@done
move.l (sp)+,a0 ; restore style ptr
Rts
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TESetJust( just: INTEGER; h: TEHandle );
;
; Sets the justify mode. DOESN'T redraw. Lovely code...
;
;----------------------------------------------------------------------
;TESetAlignment ; comment out for now <45>
TESetJust
Bsr.w StdEntry
Move (A2),teJust(A3) ; set the style
Bra.w 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
; get vertical parameter
Move (A2),D0 ; get dV
Bpl.S @PinTop ; 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 #returnChar,-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
@PinTop
; scrolling down
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
Sub d0,2(a2) ; bug found in MacDTS <12/19/88smb>
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
;formFeed
;----------------------------------------------------------------------
;
; 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 #teFAutoScr,D0
Beq.s @Exit ; if not, must skip
Bsr SelSort ; sort selection
Move teSelStart(A3),D3 ; dispStart:=selStart
Move D3,D4 ; dispEnd:=same
MoveQ #teCaret,D7 ; does nothing except moves pen
Bsr DoText ; position for the caret
; test for split caret: if exists, want the high caret in view. <21Dec88smb>
move.l ExpandMem,a0 ; <1Feb89smb>
cmpi.w #$FFFF,ExpandMemRec.emTwoCursorsFlag(a0) ; <21Dec88smb>
bne.s @HighCaretRect ; <21Dec88smb>
; use rect stored in emCursor2Rect: this is the High caret location. <21Dec88smb>
lea ExpandMemRec.emCursor2Rect(a0),a0 ; top, left, bottom, right <12July89smb>
move.l (a0),d7 ; <21Dec88smb>
bra.s @Continue ; <21Dec88smb>
@HighCaretRect
Move.L teSelRect+topLeft(A3),D7 ; save penloc in D7
@Continue
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 @Exit ; 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> **
@Exit
Rts ; adios
;formFeed
;----------------------------------------------------------------------
;
; 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 #teFAutoScr,D0 ; <PMAB381/RWW020488>
Bra.S @1
@0
;; BClr #tefAutoPos,teFlags(A3) ; allow scrolling
BClr #teFAutoScr,D0
@1
Move.L D0,newTEFlags(A0)
Bra epilog6
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEFeatureFlag( verb: word; action: word; hTe: TEHandle ):word;
; <30May89smb>
;
; Sets the verb field <selector> bit according to the action,
; but preserve the old value as the result.
;
; Verb or bit definitions for newTEFlags
; teFAutoScr EQU 0 ; (00000001b)
; teFTextBuffering EQU 1 ; (00000010b)
; teFOutlineHilite EQU 2 ; (00000100b)
; teFInlineInput EQU 3 ; (00001000b)
; teFUseTextServices EQU 4 ; (00010000b)
;
; Action for the new "bit (un)set" interface
; TEBitClear equ 0
; TEBitSet equ 1 ; set the selector bit.
; TEBitTest equ -1 ; no change; just tell the present value
;
;----------------------------------------------------------------------
iTEFeatureFlag
moveq #0,d0
moveq #0,d1
move.w (a2)+,d0 ; action
move.w (a2)+,d1 ; verb bit (which feature to affect)
move.l teDispatchH(a3),a0
move.l (a0),a0
move.l newTEFlags(a0),d2 ; move into reg for modulo 32 bit ops <15Sept89smb>
clr.w (a2) ; <6Oct89smb> necessary so the return result of 'clear' is correct.
btst d1,d2 ; <15Sept89smb>
sne (a2) ; save result
tst.w d0 ; whatcha wanna do?
blt.s @done ; action = testFlag; result already on stack
beq.s @clear
bset d1,d2 ; action = setFlag <15Sept89smb>
bra.s @done
@clear
bclr d1,d2 ; action = clearFlag <15Sept89smb>
@done
move.l d2,newTEFlags(a0) ; <15Sept89smb>
tst.b (a2) ; <13Sept89smb>
beq.s @OK
move.w #1,(a2)
@OK
moveq #10,d0 ; # of bytes on stack (include selector!)
bra stdExit2
;formFeed
;----------------------------------------------------------------------
;
; 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 #teFAutoScr,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 noAuto ; no scroll if line doesn't exist ** <C207/13oct86/MBK> ** <4>
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
noAuto ; <4>
clr.l teClikTime(a3) ; clear it out because we're not scrolling <4>
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
lea -10(sp), sp ; reserve space for call to ScrollDelay <4>
move.w #1,-(sp) ; itemsVisible = smallest possible (1) <4>
move d4,-(sp) ; pass dh
move d1,-(sp) ; pass dv
movea.l a3, a0 ; Grab Text Edit pointer from A3 <sm9>
_RecoverHandle ; Recover the tehandle <sm9>
move.l a0,-(sp) ; slam tehandle onto stack <sm9>
subq.l #4,sp ; <4>
_TickCount ; Get a time stamp. <4>
move.l (sp)+,d1 ; Copy it into D1. <4>
move.l d1,10(sp) ; And put it on the stack for ScrollDelay. <4>
; Note: teClikTime is a state variable in the TERecord which is used by TEClick.
; Fortunately, TEClick does not use it at all within its body; it only checks its
; value on entry and sets it on exit. This code relies on it also being set on
; entry, just after it has been tested. Of course, this restricts its use to
; click procs, but that's okay.
move.l teClikTime(a3),d0 ; See if it's a new scroll <4>
bne.s @gotTime ; Skip if not <4>
move.l d1,teClikTime(a3) ; Otherwise, put in a new stamp <4>
move.l d1,d0 ; in D0 too <4>
@gotTime
move.l d0,14(sp) ; D0 is startTicks for ScrollDelay <4>
_TEPinScroll ;_TEPinScroll ** <C381/6nov86/MBK> **
_ScrollDelay ; <4>
AddQ.L #2,SP ; Toss the result <4>
Bra.S doneAuto ; <C971/RWW102887>NO
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
; a0: preserved
;----------------------------------------------------------------------
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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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 TESetStyle. 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 TESetStyle.
;
; 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
; set the direction of the font in the high bit of the high-order byte <30May89smb>
move.l a0,-(sp)
move.w tsFont(a0),d1
lea scrpFace+1(a1),a0
Bsr SetDirection
move.l (sp)+,a0
@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
bclr #7,txFace+1(a0) ; want direction in scrp but not grafport <30May89smb>
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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TESetStyle( 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 @DontSet ; if not, sorry, can't set it
Bsr SetRsrved ; save the style in the grafport
; mode may be an additive combination so must test the font bit <3Dec89smb>
move.w 6(a2),d0 ; <3Dec89smb>
btst #fontBit,d0 ; is mode = doFont? <3Dec89smb>
beq.s @KeybdOK ; <3Dec89smb>
;; cmpi.w #doFont,6(a2) ; is mode = doFont? <12July89smb>
;; bne.s @KeybdOK ; <12July89smb>
bsr SetKeyboard2Font ; synch keyboard to new font <10Nov88smb>
@KeybdOK
; ** <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 @DontSet
@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
@DontSet
MoveQ #14,D0
Bra StdExit2
;formFeed
;----------------------------------------------------------------------
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.
; <31j-YDS-8/27/91>
; if/when will add this should define those:
; doAll4 EQU $7F
; doFontSmart EQU $41
; IF forLocalizability THEN ; <31j-YDS-8/27/91> - minor, has another one marked>
; And.W #doAll4,D7 ; only lower 7 bits make sense <C971/RWW102987>
; ELSE
And.W #doAll3,D7 ; only lower 6 bits make sense <C971/RWW102987>
; ENDIF
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
;formFeed
;----------------------------------------------------------------------
StyleGuts
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vStyleGuts(a0),a0
jmp (a0)
xStyleGuts
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
_BlockMoveData ; 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
; <31j-YDS-8/27/91>
;; here we will add a test to let you force a change that we do not allow, we still check it so
;; all this code will be hidden after debugging after we will decide what to do !!!!
;
; IF forLocalizability THEN ; <31j-YDS-8/27/91> Don't let me change fonts not from the same script
; BTst #doFontSmart,D7 ; check for matching script ?
; Beq.S @ignoreScript ; no
;
;
; MoveM.L D0-D2/A0-A1,-(SP) ; save registers, we call the toolbox
; Clr.W -(SP) ; space for return value of function
; Move.W stFont(A4),-(SP) ; move font to stack
; _Font2Script ; get the font script
; Clr.W -(SP) ; space for return value of function
; Move.W D4,-(SP) ; move font to stack
; _Font2Script ; get the font script
; Move.W (SP)+, D0 ; into d0
; Move.W (SP)+, D1 ; into d1
; Cmp.W D0,D1 ; is it the same script ?
; MoveM.L (SP)+, D0-D2/A0-A1 ; restore registers. (won't change cc)
; Bne.S @3 ; no , don't awitch.
; ENDIF
;
;@ignoreScript
Move.W D4,stFont(A4) ; else, put in temp rec
; set the direction of the font in the high bit of the high-order byte <30May89smb>
move.l a0,-(sp)
move.w d4,d1
lea stFace+1(a4),a0 ; store direction here
bsr SetDirection
move.l (sp)+,a0
@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
;formFeed
;----------------------------------------------------------------------
;
; 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
bclr #7,txFace+1(a1) ; clear direction <30May89smb>
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
;formFeed
;----------------------------------------------------------------------
;
; 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 GetStylScrap.
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEGetStyle( 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
clr.b -1(a1) ; clr direction <30May89smb>
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 NOT ForROM THEN ; <9Dec88smb>
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 hasCQD THEN ; <9Dec88smb>
_GetForeColor ; for Ikki
Else
Bsr GetForeColor ; for Alladin
EndIf
@1 MoveQ #20,D0
Bra StdExit2
;formFeed
;------------------------------------------------
; 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
bclr #7,txFace+1(a1) ; clr direction <30May89smb>
Move.W stSize(A0),txSize(A1) ; set size
If NOT ForROM THEN ; <9Dec88smb>
BTst #14,ROM85 ; Becks or better? <C971/RWW112487>
Bnz.S @1 ; nope <C971/RWW112487>
EndIf
If hasCQD|(NOT ForROM) THEN ; <9Dec88smb>
; 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 NOT ForROM THEN ; <9Dec88smb>
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 hasCQD THEN ; <9Dec88smb>
_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
;formFeed
;----------------------------------------------------------------------
;
; 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/d3/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 as an offset
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/d3/A2 ; restore registers ** <C381/7nov86/MBK> **
Rts ; bye
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE ConcatRuns
;
; Added 24Nov88 by SMB (taken from DrawIITE.a)
;
; ConcatRuns checks for a null style run preceding the dummy run
; at the end of the style runs, and deletes it if it finds it.
;
; Uses a0,a2,d0,d1. Preserves a2.
;
;----------------------------------------------------------------------
ConcatRuns
move.l ExpandMem,a0 ; <28June89smb>
move.l ExpandMemRec.vConcatRuns(a0),a0
jmp (a0)
xConcatRuns
tst.w teSize(a3) ; don't want to be in here if unstyled! <1Dec88smb>
bpl.s @NoRuns
; Don't allow any runs to have offset = text length
MOVE.L A2,-(SP)
MOVE.L teStylesH(A3),A0 ; handle to style info
MOVE.L (A0),A0 ; dereference
MOVE.L styleTab(A0),A2 ; handle to distinct styles
MOVE.L (A2),A2 ; dereference
MOVE.W nRuns(A0),D0 ; get # of style starts
BEQ.S @endConcat ; exit if none
SUBQ #1,D0 ; point to 1 less than end
BEQ.S @endConcat ; exit if 1 only
;; MULU #stStartSize,D0 ; * size of record
lsl.w #lnStStartSize,d0 ; replace mulu w/ shift <28June89smb>
LEA runs(A0,D0.w),A0 ; ptr to last run before dummy
MOVE.W teLength(A3),D0 ; text length
CMP.W startChar(A0),D0 ; same as run start?
BGT.S @endConcat ; okay if less
MOVEQ #0,D1
MOVE.W styleIndex(A0),D1 ; the style
MULU #stRecSize,D1 ; * size of record
SUB.W #1,stCount(A2,D1.L) ; dec count
ADDQ #1,D0 ; length + 1
MOVE.W D0,startChar(A0) ; store dummy run here
MOVE.W #$FFFF,styleIndex(A0) ; last style index
MOVE.L teStylesH(A3),A0 ; handle to style info
MOVE.L (A0),A0 ; dereference
SUB.W #1,nRuns(A0) ; store new # of style starts
@endConcat MOVE.L (SP)+,A2
@NoRuns
RTS
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE CheckMatch
;
; ** Added 7/19/86 by MBK **
;
; CheckMatch checks to see if the input style record matches
; the style being sought by TEReplaceStyle. If so, a True flag
; is returned. If the call was from TESetStyle, 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 TESetStyle, except
; in toggle mode)
; 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 TESetStyle?
Beq.S @exit ; quit with true if so
; ** <C971/RWW102987> Added code to support doToggle mode
; Specifically, A6 = -1 is used as a flag in TESetStyle
Cmp.L #-1,A6 ; ignore toggle mode, too <C971/RWW102987>
Beq.S @exit ; <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 @noMatch ; 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 @noMatch ; 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 @noMatch ; stop comparing if not
@3 BTst #clrBit,D7 ; find color?
Beq.S @exit ; must have a match if still here
Move.L tsColor(A6),D1
Cmp.L stColor(A0),D1 ; same as this style?
Bne.S @noMatch ; 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 @exit
@noMatch
MoveQ #0,D0 ; not a match
@exit Rts
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEReplaceStyle( 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
;formFeed
;----------------------------------------------------------------------
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
;formFeed
;----------------------------------------------------------------------
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION GetStylHandle( hTE: TEHandle ): TEStylHandle;
;
; ** <C94/29jul86/MBK> **
;
; Returns the style handle.
;
;----------------------------------------------------------------------
;iTEGetStyleHandle ; comment out for now <45>
;iGetStyleHandle ; comment out for now <45>
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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE SetStylHandle (hST: TEStylHandle; hTE: TEHandle);
;
; ** <C105/8aug86/MBK> **
;
; Sets the style handle.
;
;----------------------------------------------------------------------
;iTESetStyleHandle ; comment out for now <45>
;iSetStyleHandle ; comment out for now <45>
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 (NOT hasCQD)|(NOT ForROM) THEN ; <9Dec88smb>
;
; 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
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION TEGetPoint( 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 @LengthOK ; ok if less or same
;----------------------------------------------------------------------
; special case of 0 length and any offset: set the point to the DestRect's left/right edge and use
; the lineHeight + the DestRect's top. <1/8/90smb>
cmpi.w #0,teLength(a3) ; is it a 0 length record? <1/8/90smb>
bne.s @OffsetGELength ; bra if length <> 0 => offset >= length
; set up return point to be valid (or at least more correct than it was!)
lea teDestRect+8(a3),a0 ; point past destRect
lea teSelRect+8(a3),a1 ; and past stack rect
move.l -(a0),-(a1) ; copying teDestRect to teSelRect
move.l -(a0),-(a1) ; copying teDestRect to teSelRect
move top(a1),bottom(a1) ; temporarily the same
moveq #0,d0 ; current line
bsr GetHite ; height of this line returned in d1
add d1,bottom(a1) ; add line height to get bottom bound of line rect
addq #1,teSelRect+left(A3) ; indent for caret in case L just
adda.l #2,sp ; pop offset
bra.s @AssumeLeftJust
; finished w/ changes <1/8/90smb>
;----------------------------------------------------------------------
@OffsetGELength
Move.W teLength(A3),D0 ; else pin to end
Move.W D0,(SP) ; replace offset
SubQ #1,D0 ; just for GetLine
@LengthOK
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.
with TextFrame,TEFormatOrder ; <1Nov89smb>
link a6,#TextFrameSz ; for LineRect: calls FormatOrder code <1Nov89smb>
;; <1Nov89smb> Move.W saveJust(A6),-(SP) ; LineRect will write something here
Bsr LineRect ; sets up selRect from destRect and justification
;; <1Nov89smb> Move.W (SP)+,saveJust(A6) ; restore port
unlk a6 ; <1Nov89smb>
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 @DoEndOfLine ; skip CR test if not
Move.L teTextH(A3),A0
Move.L (A0),A0
Cmp.B #returnChar,-1(A0,D7) ; if last char = CR then...
Bne.S @DoEndOfLine
@AssumeLeftJust
; assume left justification
move.w teSelRect+left(a3),d0
move.w teJust(a3),d1
bne.s @DoNonLeftJust
move.w TESysJust,d1
beq.s @DoTheJustThing
;; <7Dec89smb> Cmp.W #teForceLeft,D1
;; <7Dec89smb> Beq.S @DoTheJustThing
@DoNonLeftJust
; <7Dec89smb> move test to teForceLeft to where it's useful!
cmp.w #teForceLeft,d1 ; <7Dec89smb>
beq.s @DoTheJustThing ; <7Dec89smb>
; right or center justification
move.w teDestRect+right(A3),d0 ; assume right justification
subq #1,d0
tst.w d1
bmi.s @DoTheJustThing ; branch if right
; center justification (divide width by 2)
sub.w teDestRect+left(A3),d0
asr #1,d0
add.w teDestRect+left(A3),d0
bra.s @DoTheJustThing
@DoEndOfLine
IF forLocalizability THEN ; fix for TEGetPoint Bug <31h-YDS-8/27/91>
move.l ExpandMem,a0 ; do we have more then the roman script
cmpi.b #1,ExpandMemRec.emScriptsInstalled(a0)
beq.s @romanMeas ; use MeasureIt
link a6,#TextFrameSz ; DoMeasure uses a stack frame
bsr DoMeasure ; measure with LR styles
unlk a6
bra.s @1
ENDIF
@romanMeas bsr MeasureIt ; measure with style
@1 add.w teSelRect+left(A3),d0 ; add in justification
@DoTheJustThing
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
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION GetStylScrap( 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.
;
;----------------------------------------------------------------------
;iTEGetStyleScrapHandle ; comment out for now <45>
;iGetStyleScrap ; comment out for now <45>
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>
_BlockMoveData ; 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE SetStylScrap(rangeStart, rangeEnd: LONGINT; newStyles: StScrpHandle;
; redraw: BOOLEAN; hTE: TEHandle);
; ** <C971/RWW102887> **
;
; This procedure is the logical opposite of GetStylScrap. It
; takes a handle to a style scrap record and applies it
; over the given range. SetStylScrap 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.
;
;----------------------------------------------------------------------
;iTEUseStyleScrap ; comment out for now <45>
;iSetStyleScrap ; comment out for now <45>
iSetStylScrap
Tst.W teSize(A3) ; don't do anything if not styled
Bpl @xit
; per documentation, must test for a NIL StScrpHandle handle (newStyles) <20>
tst.l 2(a2) ; is the scrap handle NIL <20>
beq @xit ; yep, don't do nuttin! <20>
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 ; TEReplaceStyle 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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TEStylInsert( 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 TEStylInsert.
; TEStylInsert is exactly the same as TEInsert if the TERec is not
; a style record, or if a NIL style handle is passed in. Otherwise,
; TEStylInsert 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.
;----------------------------------------------------------------------
;iTEStyleInsert ; comment out for now <45>
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 length & pointer params
; ** <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
; only call ConcatRuns when styles are pasted, hence moved here. Text inserted now so
; okay to call.
Bsr ConcatRuns ; <24Nov88smb> don't leave any null style runs
Sub D5,D7 ; adjust delta amount for ReCalLines
Bra.S @1 ; go recal
@0 Bsr InsGuts ; no styles to insert, only 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
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION TEGetHeight (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
;formFeed
;----------------------------------------------------------------------
;
; PROCEDURE TECustomHook(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 <2May89smb>
Add.w D0,A0 ; add in offset <2May89smb>: 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
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION TENumStyles(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
;formFeed
;----------------------------------------------------------------------
;
; FUNCTION TEContinuousStyle(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 TESetStyle. 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 TEGetStyle, 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 NOT ForROM THEN ; <9Dec88smb>
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 hasCQD THEN ; <9Dec88smb>
_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
;formFeed
;----------------------------------------------------------------------
;
; 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 TEContinuousStyle
;
;----------------------------------------------------------------------
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
;formFeed
;----------------------------------------------------------------------
;
; NewTextEditEntryPoint
;
;----------------------------------------------------------------------
NewTextEditEntryPoint
Move $20(A3), D0
Cmp $22(A3), D0
BLT.B @L1
Move.L (A2)+, -(A7)
_SetEmptyRgn
Bra.B @L3
@L1 Move.L $56(A3), -(A7)
Lea.L DT0, A0
Move.L A0, $56(A3)
_OpenRgn
Move $24(A3), -(A7)
OrI #$FF00, $24(A3)
Pea.L $10(A3)
Move.L A4, -(A7)
_TEUpdate
Move (A7)+, $24(A3)
Move.L (A2), -(A7)
_CloseRgn
SubQ #$4, A7
_NewRgn
Move.L (A7)+, D0
BEQ.B @L2
Move.L D0, -(A7)
Move.L D0, -(A7)
Move.L (A2), -(A7)
Move.L (A2), -(A7)
Move.L D0, -(A7)
Pea.L $8(A3)
_RectRgn
_SectRgn
_DisposeRgn
@L2 AddQ #$4, A2
Move.L (A7)+, $56(A3)
@L3 Clr (A2)
MoveQ.L #$A, D0
Bra StdExit2
DT0 _FrameRect
Rts
; *************************************************************************************************
; *************************************************************************************************
; *************************************************************************************************
; TextEdit end