-not a Macintosh disk-DPi`KJDBH@%/NGNP"N,L 8!"@$|Gn"`I N.@A,H<( F<B<H111.Bx<kNNF`, 8! "NH@"|J(g g`LNu"_ |a||a0@||9݁g|w|a||NH瀀 |(_@"g2<@gBA?N`Fa`||aPLNu  fBR$N"NBH@&|݁ |B$<0HN~NL@dBgg>N&|)`RNuBBBA*2h/ BBB N _"_$_"H&|݁ |B$<0NNd 0<`L$|J HA H  2I<FFI<<FFfHHFFfHHH?B@L"_2N _0H 2<@I6@o Az:<2`6@oJA~:<26" @n2BDBB(`EB@nAJEkz`z2<HAIL0.NL0.N  / p? O@ 0  0  XO _,_2_!.NBBB/ BBBN08 @ gNu@ f"_E!NH\O/ ?`@&x|N _!@"|xEz En"`CE"|xN"Ҹ< A  33"|@E E4n"`C&E"|@.N _LHNFLN*8&E@<<'CJJKK f`  f `><$CS*<FF4>BRIBC Gff&<CBSC`D GnKG45BQf` f `Ns |0< BXHQ!4 _$_"_!XOHH/8/ $ f0<? QN ! N.x $_$ g ! N.x !C !!LLyp!N\OFN  l0P߀ Aǀ`  6lo6@ 0_an*>]> j 56, l602  ۰Poo A` &ll6p@ 0?۷a?^ ꭕ 5o6, l602 8!ED91kE"0369? CoNGNOS BOOT FAILED TRY A NEWER MACHINE AND BOOT PROM _"_NN/A lNNu _.NHL$ orD?|?@?e\SFk!!QSWk:CL<HL|hH>L|4H>L|H>SWjTO>SGk\!Q`TSFk QSWk8L|H|L|H|4L|H|hL|H|LSGkQLx _O NNVH8=| f=|G* G, &N(N n"n$n 0.  S@ZeJ S@BBDBG S@gg.BC CJDg720faL`fa:` 320f8<S@`JDg  fa$` fa`  U@o$SBjt`(N&N><`JGg (Ev#$#$QNukJDg`g 3$f(N`BnLN^ _NUNPACK H>8$O&j.(j4,*8:*,BB6*2SCCn`8CL0@D@04"F K0HEY@2< Vb,g`aJaBVgbHE6SCCo`p`HE4RBCo8B@ j(0 j$L| _pN am znNu _"_$_$0H2< @`Q`BQBNNV;n *N^.NuEVINIT NVH,. ^J]g n0`4B?N. f n0`/.//. /.N6(n)FLN^ _NEAD_BLONV/ (n Jno./.?././ /.Nj nJPg`RSn`(_N^ _NEAD_SEQHNT"|E.|r |BBByBygRBf~NuLHPPNqNqpS_n.0<QLHPPNqNqpS_n|~By&JM*Np|azJGfb|a|,Mpa`JGfH|a<<AaJGf0Avtp BQvr BQH@02N\LhL"4NtB@6Kd a"JDf`02IP g a JDf`Nub SBg pxNuBDNu><Nu4< vB@bp2IPSCfSBfNuppB@(4<dBC(4< CBC(C"H4<BACSBf(CAg><NuJoNV?-,N.H|)?NN^ _TONRAP NV.HgVS@g`J.f& -`мS//<N/<NB+_`-m` . ѭ` -`o<Np`B . \J.f/-\/<N4/<N+_\-m\ -\l<N,N^ _PONGETSPACNV .мS//<N/<N-_ .=@ N^.NuINDSPARNVH.. Bg/N0Hހ m0.@I/./<N 8//<Np @n ?.Bg?<BgNLN^ _ NETMMU NVH+| d+|l+|(+||+|+|t+|(|;TV(|;T|(|.;Tz&| n!SLN^.NuETVARS NVH/Nt;| .䐼/+@ .м/м+@+|`*<(< E"D +@\&|?-|0-VS?NHnHmJNJngp+@JBBg/-BgNz+_ -Э+@XBB<0<H/BgNPN+_P+mPBG` m @I G~V GTVgd Gl|p@ @8`$ Gf|p@BT`| p@BT H< @"@=A?.??<BgNRG Gox mI|p@BT mIP|p@/-P/<N* 8LN^NuOOTINITNVH(nB BgNBgNHH,BgN0HѬ f,/, N"BgNBgNHH,BgN0HѬ f,/, NBgNrBgNjHH,BgN0HѬ f:Jf< N/, NBgN2BgN*HH,BgNb0HѬ g<NLBN,BN+_ n/BN|  _r Ё0p//-`N/-/-`N&m`:=E E0o<N0<H+@l+| -lЭd n2HҀ -Ё"-Ҁ(Bg Э/N0Hѭ -Є+@B</-BgN+_+mh -dЭh+@p -lЭp, n0HІ+@ -Э+@ -Э+@?<f/-/-?<Nb-m/ /./-N n LN^ _ NUILD_SYNVH(nBGBF. gB `P-n n0. PoB."` n0. A-H&n/+/<N  n0>+<+/, NBgN<BgN4HH-@BgNj0H(٬ JVJ_gB."`4JGW WJGV WgJFf n `H n n/B."n/BgN2  _ BNB-_JGf n Q/ n P/Nr` Q@H/ n P/NZ|B. n=h-nA-H n-P/./.p/N JGgR-mBg n/( n r Ё/ n P/ nP/ | ? Q@?N9_Jlg< N, nQ f|"LN^ _NOADSEG NVHBBg/-tBgN+_x -x"-Ҁ+At(|`p}//<Nn -Пx((|p}//<NN -Пx(?<}/-x/-t?<N&|BSLN^.NuLLOC_SCNVHAC 0BgHnNz_m+m-gBBg/-BgNP+_`+m-gBBg/<BgN, м,BgBgBHnBgHnHnBg/.N g<NACD 0BgHnN  g B-n`.BgBgBHnBgHnHnBg/.Nx g<Nf .@+@ -Э+@` B -@+@ -м@+@?</-/-?<N@ <逐.JfB` .ЇP-@JfB` .ЇP-@-g -Ї/ -Ї//./.N`/-/-BBN(|p((|t(LN^.NuOAD_DEB SYSTEM.DEBUG2 SYSTEM.DEBUGNVH nCJp"S@n2&n (nBBgHnN dgZB /, N NBgN BgN HH(BgN0H* f&.B</BgN&B /, N //NlLN^ _ NOAD_UNPNVBgBgBHn</. /.Bg/.N g<NN^ _ NOAD_LLDNVH(n 0-N|>Jg,, .* Ю(H//<N( Д-@`,.(.H//<N-_?//?<N. .P/NdLN^ _NNSTALL_NVH(n=n ~`/, N BgN p_BgN fHH(BgN 0H-@Jg .Ѭ `<N~ .fBN (BN ( GfAB0pB5pB`ACZ 0z`BgN _ .ARE EoHn?<?<HnNAC 0HnHzNg(AB0pp @AB @AB`2HnHzNPgAB0pB5pB`App| 5pgnBg?/.Hn @AHp @AHp</.NX g<NF?. @A/0 @A"0Ҽ/?<NHRGinoLLN^ _ NOADCODEkrni NVBBg/-BgN+_?<e/-/-?<NN^.NuAKESUPSNVH(m . R A T&@-kLN^ _ NINDMAINNVBg/-NF0HѭB</-BgNx+_?<g/-/-?<N\Bg/-|N 0Hѭ|B</-|BgN>+_?<{/-/-|?<N"N^.NuLLOC_OPNV A0C ArC 0AC 0/NLHnHm/NFBgHn0N g< NHnHn/NBgHnrN g<N^/NZBg/.Hn$/N;_N/./.Hm/N-UgNj/.$?-N/N@/N2 n /B/.$0-NH//NR  _ /NBNj+_N^ _PONOADSYS $ SYSTEM.UNPACK SYSTEM.OS SYSTEM.LLDN :NV,_NUvN ,+|v mv PVD@UNHmHmNHm?- -|Э//-NzNZN N]N NuN^NuOADER NVHAv(HA^&HHn?-.0-0H".Ҁ// / NrJng<NLN^.NuEAD_PAGNV0.HBH"-DҀ-A0.HBH@J@=@/.NvAv0.HЈ-@ N^ _TONIND_SENNVBH nCJp"S@n2 n BBgA/A/Nz-m2Av(H&L U.=m6B|`A^-HHAv(BE`:HnN?-.0-0H".ҀH҅///.HNhؼJnNg<NRE Eom6l^Bn So4 X/ U/0S@?A/?<$Hn/. N n gRn G0.D@@20HҌ-A n-P`/ /?A/?<$Hn/. NRFinBo$ n g< G0.D@@20HҌ-A/.HnP?<NN n/B?.vN4  _ LN^ _ ND_SEARCNVH n-h .S/0-:H/N ;@Z-n p+@V;m:\BF` AvIBBlRF Fo=mHnNBgHn?->N>H/p6/NNZBp6/A/NACp S@n0HnN^J.gHHnHnN .Wgz n/B?.N  _ `SFRGm>fBGBNJFfELN^ _PONOOKUP_ENVH.<A"G";n .;m.,?.?-.N;n0BN&Av(HJg<NH;l~:+lD;lB;l>;l@;l<;T8;l26+l.2 2f<N m8lB?,N&_+SH+kL+kPLN^.NuNITMEDINV m8lBg/.HnN2_`/.HnHnNn .gB/.N-_N^.NuPENINPUNVH(.BGBF Go<NR Av:0JEf<N8 EHl@ AvH"Ұ n n Jf<NHH " n ``RGE`LN^ _ NIND_POSNV-mV/.0-:H/N+_VJV]2-ZHV]g<N0-:H/-V/N2 .;@\ -Vg/-VHnHnN/.N"N^.NuILLBUF NV0-\m:f -VR2-:H//NNT0-\AvpRm\N^NuETBYTE NVHBgNHH<BgNH>JGl H м> G=@LN^NuETWORD NVHBgN0H//<ND,BgN0H.Jl޼ Ї-@LN^NuETLONG NVH,. 0-:m\>HǼl>JGo0-\AvA//.H/NH߮Hǜm\0-:HnJV]2-ZHV]g<N -VR/HnHnNn-nA^(H/0-:H/N*l-EJoZHn?-.0-0H".Ҁ/?././ NjJng<N~0-:H/./N(ٮ .Ѯ .ѭV`:Jo -VR2-:H//NNhJfLN^ _PONOVEMULTNVH(n0,k @nH0;N *6BN\BgHlN_`n/,N`dBgN_`XBgN9_`LBN)_`@/,/,N:`2&l.,/ ?-.0-0H", Ҁ/?,/ /NP`<NhLN^.NuRIVER_C//0/2/ AH@B@2/Ё/@" /WXNuNV// /"/N:/A" N^/WXNuNV// /"/N/@" N^/WXNuH>*jD,jD$HBJBf6B@H@g4HB04"B@H@`$&BBxԂрҁmRQJjDjDL|NuNuNuJoNu$_0 _"_J @o4$ Tg,2ABAgSBgS@2@ISA QS@kQN$_0 _"_J`!QN$_02 _`QNHBB oJ0/2/gk gRBSAn` R gSBRAk?B/oL\NuHBB oJ0/2/gk fRBSAn` R fSBRAk?B/oL\NuHr`HBA oJ"oJB@f`fQ AA/oL\NuH"o J oJv`:H"o J oJBC`&H o J"oJv`H o J"oJBCB@BA@m4`4`fQ@n C`cC"/oL\NuH0/ oC"4JBAR`$aJBBB`QQ oC"0/H#//IL._NuH oJB@BA"o JBBBlBA`$HR` fQ`RS@`?A"/oL\NuH o0/2/SA"o JBBA@m`Q/o L NuB`$_02 _ @o0 Ao*BBAm"6@SCBoSA`@"H`RCoN$_0"_ _J/ S@m*BABB@m6B$I”@`!Q`QNuKbA TK Sources 4̆V{t̆^K :a$kT.k\:)$ "#." #"##%& ! . M   4(S0   $F.1 .1m$BUILD/ASSEMB.TEXT $BUILD/COMP.TEXT gKb$BUILD/INSTALL.TEXT݂Kb-$BUILD/MAKE/ATKLIB.TEXTII$build/make/Ctk2lib.textf [f ]$BUILD/MAKE/CTKLIB.TEXTf _Kb$build/make/Ltk2lib.textKbW$BUILD/MAKE/LTKLIB.TEXTnKbY$BUILD/MAKE/TKLIB.TEXTf pY<$LIBPL/PASLIBCALL.OBJstopoutput : BOOLEAN); {open/stop output file} $FUNCTION OutputRFlag : BOOLEAN; {return true if output is redirected} $procedure DSPaslibCall (VAR ProcParam : dsProcParam); {by Workshop Shell only} implementation 3. "6F^9 SD!$ǐ^DSGSG.Lph; top+lineInfo.lineAscent); ar)} } ; ent; {Text Selections and Commands} END. (s := SELF.lineList.Scanner; (i := 0; (endLine := Min(endLine, SELF.lineList.Size); (startLine := Max(startLine, 1); (styleIndex := 1; (WHILE s.scan(lineInfo) DO ,BEGIN ,i := i+1; ,IF i < startLine THEN {nothing} ,ELSE 0BEGI{UText2} {Paragraph Classes} {changed 05/11/84 1135 Added TParagraph.Clone} {changed 04/25/84 1250 Changed FilterAndDo calls back to filtering TParaImage for Compugraphic} {changed 04/18/84 1652 Use TTextImage.firstLinePixel in DrawParaImage} {changed 04/17/84 1806 Put call to ReplTString outside of IF in ReplPara; 8Put more parameter checks in ReplTString} {changed 04/16/84 1135 Added styleSheet field to TParaFormat; use it in ChangeRefCountBy} {changed 04/16/84 1033 Put PicTextBegin, End in TParagraph.DrawLine; 8Put PicGrpBegin, End in TParaImage.RedrawLines; 8Removed picture comments from TParaImage.DrawLine} {changed 04/13/84 1739 Set paraformat.refcount = 0 in TParaFormat.Clone} {changed 04/13/84 1537 Changed calls to FilterAndDo to pass TEditPara rather than TParaImage} {changed 04/12/84 2344 Modified UpdateRuns to use new parameter list} {changed 04/11/84 1527 Call UpdateRuns after deleting characters in TParagraph.ReplPString and ReplTString} {changed 04/11/84 1454 Debug statement in Qualifies to check bug involving special characters} {changed 04/10/84 1400 Changed TEditPara.images field back to a TList and adusted references to it} {changed 04/10/84 1158 Put calls to TParaFormat.ChangeRefCountBy in TEditPara.CREATE, Free} {$IFC fRngABC} {$R+} {$ELSEC} {$R-} {$ENDC} {$IFC fSymABC} {$D+} {$ELSEC} {$D-} {$ENDC} TYPE $TScanState = (cBeforeRange, cInRange, cAfterRange); $TFakeTStyle = PACKED ARRAY[1..SIZEOF(TTypeStyle)] OF CHAR; ${$IFC LibraryVersion <= 20} $Style = TSeteface; $FontInfo = TFinfo; ${$ENDC} {$S SgTxtHot} VAR nextHighTransit: THighTransit; $nextTransitTime: LONGINT; $uvFont: ARRAY [1..14] OF TFontRecord; METHODS OF TParaFormat; {$S SgTxtIni} $FUNCTION TParaFormat.CREATE(object: TObject; heap: THeap; itsStyleSheet: TStyleSheet): TParaFormat; $VAR tabArray: TArray; $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TParaFormat(object); (tabArray := TArray.CREATE(NIL, heap, 0, SIZEOF(TTxtTabDescriptor)); (WITH SELF DO ,BEGIN ,{$H-} ,MakeTypeStyle(famModern, size12Pitch, [], dfltTstyle); ,{$H+} ,wordWrap := TRUE; ,quad := aLeft; ,firstIndent := 0; ,leftIndent := 0; ,rightIndent := 0; ,spaceAbovePara := 0; ,spaceBelowPara := 0; ,lineSpacing := 0; ,tabs := tabArray; ,permanent := FALSE; ,refCount := 0; ,styleSheet := itsStyleSheet; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParaFormat.Free; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (Free(SELF.tabs); (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TParaFormat.Clone(heap: THeap): TObject; $VAR tabs: TArray; (paraFormat: TParaFormat; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (tabs := TArray(SELF.tabs.Clone(heap)); (paraFormat := TParaFormat(SUPERSELF.Clone(heap)); (paraFormat.tabs := tabs; (paraFormat.refCount := 0; (Clone := paraFormat; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fParaTrace} $PROCEDURE TParaFormat.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('dfltTstyle: RECORD onFaces: HexByte; filler: HexByte; fontFamily: Byte; fontSize: Byte END'); (Field('wordWrap: BOOLEAN'); (Field('quad: HexByte'); (Field('firstIndent: INTEGER'); (Field('leftIndent: INTEGER'); (Field('rightIndent: INTEGER'); (Field('spaceAbovePara: INTEGER'); (Field('spaceBelowPara: INTEGER'); (Field('lineSpacing: INTEGER'); (Field('tabs: TArray'); (Field('refCount: INTEGER'); (Field('permanent: BOOLEAN'); (Field('styleSheet: BOOLEAN'); (Field(''); $END; {$ENDC} {$S SgTxtCld} $PROCEDURE TParaFormat.ChangeRefCountBy(delta: INTEGER); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.refCount := SELF.refCount + delta; (IF (SELF.refCount <= 0) AND NOT SELF.permanent THEN ,BEGIN ,IF SELF.styleSheet <> NIL THEN 0SELF.styleSheet.formats.DelObject(SELF, TRUE) ,ELSE 0SELF.Free; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParaFormat.SetTypeStyle(tStyle: TTypeStyle); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SetQDTypeStyle(tStyle); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} BEGIN $UnitAuthor('Apple'); END; METHODS OF TParagraph; {$S SgTxtIni} $FUNCTION TParagraph.CREATE(object: TObject; heap: THeap; HinitialSize: INTEGER; initialTypeStyle: TTypeStyle): TParagraph; $VAR ts: TArray; (styleChange: TStyleChange; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF object = NIL THEN ,object := NewDynObject(heap, THISCLASS, initialSize); (SELF := TParagraph(TString.CREATE(object, heap, initialSize)); (ts := TArray.CREATE(NIL, heap, 0, SIZEOF(TStyleChange)); (styleChange.lp := MAXINT; { -sentinel- } (styleChange.newStyle := initialTypeStyle; (ts.InsAt(1, @styleChange); (styleChange.lp := -1; (ts.InsAt(1, @styleChange); (SELF.typeStyles := ts; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParagraph.Free; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (Free(SELF.typeStyles); (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TParagraph.Clone(heap: THeap): TObject; $VAR paragraph: TParagraph; (styles: TArray; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (styles := TArray(SELF.typeStyles.Clone(heap)); (paragraph := TParagraph(SUPERSELF.Clone(heap)); (paragraph.typeStyles := styles; (Clone := paragraph; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fParaTrace} $PROCEDURE TParagraph.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field(CONCAT('typeStyles: TArray OF RECORD lp: INTEGER; onFaces: HexByte; ', L'filler: HexByte; fontFamily: Byte; fontSize: Byte END')); (Field(''); $END; {$ENDC} {$S TK2Start} "{BuildExtentLRect takes an LPoint that indicates the baseline of the paragraph. It returns #in extentLRect the bounding rectangle whose height is based on the tallest font in the #paragraph and width is the width of the characters in the paragraph.} $PROCEDURE TParagraph.BuildExtentLRect(baseLPt: LPoint; VAR extentLRect: LRect); $VAR styleChange: TStyleChange; (fInfo: FontInfo; (i: INTEGER; (tallestFont: FontInfo; (width: INTEGER; (oldTallest: INTEGER; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (oldTallest := 0; (FOR i := 1 to SELF.typeStyles.size - 1 DO ,BEGIN ,SELF.typeStyles.GetAt(i, @styleChange); ,SELF.SetTypeStyle(styleChange.newStyle); ,GetFontInfo(fInfo); ,WITH fInfo DO 0IF oldTallest < ascent + descent + leading THEN 4BEGIN 4oldTallest := ascent + descent + leading; 4tallestFont := fInfo; 4END; ,END; (width := SELF.Width(1, SELF.size); (WITH extentLRect, baseLPt, tallestFont DO ,BEGIN ,top := v - ascent; ,bottom := v + descent + leading; ,left := h; ,right := h + width; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParagraph.ChangeStyle(startLP, endLP: INTEGER; PROCEDURE Change(VAR typeStyle: TTypeStyle); XVAR styleOfStartLP: TTypeStyle); $VAR firstChange: TStyleChange; (tempChange: TStyleChange; (prevChange: TStyleChange; (styles: TArray; (styleIndex: INTEGER; (newStyle: TTypeStyle; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({$IFC fParaTrace} (IF fParaTrace THEN ,BEGIN ,WriteLn('=== Entering TParagraph.ChangeStyle: startLP=', startLP:1, ' endLP=', endLP:1); ,END; ({$ENDC} (styles := SELF.typeStyles; (styleIndex := 1; (REPEAT ,styleIndex := styleIndex + 1; ,styles.GetAt(styleIndex, @tempChange); (UNTIL tempChange.lp >= startLP; ({If the change is on a run boundary, just remember the changed style at the beginning so )we can set styleOfStartLP later} (IF tempChange.lp = startLP THEN ,BEGIN ,firstChange := tempChange; ,Change(firstChange.newStyle); ,END (ELSE ,BEGIN ,{Insert new run descriptor for beginning of changed characters} ,styles.GetAt(styleIndex - 1, @firstChange); ,prevChange := firstChange; ,firstChange.lp := startLP; ,Change(firstChange.newStyle); ,styles.InsAt(styleIndex, @firstChange); ,styleIndex := styleIndex + 1; ,END; ({Change existing runs} (WHILE (tempChange.lp < endLP) DO ,BEGIN ,prevChange := tempChange; ,Change(tempChange.newStyle); ,styles.PutAt(styleIndex, @tempChange); ,styleIndex := styleIndex + 1; ,styles.GetAt(styleIndex, @tempChange); ,END; ({Don't restore old run info if new run info goes to end of para or ends on old run boundary} (IF endLP < SELF.size THEN ,IF tempChange.lp <> endLP THEN 0BEGIN 0prevChange.lp := endLP; 0styles.InsAt(styleIndex, @prevChange); 0END; (SELF.CleanRuns; ({return typestyle of beginning of run} (styleOfStartLP := firstChange.newStyle; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParagraph.ChgFace(startLP, endLP: INTEGER; HnewOnFaces: {$IFC LibraryVersion <= 20}TSeteface{$ELSEC}Style{$ENDC}; XVAR styleOfStartLP: TTypeStyle); (PROCEDURE ChangeFace(VAR typeStyle: TTypeStyle); (BEGIN ,IF newOnFaces = [] THEN 0typeStyle.onFaces := [] ,ELSE 0typeStyle.onFaces := typeStyle.onFaces + newOnFaces; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.ChangeStyle(startLP, endLP, ChangeFace, styleOfStartLP); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParagraph.ChgFontFamily(startLP, endLP: INTEGER; newFontFamily: Byte; XVAR styleOfStartLP: TTypeStyle); (PROCEDURE ChangeFamily(VAR typeStyle: TTypeStyle); (BEGIN ,typeStyle.font.fontFamily := newFontFamily; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.ChangeStyle(startLP, endLP, ChangeFamily, styleOfStartLP); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParagraph.ChgFontSize(startLP, endLP: INTEGER; newFontSize: Byte; XVAR styleOfStartLP: TTypeStyle); (PROCEDURE ChangeSize(VAR typeStyle: TTypeStyle); (BEGIN ,typeStyle.font.fontSize := newFontSize; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.ChangeStyle(startLP, endLP, ChangeSize, styleOfStartLP); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} ${Deletes redundant run information} $PROCEDURE TParagraph.CleanRuns; $VAR styleChange: TStyleChange; (prevChange: TStyleChange; (styles: TArray; (styleIndex: INTEGER; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (styles := SELF.typeStyles; (styles.GetAt(1, @prevChange); (styleIndex := 2; ({Iterate through the style changes and delete any that have either the same lp as the previous )change or the same font and faces info} (WHILE styleIndex < styles.Size DO ,BEGIN ,styles.GetAt(styleIndex, @styleChange); ,IF (styleChange.lp = prevChange.lp) OR 8((styleChange.newStyle.onFaces = prevChange.newStyle.onFaces) AND 8(styleChange.newStyle.font.fontNum = prevChange.newStyle.font.fontNum)) THEN 0styles.DelAt(styleIndex) ,ELSE 0styleIndex := styleIndex + 1; ,prevChange := styleChange; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParagraph.Draw(i: LONGINT; howMany: INTEGER); $VAR dumInt: INTEGER; (dumIndex: INTEGER; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (dumIndex := 1; (SELF.DrawLine(i-1, i + howMany - 2, TRUE, FALSE, dumInt, dumIndex); ({$IFC fTrace}EP;{$ENDC} $END; {$S TK2Start} $PROCEDURE TParagraph.DrawLine(startLP, endLP: INTEGER; fDraw: BOOLEAN; fWidth: BOOLEAN; IVAR width: INTEGER; VAR styleIndex: INTEGER); ${If fDraw = TRUE, draws a line of characters from startLP to endLP; does not worry about word wrap. %If fWidth = TRUE, returns width of characters. Also accepts an initial styleIndex (index into %run array) to make typestyle scanning faster. Returns styleIndex of run of last character drawn.} ${IDEAS TO MAKE THIS FASTER: (special check to see if there are no typestyle changes in this para? $} $VAR startPP: INTEGER; (endPP: INTEGER; (styleChange: TStyleChange; (prevChange: TStyleChange; (tStyles: TArray; (drawCount: INTEGER; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({$IFC fParaTrace} (IF fParaTrace THEN ,BEGIN ,writeln('>> DrawLine: startLP=', startLP:1, ' endLP=', endLP:1, 4' styleIndex=', styleIndex:1); ,WriteLn('>> DrawLine: fDraw=', fDraw, ' holeStart =', SELF.holeStart:1, 4' holeSize =', SELF.holeSize:1); ,END; ({$ENDC} (width := 0; (tStyles := SELF.typeStyles; (IF (styleIndex < 1) OR (styleIndex > tStyles.size) THEN ,styleIndex := 1; (tStyles.GetAt(styleIndex, @styleChange); (prevChange := styleChange; (WHILE styleChange.lp < startLP DO ,BEGIN ,prevChange := styleChange; ,styleIndex := styleIndex + 1; ,tStyles.GetAt(styleIndex, @styleChange); ,END; (PicTextBegin(aLeft); (SELF.SetTypeStyle(prevChange.newStyle); ({$IFC fParaTrace} (IF fParaTrace THEN ,writeln('>> DrawLine: starting to Draw'); ({$ENDC} (WHILE startLP <= endLP DO ,BEGIN ,drawCount := MIN(styleChange.lp, endLP+1) - startLP; ,IF fWidth THEN 0width := width + TString.Width(startLP+1, drawCount); ,IF fDraw THEN 0BEGIN 0{$IFC fParaTrace} 0IF fParaTrace THEN 4writeln('>> DrawLine: About to call DrawText; startLP,drawCount=', startLP:1, D',', drawCount:1); 0{$ENDC} 0TString.Draw(startLP+1, drawCount); 0END; ,startLP := startLP + drawCount; ,IF startLP = styleChange.lp THEN 0BEGIN 0{$IFC fParaTrace} 0IF fParaTrace THEN 4writeln('>> DrawLine: found a typestyle change at LP=', startLP:1); 0{$ENDC} 0SELF.SetTypeStyle(styleChange.newStyle); 0styleIndex := styleIndex+1; 0tStyles.GetAt(styleIndex, @styleChange) 0END; ,END; (PicTextEnd; (styleIndex := styleIndex-1; {return styleIndex of current typeStyle run} ({$IFC fParaTrace} (IF fParaTrace THEN ,BEGIN ,Writeln('>> DrawLine: Finished, width=', width:1); ,WriteLn; ,END; ({$ENDC} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TParagraph.FindWordBounds(orig: INTEGER; VAR first, last: INTEGER); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (first := orig; (last := orig; (IF SELF.Qualifies(orig) THEN ,BEGIN ,WHILE SELF.Qualifies(first - 1) DO first := first - 1; ,WHILE SELF.Qualifies(last + 1) DO last := last + 1; ,END; (IF last < SELF.size THEN ,last := last+1; {always selects at least one character, except at end of para} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TParagraph.FixLP(LP: INTEGER): INTEGER; $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (IF LP < 0 THEN ,FixLP := 0 (ELSE IF LP >= SELF.size THEN ,FixLP := SELF.size (ELSE ,FixLP := LP; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParagraph.NewStyle(startLP, endLP: INTEGER; newTypeStyle: TTypeStyle); $VAR styleOfStartLP: TTypeStyle; (PROCEDURE ChgStyle(VAR typeStyle: TTypeStyle); (BEGIN ,typeStyle := newTypeStyle; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.ChangeStyle(startLP, endLP, ChgStyle, styleOfStartLP); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $FUNCTION TParagraph.Qualifies(pos: INTEGER): BOOLEAN; $VAR i,j: INTEGER; (left, this, right: CHAR; (FUNCTION CharClass(ch: CHAR): CHAR; (VAR c: INTEGER; (BEGIN ,c := ORD(ch); ,IF c IN [65..90, 97..122, 128..159, 167, 174..175, 5187..188, 190..191, 202] THEN ch := 'A' ,ELSE IF (48 <= c) AND (c <= 57) THEN ch := '9' ,ELSE IF (c = 162) OR (c = 163) OR (c = 180) THEN ch := '$'; ,CharClass := ch; (END; (FUNCTION CharAt(i: INTEGER): CHAR; (BEGIN ,IF i < 0 THEN 0CharAt := ' ' ,ELSE IF i >= SELF.size THEN 0CharAt := ' ' ,ELSE 0CharAt := SELF.At(i+1); (END; $BEGIN {Qualifies} ({$IFC fTrace}BP(9);{$ENDC} (left := CharClass(CharAt(pos-1)); (this := CharClass(CharAt(pos)); (right := CharClass(CharAt(pos+1)); ({$IFC fParaTrace} (IF fParaTrace THEN ,WriteLn('IN QUALIFIES: left, this, right = (', left:1, this:1, right:1, ') => [', 8ORD(left):1, ',', ORD(this):1, ',', ORD(right):1, ']'); ({$ENDC} (FOR i := 1 TO (LENGTH(wordDelimiters) + 1) DIV 4 DO ,BEGIN ,j := 4*i-2; { FOR j := 2 TO LENGTH(wordDelimiters) STEP 4 DO } ,IF ((wordDelimiters[j-1]=left) OR (wordDelimiters[j-1] = 'x')) AND 0(wordDelimiters[j] = this) AND /((wordDelimiters[j+1]=right) OR (wordDelimiters[j+1]='x')) THEN 4BEGIN 4Qualifies := TRUE; 4{$IFC fTrace}EP;{$ENDC} 4EXIT(Qualifies); 4END; ,END; (Qualifies := FALSE; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TParagraph.ReplPara(fPos, numChars: INTEGER; GotherPara: TParagraph; otherFPos, otherNumChars: INTEGER); $VAR styles: TArray; (otherStyles: TArray; (styleIndex: INTEGER; (otherIndex: INTEGER; (styleChange: TStyleChange; (otherChange: TStyleChange; (prevStyle: TTypeStyle; (diff: INTEGER; (endLP: INTEGER; (nextLP: INTEGER; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} (otherPara.StopEdit; (SELF.ReplTString(fPos, numChars, otherPara, otherFPos, otherNumChars); (IF otherNumChars > 0 THEN ,BEGIN ,{COPY THE TYPESTYLE RUN INFO TO SELF.typeStyles} ,otherStyles := otherPara.typeStyles; ,styles := SELF.typeStyles; ,{Find out what run we're in in SELF} ,styleIndex := 1; ,REPEAT 0styleIndex := styleIndex+1; 0styles.GetAt(styleIndex, @styleChange); ,UNTIL fPos <= styleChange.lp; ,nextLP := styleChange.lp; ,IF fPos < nextLP THEN 0styles.GetAt(styleIndex-1, @styleChange); {back up one to get current run} ,{Find the first run in otherPara} ,otherIndex := 1; ,REPEAT 0otherIndex := otherIndex+1; 0otherStyles.GetAt(otherIndex, @otherChange); ,UNTIL otherFPos < otherChange.lp; ,otherStyles.GetAt(otherIndex-1, @otherChange); ,diff := fPos - otherFPos; ,endLP := otherfPos + otherNumChars; ,prevStyle := styleChange.newStyle; ,{Insert the new run info but avoid consecutive run descriptors of the same info} ,otherChange.lp := otherFPos; ,WHILE otherChange.lp <= endLP DO 0BEGIN 0IF TFakeTStyle(otherChange.newStyle) <> TFakeTStyle(prevStyle) THEN 4BEGIN 4otherChange.lp := otherChange.lp + diff; 4styles.InsAt(styleIndex, @otherChange); 4styleIndex := styleIndex + 1; 4prevStyle := otherChange.newStyle; 4END; 0otherStyles.GetAt(otherIndex, @otherChange); 0otherIndex := otherIndex + 1; 0END; ,{Insert descriptor of original run after the inserted info, unless we were on a run boundary .or the last run has the same font and faces as the original run} ,IF fPos < nextLP THEN 0IF TFakeTStyle(styleChange.newStyle) <> TFakeTStyle(prevStyle) THEN 4BEGIN 4styleChange.lp := fPos+otherNumChars; 4styles.InsAt(styleIndex, @styleChange); 4END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParagraph.ReplPString(fPos, numChars: INTEGER; pStr: TPString); (VAR otherNumChars: INTEGER; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} ({ make fPos lie within [0..# chars in paragraph] } (fPos := SELF.fixLP(fPos); (IF pStr = NIL THEN ,otherNumChars := 0 (ELSE ,otherNumChars := Length(pStr^); (SELF.StartEdit(otherNumChars); (SELF.DelManyAt(fPos + 1, numChars); ((* (SELF.UpdateRuns(fPos,-numChars); (*) (IF pStr <> NIL THEN ,SELF.InsPStrAt(fPos + 1, pStr); (SELF.StopEdit; (SELF.UpdateRuns(fPos, numChars, otherNumChars); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParagraph.ReplTString(fPos, numChars: INTEGER; 7otherString: TString; otherFPos, otherNumChars: INTEGER); $BEGIN ({$IFC fTrace}BP(9);{$ENDC} ({ make fPos lie within [0..# chars in paragraph] } (fPos := SELF.fixLP(fPos); (SELF.StartEdit(otherNumChars); (IF numChars > 0 THEN ,SELF.DelManyAt(fPos + 1, numChars); (IF (otherString <> NIL) AND (otherNumChars > 0) THEN ,SELF.InsManyAt(fPos + 1, otherString, otherFPos + 1, otherNumChars); (SELF.StopEdit; (SELF.UpdateRuns(fPos, numChars, otherNumChars); ({$IFC fTrace}EP;{$ENDC} $END; {$S TK2Start} $PROCEDURE TParagraph.SetTypeStyle(tStyle: TTypeStyle); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SetQDTypeStyle(tStyle); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParagraph.StyleAt(lp: INTEGER; VAR typeStyle: TTypeStyle); $VAR styleChange: TStyleChange; (styles: TArray; (styleIndex: INTEGER; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} (styles := SELF.typeStyles; (styleIndex := 1; (styles.GetAt(1, @styleChange); (WHILE styleChange.lp <= lp DO ,BEGIN ,typeStyle := styleChange.newStyle; ,styleIndex := styleIndex+1; ,styles.GetAt(styleIndex, @styleChange); ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParagraph.UpdateRuns(atLP: INTEGER; replacedChars: INTEGER; insertedChars: INTEGER); $VAR tStyles: TArray; (i: INTEGER; (aChange: TStyleChange; (tempChange: TStyleChange; (prevStyle: TTypeStyle; (lastDeleted: INTEGER; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} (tStyles := SELF.typeStyles; (lastDeleted := -1; (i := 1; (WHILE i <= tStyles.size DO ,BEGIN ,tStyles.GetAt(i, @aChange); ,IF atLP <= aChange.lp THEN 0BEGIN 0IF i < tStyles.size THEN 4aChange.lp := aChange.lp - replacedChars; 0{if we deleted some chars, we must delete associated run info} 0IF aChange.lp <= atLP THEN 4BEGIN 4{save type style since we may have deleted only part of this run} 4tempChange := aChange; 4{assume whole run deleted, reinsert later if not} 4tStyles.DelAt(i); 4lastDeleted := i; 4i := i-1; 4END 0ELSE 4BEGIN 4IF i = lastDeleted THEN 8{put back run info for last run deleted if part of it still remains and is not 9the same as the run before the changes} 8IF (aChange.lp <> atLP) AND <(TFakeTStyle(tempChange.newStyle) <> TFakeTStyle(prevStyle)) THEN  SELF.holeStart) OR (size <> 0) THEN {nothing to do--must be backspacing} (BEGIN (SELF.EditAt(atLP + 1, size); (SELF.bsCount := 0; (END; ${$IFC fTrace} EP; {$ENDC} $END; {$S SgTxtCld} $PROCEDURE TEditPara.DelImage(delImage: TParaImage; fFree: BOOLEAN); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.images.DelObject(delImage, fFree); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} ${Selectively delete paraImages from list based on Function Parameter} $PROCEDURE TEditPara.DelImgIF(FUNCTION ShouldDelete(paraImage: TParaImage): BOOLEAN); $VAR s: TListScanner; (paraImage: TParaImage; ((* (i: INTEGER; (numDeleted: INTEGER; (*) $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (s := SELF.images.Scanner; (WHILE s.Scan(paraImage) DO ,IF ShouldDelete(paraImage) THEN 0s.Delete(FALSE); ((* (numDeleted := 0; (WITH SELF DO ,BEGIN ,i := 1; ,WHILE i <= numImages DO 0BEGIN 0{$R-} {$H-} 0IF ShouldDelete(images[i]) THEN 4numDeleted := numDeleted+1 0ELSE IF numDeleted > 0 THEN 4images[i-numDeleted] := images[i]; 0{$IFC fRngText}{$R+}{$ENDC} {$H+} 0i := i+1; 0END; ,IF numDeleted > 0 THEN 0BEGIN 0FOR i := (numImages-numDeleted+1) TO numImages DO 4{$R-} 4images[numImages] := NIL; 4{$IFC fRngText}{$R+}{$ENDC} 0numImages := numImages-numDeleted; 0END; ,END; (*) ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TEditPara.EachImage(PROCEDURE ImageProc(paraImage: TParaImage)); $(* $VAR i: INTEGER; $*) (PROCEDURE DoIt(object: TObject); (BEGIN ,ImageProc(TParaImage(object)); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.images.Each(DoIt); ((* (FOR i := 1 TO SELF.numImages DO %{$R-} ImageProc(SELF.images[i]); {$IFC fRngText}{$R+}{$ENDC} (*) ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TEditPara.EndInsertion; ({After calling this: ,holeStart = emptyPos = # chars in paragraph (} $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (SELF.StopEdit; (SELF.bsCount := 0; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TEditPara.GrowSize: INTEGER; $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (GrowSize := 200; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TEditPara.InsertOneChar(ch: CHAR; atLP: INTEGER); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.BeginInsertion(atLP, 1); {UNDO} ({ now we have SELF.holeStart = atLP } (SELF.PutAt(atLP+1, ch); (SELF.UpdateRuns(atLP, 0, 1); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TEditPara.InsImage(paraImage: TParaImage); $(* $VAR i: INTEGER; (found: BOOLEAN; $*) $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.images.InsLast(paraImage); ((* (IF SELF.numImages = SELF.maxImages THEN ,BEGIN ,SELF.ResizeCollection(SELF.size + SELF.holeSize + 4); ,SELF.ShiftCollection(0, 4, SELF.size + SELF.holeSize); ,WITH SELF DO 0BEGIN 0dynStart := dynStart + 4; 0maxImages := maxImages + 1; 0END; ,END; (WITH SELF DO ,BEGIN ,numImages := numImages + 1; ,{$R-} ,images[numImages] := paraImage; ,{$IFC fRngText}{$R+}{$ENDC} ,END; (*) ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TEditPara.SetTypeStyle(tStyle: TTypeStyle); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.format.SetTypeStyle(tStyle); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; METHODS OF TLineInfo; {$S SgTxtWrm} $FUNCTION TLineInfo.CREATE(object: TObject; heap: THeap): TLineInfo; $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TLineInfo(object); (WITH SELF DO ,BEGIN ,valid := FALSE; ,startLP := 0; ,lastDrawnLP := 0; ,endLP := 0; ,lineLRect := zeroLRect; ,lineAscent := 0; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fParaTrace} $PROCEDURE TLineInfo.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('valid: BOOLEAN'); (Field('startLP: INTEGER'); (Field('lastDrawnLP: INTEGER'); (Field('endLP: INTEGER'); (Field('lineLRect: LRect'); (Field('lineAscent: INTEGER'); (Field(''); $END; {$ENDC} {$S SgTxtHot} $FUNCTION TLineInfo.LeftCoord(proposedLeftPixel: LONGINT): LONGINT; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} ({Default is to not change the parameter; TLineInfo subclassers may choose to do otherwise} (LeftCoord := proposedLeftPixel; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TLineInfo.RightCoord(proposedRightPixel: LONGINT): LONGINT; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} ({Default is to not change the parameter; TLineInfo subclassers may choose to do otherwise} (RightCoord := proposedRightPixel; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; METHODS OF TParaImage; {$S SgTxtWrm} $FUNCTION TParaImage.CREATE(object: TObject; heap: THeap; itsView: TView; itsParagraph: TEditPara; ?itsLRect: LRect; lineTop: LONGINT; lineLeft: LONGINT): TParaImage; $VAR aLineList: TList; (lineInfo: TLineInfo; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TParaImage(TImage.CREATE(object, heap, itsLRect, itsView)); (SELF.paragraph := itsParagraph; (SELF.extentLRect := itsLRect; (aLineList := TList.CREATE(NIL, heap, 0); (lineInfo := SELF.DfltLineInfo(lineTop, lineLeft); (aLineList.InsLast(lineInfo); (WITH SELF DO ,BEGIN ,height := lineInfo.lineLRect.bottom - lineInfo.lineLRect.top; ,lineList := aLineList; ,tickcount := 0; ,changed := TRUE; ,startLP := 0; ,endLP := 0; ,textImage := NIL; ,wasOffset := FALSE; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TParaImage.Free; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (Free(SELF.lineList); ((* Since caller of this may be scanning the paragraph's image list we can't delete it from the +list here lest we screw up the caller's scanner. So the caller will have to to do this} (SELF.paragraph.DelImage(SELF, FALSE); (*) (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fParaTrace} $PROCEDURE TParaImage.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('paragraph: TEditPara'); (Field('height: INTEGER'); (Field('lineList: TList'); (Field('changed: BOOLEAN'); (Field('tickCount: INTEGER'); (Field('startLP: INTEGER'); (Field('endLP: INTEGER'); (Field('textImage: TTextImage'); (Field('wasOffset: BOOLEAN'); (Field(''); $END; {$ENDC} {$S SgTxtHot} $PROCEDURE TParaImage.AdjustLineLPs(atLP, deltaLP: INTEGER); ({positive deltaLP implies character(s) were inserted, negative deltaLP implies they were deleted} (PROCEDURE AdjustLP(obj: TObject); (BEGIN ,WITH TLineInfo(obj) DO 0BEGIN 0{$H-} 0IF startLP > atLP THEN 4startLP := Max(atLP, startLP + deltaLP); 0IF lastDrawnLP > atLP THEN 4lastDrawnLP := Max(atLP, lastDrawnLP + deltaLP); 0IF endLP > atLP THEN 4endLP := Max(atLP, endLP + deltaLP); 0{$H+} 0END; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.lineList.Each(AdjustLP); (WITH SELF DO ,BEGIN ,{$H-} ,IF startLP > atLP THEN 0startLP := Max(atLP, startLP + deltaLP); ,IF endLP >= atLP THEN 0endLP := Max(atLP, endLP + deltaLP); ,{$H+} ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParaImage.ComputeLineInfo(curLine: TLineInfo; maxLineLen: INTEGER; PVAR nextLP: INTEGER; VAR lRectNeeded: LRect); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $FUNCTION TParaImage.DfltLineInfo(lineTop: LONGINT; lineLeft: LONGINT): TLineInfo; $VAR lineInfo: TLineInfo; (fInfo: FontInfo; (i: INTEGER; (format: TParaFormat; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} (lineInfo := TLineInfo.CREATE(NIL, SELF.Heap); (format := SELF.GetFormat; (format.SetTypeStyle(format.dfltTStyle); (GetFontInfo(fInfo); (i := SELF.paragraph.size; (WITH lineInfo, fInfo, format DO ,BEGIN ,lastDrawnLP := i; ,endLP := i; ,lineAscent := ascent; ,{$H-} ,SetLRect(lineLRect, lineLeft, lineTop, lineLeft, 8spaceAbovePara + lineTop + ascent + descent + leading + spaceBelowPara); ,OffsetLRect(lineLRect, SELF.extentLRect.left + firstIndent, SELF.extentLRect.top); ,{$H+} ,END; (DfltLineInfo := lineInfo; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParaImage.DrawLine(startLP: INTEGER; fDraw: BOOLEAN; stopWidth, wrapWidth: INTEGER; EVAR lineWidth, lastToDraw, endLP: INTEGER); ${Figures out what characters to draw based on a variety of input constraints. ,Returns: 0lineWidth: the width of the line calculated (including trailing spaces) [??] 0lastToDraw: the lp of the last non blank character in the line 0endLP: the lp of the last character in the line (may be a blank) } ${NOTE: the wrapWidth parameter may eventually be dropped and instead calculated from SELF.extentLRect ,and certain format fields} $LABEL 1; $VAR c: CHAR; (startPP: INTEGER; (curIndex: INTEGER; { PP of last character looked at } (styleChange: TStyleChange; (prevChange: TStyleChange; (styles: TArray; (styleIndex: INTEGER; (firstStyleIndex:INTEGER; (cWidth: INTEGER; (maxPP: INTEGER; (endPP: INTEGER; (breakIndex: INTEGER; (breakCount: INTEGER; (breakLen: INTEGER; (paragraph: TEditPara; (format: TParaFormat; (drawStart: INTEGER; (drawCount: INTEGER; (dummy: INTEGER; (maxLP: INTEGER; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({$IFC fParaTrace} (IF fParaTrace THEN ,writeln('** DrawLine: startLP=', startLP:1, ', maxLP=',maxLP:1, ', fDraw=', fDraw, 4', stopWidth=',stopWidth:1, ', wrapWidth=',wrapWidth:1); ({$ENDC} (maxLP := SELF.paragraph.size-1; (IF maxLP < startLP THEN ,BEGIN ,lineWidth := 0; ,lastToDraw := maxLP; ,endLP := maxLP; ,END (ELSE ,BEGIN ,paragraph := SELF.paragraph; ,format := SELF.GetFormat; ,breakIndex := 0; ,lastToDraw := 0; ,lineWidth := 0; ,cWidth := 0; ,curIndex := paragraph.FixLP(startLP); ,styles := paragraph.typeStyles; ,styles.GetAt(1, @styleChange); ,styleIndex := 1; ,REPEAT 0prevChange := styleChange; 0styleIndex := styleIndex + 1; 0styles.GetAt(styleIndex, @styleChange); ,UNTIL curIndex < styleChange.lp; ,format.SetTypeStyle(prevChange.newStyle); ,firstStyleIndex := styleIndex-1; ,startPP := curIndex; ,maxPP := MIN(paragraph.size, paragraph.FixLP(maxLP)); ,{$IFC fParaTrace} ,IF fParaTrace THEN 0writeln('** DrawLine: About enter loop, maxPP =',maxPP:1,' holeStart=',paragraph.holeStart:1, 8' holeSize=',paragraph.holeSize:1); ,{$ENDC} ,WHILE curIndex <= maxPP DO 0BEGIN 0IF curIndex = styleChange.lp THEN 4BEGIN 4format.SetTypeStyle(styleChange.newStyle); 4styleIndex := styleIndex+1; 4styles.GetAt(styleIndex, @styleChange) 4END; 0c := paragraph.At(curIndex+1); 0cWidth := CharWidth(c); 0{$IFC fParaTrace AND FALSE} 0IF fParaTrace THEN 4writeln('curIndex=', curIndex:1, ', char=', c, ', cWidth=', @cWidth:1, ', lineWidth=',lineWidth:1); 0{$ENDC} 0{Drop out of loop if lineWidth > stopWidth unless 4we're at end of line and have trailing spaces} 0IF (lineWidth + cWidth > stopWidth) THEN 4IF format.wordWrap AND (stopWidth = wrapWidth) THEN 8IF (c <> ' ') THEN  wrapWidth) AND (breakIndex > 0) THEN 0{ PRIMITIVE WORD WRAP! } 0BEGIN 0lineWidth := breakLen; 0curIndex := breakIndex; 0END ,ELSE 0lastToDraw := curIndex; ,{$IFC fParaTrace} ,IF fParaTrace THEN 0writeln('** DrawLine: About to figure endLP, curIndex =',curIndex:1); ,{$ENDC} ,endLP := curIndex; ,{$IFC fParaTrace} ,IF fParaTrace THEN 0writeln('** DrawLine: endLP figured =',endLP:1); ,{$ENDC} ,IF (lastToDraw >= 0) AND fDraw THEN 0SELF.FastDrawLine(paragraph.fixLP(startLP), lastToDraw, TRUE, XFALSE, dummy, firstStyleIndex); ,END; ({$IFC fParaTrace} (IF fParaTrace THEN ,BEGIN ,writeln('** DrawLine done: endLP=',endLP:1,', lineWidth=',lineWidth:1); ,writeln('** DrawLine done: final lastToDraw=',lastToDraw:1); ,WriteLn; ,END; ({$ENDC} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParaImage.DrawParaImage(limitLRect: LRect; startLP: INTEGER; drawAction: TDrawAction; LinvalBits: BOOLEAN; VAR drawnLRect: LRect); ${Note: DrawParaImage now assumes that the paragraph was changed} $LABEL 1; $VAR paragraph: TEditPara; (fInfo: FontInfo; (lineInfo: TLineInfo; (firstLineInfo: TLineInfo; (lineList: TList; (lineSpacing: INTEGER; (curBase: LONGINT; (leftMargin: LONGINT; (curLP: INTEGER; (endLP: INTEGER; (numChars: INTEGER; (lineLen: INTEGER; (maxLineLen: INTEGER; (lineIndex: INTEGER; (pixel: LONGINT; (lastDrawnLP: INTEGER; (testLPoint: LPoint; (format: TParaFormat; (firstFudge: INTEGER; (startOfNewPara: BOOLEAN; (anLRect: LRect; (sLine: TListScanner; (genRest: BOOLEAN; (genBefore: BOOLEAN; (oldEndLP: INTEGER; (prevLineInfo: TLineInfo; (prevLen: INTEGER; (prevPImage: TParaImage; (prevTxtImage: TTextImage; (origStart: INTEGER; (dummy: INTEGER; (styleIndex: INTEGER; (r: LRect; ({$IFC fParaTrace} (str: STR255; ({$ENDC} $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({$IFC fParaTrace} (IF fParaTrace THEN ,BEGIN ,WITH limitLRect DO 0WriteLn('## Entering DrawParaImage: limitLRect=[(',left:1,',',top:1,'),(', dright:1,',', bottom:1,')]'); ,LIntToHex(ORD(SELF), @str); ,WriteLn( ' SELF = ', str,' startLP=',startLP:1,' drawAction=',ORD(drawAction)); ,END; ({$ENDC} (drawnLRect := limitLRect; (endLP := startLP; (paragraph := SELF.paragraph; (format := SELF.GetFormat; (IF drawAction = actionDraw THEN WITH SELF DO ,tickCount := (tickCount+1) MOD MAXINT; (PicGrpBegin; (PenNormal; (genRest := FALSE; (genBefore := FALSE; (curLP := startLP; (numChars := paragraph.size; (SELF.startLP := curLP; (format.SetTypeStyle(format.dfltTStyle); (GetFontInfo(fInfo); (WITH fInfo DO ,lineSpacing := ascent + descent + leading + format.lineSpacing; (lineList := SELF.lineList; (curBase := limitLRect.top; (prevLineInfo := NIL; (IF lineList.Size > 0 THEN ,BEGIN ,sLine := lineList.Scanner; ,{If existing lineInfo's start after startLP then we need to generate preceeding lineInfo's} ,IF TLineInfo(lineList.First).startLP > startLP THEN 0BEGIN 0origStart := TLineInfo(lineList.First).startLP; 0genBefore := TRUE; 0END ,ELSE WHILE sLine.Scan(lineInfo) DO 0BEGIN 0{delete lineinfo's that start before the startLP parameter} 0IF lineInfo.endLP < startLP THEN 4sLine.Delete(TRUE) 0ELSE 4BEGIN 4IF lineInfo.valid THEN 8BEGIN 8prevLineInfo := lineInfo; 8curBase := lineInfo.lineLRect.bottom; 8END 4ELSE 8GOTO 1; 4END; 0END; ,END (ELSE ,lineInfo := NIL; (1: (IF NOT genBefore THEN ,IF lineInfo = NIL THEN 0BEGIN 0genRest := TRUE; 0curLP := Max(startLP, SELF.endLP); 0END ,ELSE 0curLP := Max(startLP, lineInfo.startLP); (startOfNewPara := curLP = 0; (curBase := curBase + fInfo.ascent; (IF startOfNewPara THEN ,BEGIN ,curBase := curBase + format.spaceAbovePara; ,leftMargin := limitLRect.left + format.firstIndent; ,{ The first line maxLineLen might be different (due to firstIndent)} ,firstFudge := format.firstIndent - format.leftIndent; ,END (ELSE ,BEGIN ,leftMargin := limitLRect.left + format.leftIndent; ,firstFudge := 0; ,END; (limitLRect.left := limitLRect.left + format.leftIndent; (limitLRect.right := limitLRect.right - format.rightIndent; (maxLineLen := lengthLRect(limitLRect, h) - firstFudge; {if firstIndent is to left of aleftIndent, fudge will be negative} (SetLPt(testLPoint, limitLRect.left, curBase + fInfo.descent); ({$IFC fParaTrace} (IF fParaTrace THEN ,BEGIN ,WriteLn('## DrawParaImage: Entering DrawLine loop -- leftMargin=',leftMargin:1, <' curBase=',curBase:1); ,END; ({$ENDC} ({don't bother going into the loop if we can't fit the first line or we've run out )of characters already (eg: empty para)} (IF (NOT LPtInLRect(testLPoint, limitLRect)) OR (curLP >= numChars) THEN ,BEGIN ,SELF.extentLRect := drawnLRect; ,IF NOT genRest THEN 0BEGIN 0r := lineInfo.lineLRect; 0r.left := lineInfo.LeftCoord(SELF.textImage.extentLRect.left-1); 0r.right := lineInfo.RightCoord(SELF.textImage.extentLRect.right+1); 0lineInfo := SELF.DfltLineInfo(0,0); 0r.bottom := lineInfo.lineLRect.bottom; 0sLine.Replace(lineInfo, TRUE); 0genRest := NOT sLine.Scan(lineInfo); 0END; ,{These two assignments distinguish (for the calling routine) whether an empty -paragraph did or did not fit in the limitLRect. Assuming curLP = 0, SELF.endLP -will be 0 for a paragraph that did fit and -1 for one that did not fit. The calling -routine checks this value against paragraph.size to see if the paragraph fit} ,IF LPtInLRect(testLPoint, limitLRect) THEN 0BEGIN 0SELF.endLP := curLP; 0{Erase the old line} 0IF drawAction = actionDraw THEN 4FillLRect(r, lPatWhite) 0ELSE IF drawAction = actionInval THEN 4thePad.InvalLRect(r); 0END ,ELSE 0SELF.endLP := curLP-1; ,{$IFC fParaTrace} ,IF fParaTrace THEN 0BEGIN 0WriteLn('## DrawParaImage: Empty para or cannot fit; endLP set to ',SELF.endLP:1); 0END; ,{$ENDC} ,END ({Otherwise, set up lineLRect and call DrawLine while there are still characters to display )and we still fit in limitLRect} (ELSE ,BEGIN ,{Layout line previous to first invalid line to see if characters from the -invalid line can wrap back. First, however, we must check for special case -of the previous line being in another textImage.} ,IF NOT startOfNewPara AND (prevLineInfo = NIL) THEN 0BEGIN 0prevTxtImage := SELF.textImage.prevTxtImg; 0IF prevTxtImage <> NIL THEN 4BEGIN 4prevPImage := TParaImage(prevTxtImage.imageList.Last); 4prevLineInfo := TLineInfo(prevPImage.lineList.Last); 4prevLen := LengthLRect(prevPImage.extentLRect, h) - format.leftIndent f- format.rightIndent; 4END; 0END ,ELSE 0BEGIN 0prevLen := maxLineLen; 0prevPImage := SELF; 0END; ,IF prevLineInfo <> NIL THEN 0BEGIN 0oldEndLP := prevLineInfo.endLP; 0IF prevLineInfo.startLP = 0 THEN 4prevLen := prevLen - (format.firstIndent - format.leftIndent); 0prevPImage.DrawLine(prevLineInfo.startLP, FALSE, prevLen, prevLen, LlineLen, lastDrawnLP, endLP); 0IF endLP <> oldEndLP THEN 4BEGIN 4SELF.textImage.useFirstPixel := FALSE; 4r := prevLineInfo.lineLRect; 4r.left := prevLineInfo.LeftCoord(prevPImage.textImage.extentLRect.left-1); 4r.right := prevLineInfo.RightCoord(prevPImage.textImage.extentLRect.right+1); 4IF drawAction = actionDraw THEN 8BEGIN 8FillLRect(r, lPatWhite); 8styleIndex := 1; 8MoveToL(prevLineInfo.lineLRect.left, @prevLineInfo.lineLRect.top+prevLineInfo.lineAscent); 8SELF.FastDrawLine(prevLineInfo.startLP, lastDrawnLP, TRUE, TFALSE, dummy, styleIndex); 8END 4ELSE IF drawAction = actionInval THEN 8thePad.InvalLRect(r); 4WITH prevLineInfo.lineLRect DO 8BEGIN 8prevLineInfo.valid := invalBits; 8right := left + lineLen; 8prevLineInfo.lastDrawnLP := lastDrawnLP; 8prevLineInfo.endLP := endLP; 8curLP := endLP + 1; 8prevPImage.endLP := curLP; 8IF curLP >= numChars THEN leftMargin + maxlineLen, curBase + descent + leading); ,leftMargin := limitLRect.left; ,{Setup GrafPort for first line (after prev line)} ,IF drawAction = actionDraw THEN 0MoveToL(leftMargin + firstFudge, curBase); ,WHILE (curLP < numChars) AND (LPtInLRect(testLPoint, limitLRect)) DO 0BEGIN 0IF genRest OR genBefore THEN 4lineInfo := TLineInfo.CREATE(NIL, paragraph.heap); 0IF NOT lineInfo.valid THEN 4BEGIN 4WITH fInfo, lineInfo DO 8BEGIN 8startLP := curLP; 8lineAscent := ascent; 8lineLRect := anLRect; 8END; 4r := anLRect; 4r.left := lineInfo.LeftCoord(SELF.textImage.extentLRect.left-1); 4IF SELF.textImage.useFirstPixel THEN 8BEGIN 8r.left := Max(r.left, SELF.textImage.firstLinePixel); 8SELF.textImage.useFirstPixel := FALSE; 8END; 4r.right := lineInfo.RightCoord(SELF.textImage.extentLRect.right+1); 4IF drawAction = actionDraw THEN 8FillLRect(r, lPatWhite) 4ELSE IF drawAction = actionInval THEN 8thePad.InvalLRect(r); 4oldEndLP := lineInfo.endLP; 4SELF.DrawLine(curLP, drawAction = actionDraw, maxLineLen, maxLineLen, LlineLen, lastDrawnLP, endLP); 4{$IFC fParaTrace} 4IF (curLP > endLP) AND (curLP < numChars)THEN 8BEGIN 8ABCbreak('loop in DrawParaImage; curLP=',curLP); 8endLP := curLP + 1; 8END; 4{$ENDC} 4{finish setting up new lineInfo} 4WITH fInfo, lineInfo.lineLRect DO 8BEGIN 8lineInfo.lastDrawnLP := lastDrawnLP; 8lineInfo.endLP := endLP; 8right := left + lineLen; 8{if this is last line in paragraph, add spaceBelowPara, unless that extra amount 9would put it ouside of the limitLRect} 8IF (endLP+1) >= numChars THEN  lineInfo.lineLRect.right THEN 8BEGIN 8r.left := lineInfo.lineLRect.right; 8IF drawAction = actionDraw THEN  curLP; 0IF NOT (genRest OR genBefore) THEN 4BEGIN 4IF sLine.Scan(lineInfo) THEN 8IF lineInfo.startLP <> curLP THEN  endLP); 0prevLineInfo := lineInfo; 0END; ,{last line} ,IF prevLineInfo.valid THEN 0BEGIN 0numChars := SELF.paragraph.size; 0prevLineInfo.valid := (numChars < startLP) OR (prevLineInfo.startLP > endLP); 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TParaImage.LineWithLPt(pt: LPoint; VAR lineIndex: INTEGER; VAR lineInfo: TLineInfo); $VAR s: TListScanner; (nxtLnInfo: TLineInfo; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} ({$IFC fParaTrace} (IF fParaTrace THEN ,writeln('in LineWithLPt, point=(,',pt.h:1,', ',pt.v:1,')'); ({$ENDC} (s := SELF.lineList.scanner; {&&& maybe could use TList.scannerFrom(index)} (lineIndex := 1; ({This has been modified to allow for the possibility of multiple lineRects at the same )vertical coordinate } (IF s.Scan(lineInfo) THEN ,WHILE s.scan(nxtLnInfo) DO 0BEGIN 0IF (pt.v < lineInfo.lineLRect.bottom) AND 4((pt.h < lineInfo.lineLRect.right) OR (pt.v < nxtLnInfo.lineLRect.top)) THEN 8s.Done 0ELSE 4BEGIN 4lineIndex := lineIndex + 1; 4lineInfo := nxtLnInfo; 4END; 0END (ELSE ,BEGIN ,{$IFC fParaTrace} ,IF fParaTrace THEN 0writeln(chr(7), 'LineWithLPt: no TLineInfo in TParaImage, lineIndex=0'); ,{$ENDC} ,lineIndex := 1; ,lineInfo := SELF.DfltLineInfo(0, 0); ,SELF.lineList.InsLast(lineInfo); ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParaImage.LocateLP(LP: INTEGER; VAR lineIndex: INTEGER; VAR pixel: LONGINT); $VAR s: TListScanner; (lstLnInfo: TLineInfo; (lineInfo: TLineInfo; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} (IF LP < 0 THEN ,LP := 0; (s := SELF.lineList.Scanner; (lineIndex := 0; (WHILE s.Scan(lineInfo) DO ,BEGIN ,IF LP < lineInfo.startLP THEN 0s.Done ,ELSE 0BEGIN 0lineIndex := lineIndex + 1; 0lstLnInfo := lineInfo; 0END; ,END; (IF lineIndex=0 THEN ,BEGIN ,{$IFC fParaTrace} ,IF fParaTrace THEN 0writeln(chr(7), 'LocateLP: no TLineInfo in TParaImage, lineIndex=0'); ,{$ENDC} ,lineIndex := 1; ,lineInfo := SELF.DfltLineInfo(0, 0); ,pixel := lineInfo.lineLRect.left - 1; { leave 1 pixel space before character } ,SELF.lineList.InsLast(lineInfo); ,END (ELSE ,BEGIN ,pixel := lstLnInfo.lineLRect.left + SELF.ParaTextWidth(lstLnInfo.startLP, LP-1) - 1; `{ leave 1 pixel space before character } ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TParaImage.LpWithLPt(pt: LPoint): INTEGER; $VAR lineIndex: INTEGER; (lineInfo: TLineInfo; (endLP: INTEGER; (lineLen: INTEGER; (charWid: INTEGER; (paragraph: TEditPara; (wrapMargin: INTEGER; (lastLP: INTEGER; (PROCEDURE DrawLine(obj: TObject); {This routine gets filtered after a type style change} (BEGIN ,SELF.DrawLine(lineInfo.startLP, FALSE, pt.h-lineInfo.lineLRect.left, wrapMargin, @lineLen, lastLP, endLP); (END; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} (SELF.LineWithLPt(pt, lineIndex, lineInfo); (IF pt.v < lineInfo.lineLRect.top THEN ,pt := lineInfo.lineLRect.topLeft (ELSE IF pt.v > lineInfo.lineLRect.bottom THEN ,pt := lineInfo.lineLRect.botRight (ELSE ,LRectHaveLPt(lineInfo.lineLRect, pt); (paragraph := SELF.paragraph; (wrapMargin := lengthLRect(SELF.extentLRect, h); (SELF.FilterAndDo(SELF, DrawLine); ({ endLP is now the LP of the character before the character the cursor was over} (lineLen := lineLen + lineInfo.lineLRect.left; ({ lineLen is now the x-coord of screen position of endLP (right pixel) } (endLP := MIN(endLP+1, paragraph.size); (charWid := SELF.paraTextWidth(endLP, endLP); { find width of the char under cursor } ({$IFC fParaTrace} (IF fParaTrace THEN ,writeln('LpWithLPt: endLP=', endLP:1, ' pt.h=', pt.h:1, ' lineLen=', lineLen:1, <' charWid=', charWid:1); ({$ENDC} (IF 2*(pt.h-lineLen) >= charWid THEN { pt is right of center of char } ,LpWithLPt := paragraph.fixLP(endLP+1) (ELSE { pt is left of center of char } ,LpWithLPt := paragraph.fixLP(endLP); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TParaImage.OffsetBy(deltaLPt: LPoint); $VAR s: TListScanner; (lineInfo: TLineInfo; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({&&& should make sure the results falls within view} (WITH deltaLPt DO ,BEGIN ,{$H-} OffsetLRect(SELF.extentLRect, h, v); {$H+} ,s := SELF.lineList.Scanner; ,WHILE s.Scan(lineInfo) DO 0{$H-} OffsetLRect(lineInfo.lineLRect, h, v); {$H+} ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} ${Returns width of characters in range startLP, endLP. (NOTE: startLP=endLP for width of one char)} $FUNCTION TParaImage.ParaTextWidth(startLP, endLP: INTEGER): INTEGER; $VAR styleIndex: INTEGER; (width: INTEGER; (PROCEDURE FastDraw(obj: TObject); {This routine gets filtered after a type style change} (BEGIN ,SELF.FastDrawLine(startLP, endLP, FALSE, TRUE, width, styleIndex); (END; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} (styleIndex := 1; (IF endLP < startLP THEN ,width := 0 (ELSE ,SELF.FilterAndDo(SELF, FastDraw); (ParaTextWidth := width; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TParaImage.RedrawLines(startLine: INTEGER; endLine: INTEGER); $VAR s: TListScanner; (i: INTEGER; (lineInfo: TLineInfo; (prevLineInfo: TLineInfo; (styleIndex: INTEGER; (dummy: INTEGER; (PROCEDURE FastDraw(obj: TObject); {This routine gets filtered after a type style change} (BEGIN ,SELF.FastDrawLine(lineInfo.startLP, lineInfo.lastDrawnLP, TRUE, \FALSE, dummy, styleIndex); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (PicGrpBegin; (s := SELF.lineList.Scanner; (i := 0; (endLine := Min(endLine, SELF.lineList.Size); (startLine := Max(startLine, 1); (styleIndex := 1; (WHILE s.scan(lineInfo) DO ,BEGIN ,i := i+1; ,IF i < startLine THEN {nothing} ,ELSE 0BEGIN 0IF LRectIsVisible(lineInfo.lineLRect) THEN 4BEGIN 4{$IFC fParaTrace} 4IF fParaTrace THEN 8writeln('## ReDrawLines: About to call FastDraw; i=', i:1); 4{$ENDC} 4MoveToL(lineInfo.lineLRect.left, lineInfo.lineLRect.top+lineInfo.lineAscent); 4SELF.FilterAndDo(SELF, FastDraw); 4END; 0IF i = endLine THEN 4s.Done; 0END; ,END; (PicGrpEnd; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TParaImage.SeesSameAs(image: TImage): BOOLEAN; $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (IF SELF = image THEN ,SeesSameAs := TRUE (ELSE IF NOT InClass(image, TParaImage) THEN ,SeesSameAs := FALSE (ELSE ,SeesSameAs := SELF.paragraph = TParaImage(image).paragraph; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {$S SgTxtIni} 3. "6F^9. ^T22T\ un of text each time called} o heap } agraph} AME. |DATANREL RF@l B- BP l.DATASTD  {$SetC fTraceUT := doTraceUT AND fUniversalTextTrace} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {$I libut/UUnivText2.text} {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END. {$E+} {$E ERR1.TEXT} {------------------------------------------------------------------------------------------------------------} { UUniversalText V0.3 } {------------------------------------------------------------------------------------------------------------} {$SETC ForOS := TRUE } {$DECL WithUObject} {$SETC WithUObject := TRUE} {Note: TRUE/FALSE status MUST agree with below} UNIT {$IFC WithUObject} %UTKUniversalText %{$ELSEC} %UUniversalText %{$ENDC}; {$DECL IsIntrinsic} {$SETC IsIntrinsic := TRUE} {$SETC WithUObject := TRUE} {Note: TRUE/FALSE status MUST agree with above} {$IFC IsIntrinsic} INTRINSIC; {$ENDC} {$IFC NOT WithUObject} ${$SETC LibraryVersion := 30 } { 10 = 1.0 libraries; 13 = 1.3 libraries; 20 = Pepsi, 30 = Spring, etc. } {$ENDC} INTERFACE USES {$IFC WithUObject} ${$U libtk/UObject} UObject, ${$SETC fTrce := fTrace} {$ENDC} ${$U libsm/UnitStd.obj } UnitStd, ${$U libsm/UnitHz.obj } UnitHz, {$IFC NOT WithUObject} ${$U libpl/UClascal} UClascal, {Will be in PASLIB in Spring} ${$U libqd/Storage.obj } Storage, {$ENDC} {$IFC LibraryVersion <= 20} ${$U libfm/FontMgr.obj } FontMgr, ${$U libqd/QuickDraw.obj } QuickDraw, {$ELSEC} ${$U libqd/QuickDraw.obj } QuickDraw, ${$U libfm/FontMgr.obj } FontMgr, {$ENDC} ${$U -#BOOT-SysCall } Syscall, ${$U libpm/PMDecl.obj } PMDecl, ${$U libpr/PrStdInfo.obj } PrStdInfo, ${$U libsu/UnitFmt.obj } UnitFmt, ${$U libsu/UnitCS.obj } UnitCS, ${$U libwm/Events.obj } Events, ${$U libsu/Scrap.obj } Scrap; {$DECL fUniversalTextTrace} {$IFC NOT WithUObject} ${$DECL fDebugMethods} ${$SETC fDebugMethods := FALSE} {Must be FALSE} ${$DECL fDbgObject} ${$DECL fTrce} ${$SETC fTrce := FALSE} {Must be FALSE} ${$SETC fDbgObject := FALSE} {Set to FALSE for final libraries} {$ENDC} {$SETC fUniversalTextTrace := fTrce} {Normal} {$DECL PasteTrace} {Generates READLN asking for tracing during Write UT} {$SETC PasteTrace := FALSE} TYPE {$IFC NOT WithUObject} $S255 = STRING[255]; $THeap = Ptr; {alias for THz} $TClass = Ptr; {alias for TPSliceTable in UClascal} $TCollecHeader = RECORD (classPtr: TClass; (size: LONGINT; {number of real elements, not counting the hole} (dynStart: INTEGER; {bytes from the class ptr to the dynamic data; MAXINT if none allowed} (holeStart: INTEGER; {0 = at the beginning, size = at the end; MAXINT = none allowed} (holeSize: INTEGER; {measured in MemberBytes units} (holeStd: INTEGER; {if the holeSize goes to 0, how much to grow the collection by} (END; $TFastString = RECORD {only access ch[i] when hole is at end & TString is not subclassed} (header: TCollecHeader; (ch: PACKED ARRAY[1..32740] OF CHAR; (END; $TPFastString = ^TFastString; $THFastString = ^TPFastString; $TUTObject = SUBCLASS OF NIL (FUNCTION {TUTObject.}CREATE(heap: THeap): TUTObject; ABSTRACT; (FUNCTION {TUTObject.}Heap: THeap; {which heap it is in} (PROCEDURE {TUTObject.}FreeObject; DEFAULT; {frees just the object, not its contents} (PROCEDURE {TUTObject.}Free; DEFAULT; {frees the object and its contents} (FUNCTION {TUTObject.}Class: TClass; (END; $TUTCollection = SUBCLASS OF TUTObject &{Variables} (size: LONGINT; {number of real elements, not counting the hole} (dynStart: INTEGER; {bytes from the class ptr to the dynamic data} (holeStart: INTEGER; {0 means hole at the beginning, size means hole at the end} (holeSize: INTEGER; {measured in MemberBytes units} (holeStd: INTEGER; {if the holeSize goes to 0, how much to grow the collection by} (FUNCTION {TCollection.}CREATE(object: TUTObject; heap: THeap; initialSlack: INTEGER): TUTCollection; (FUNCTION {TCollection.}AddrMember(i: LONGINT): LONGINT; (FUNCTION {TCollection.}MemberBytes: INTEGER; ABSTRACT; (PROCEDURE {TCollection.}EditAt(atIndex: LONGINT; deltaMembers: INTEGER); (PROCEDURE {TCollection.}InsManyAt(i: LONGINT; otherCollection: TUTCollection; index, howMany: LONGINT); (PROCEDURE {TCollection.}ResizeColl(membersPlusHole: INTEGER); (PROCEDURE {TCollection.}ShiftColl(afterSrcIndex, afterDstIndex, howMany: INTEGER); (PROCEDURE {TCollection.}StartEdit(withSlack: INTEGER); (PROCEDURE {TCollection.}StopEdit; (END; $TUTArray = SUBCLASS OF TUTCollection (recordBytes: INTEGER; (FUNCTION {TArray.}CREATE(object: TUTObject; heap: THeap; initialSlack, bytesPerRecord: INTEGER) D: TUTArray; (FUNCTION {TArray.}MemberBytes: INTEGER; OVERRIDE; (FUNCTION {TArray.}At(i: LONGINT): Ptr; DEFAULT; (PROCEDURE {TArray.}InsAt(i: LONGINT; pRecord: Ptr); DEFAULT; (PROCEDURE {TArray.}InsLast(pRecord: Ptr); (PROCEDURE {TArray.}DelAll; (PROCEDURE {TArray.}DelAt(i: LONGINT); DEFAULT; (PROCEDURE {TArray.}DelManyAt(i, howMany: LONGINT); DEFAULT; (PROCEDURE {TArray.}PutAt(i: LONGINT; pRecord: Ptr); (END; $TUTString = SUBCLASS OF TUTCollection (FUNCTION {TString.}CREATE(object: TUTObject; heap: THeap; initialSlack: INTEGER): TUTString; (FUNCTION {TString.}At(i: LONGINT): CHAR; (FUNCTION {TString.}MemberBytes: INTEGER; OVERRIDE; (PROCEDURE {TString.}ToPAOCAt(i, howMany: LONGINT; pPackedArrayOfCharacter: Ptr); (PROCEDURE {TString.}InsAt(i: LONGINT; character: CHAR); (PROCEDURE {TString.}InsPAOCAt(i: LONGINT; pPackedArrayOfCharacter: Ptr; howMany: LONGINT); (PROCEDURE {TString.}DelAt(i: LONGINT); (PROCEDURE {TString.}DelManyAt(i, howMany: LONGINT); (PROCEDURE {TString.}DelAll; (END; {$ENDC} $TEnumLevelOfGranularity = (UTCharacters, UTParagraphs); $TLevelOfGranularity = SET OF TEnumLevelOfGranularity; $TCharDescriptor = RECORD { character descroptor record } ,font: INTEGER; { font number } ,face: {$IFC LibraryVersion <= 20}TSeteface{$ELSEC}style{$ENDC}; { formating } ,superscript: -128..127; { number of bits to superscript } ,keepOnSamePage: BOOLEAN; ,END; $TTabTypes = (qLeftTab, qCenterTab, qRightTab, qPeriodTab, qCommaTab); $TTabFill = (tNoFill, tDotFill, tHyphenFill, tUnderLineFill); $TParaTypes = (qLeftPara, qCenterPara, qRightPara, qJustPara); $TTabDescriptor = RECORD ,position: INTEGER; {Location of the tab} ,fillBetweenTabs: TTabFill; {Fill character for the tab} ,tabType: TTabTypes; {Type of tab} ,END; $TParaDescriptor = RECORD ,paragraphStart: BOOLEAN; { TRUE if the beginning of the run is also the beginning of a paragraph} {$IFC WithUObject} ,additionalChrInParagraph: INTEGER; {$ENDC} ,firstLineMargin: INTEGER; {Left margin of first line} ,bodyMargin: INTEGER; {Left margin of subsequent lines} ,rightMargin: INTEGER; {Right margin} ,paraLeading: INTEGER; {Paragraph leading} ,lineSpacing: 0..63; {Inter-line spacing } {$IFC WithUObject} ,tabTable: TArray {OF TTabDescriptor}; { table of tabs } {$ELSEC} ,tabTable: TUTArray {OF TTabDescriptor}; { table of tabs } {$ENDC} ,paraType: TParaTypes; {Paragraph adjustment } ,hasPicture: BOOLEAN; {Is there a picture avaible for this paragraph?} ,END; {$IFC WithUObject} $TTKUnivText = SUBCLASS OF TOBJECT {$ELSEC} $TUnivText = SUBCLASS OF TUTObject {$ENDC} (paragraphDescriptor: TParaDescriptor; (characterDescriptor: TCharDescriptor; (maxDataSize: INTEGER; {$IFC WithUObject} (data: TString; {$ELSEC} (data: TUTString; {$ENDC} (itsOurTString: BOOLEAN; {$IFC WithUObject} (FUNCTION {TTKUnivText.}CREATE(object: TObject; EitsHeap: THeap; EitsTString: TString; EitsDataSize: INTEGER) : TTKUnivText; {$ELSEC} (FUNCTION {TUnivText.}CREATE(object: TUTObject; EitsHeap: THeap; EitsTString: TUTString; EitsDataSize: INTEGER) : TUnivText; {$ENDC} (PROCEDURE {TUnivText.}Free; OVERRIDE; (PROCEDURE {TUnivText.}RunToStream; (PROCEDURE {TUnivText.}StreamToTRun; (PROCEDURE {TUnivText.}TabTableToArgTbd; (PROCEDURE {TUnivText.}ArgTbdToTabTable; (END; {$IFC WithUObject} $TTKReadUnivText = SUBCLASS OF TTKUnivText {$ELSEC} $TReadUnivText = SUBCLASS OF TUnivText {$ENDC} {$IFC WithUObject} (buffer: TString; {$ELSEC} (buffer: TUTString; {$ENDC} (columnCount: INTEGER; (dataBeforeTab: BOOLEAN; {$IFC WithUObject} (FUNCTION {TReadUnivText.}CREATE(object: TObject; IitsHeap: THeap; IitsTString: TString; IitsDataSize: INTEGER; ILevelOfGranularity: TLevelOfGranularity) q: TTKReadUnivText; {$ELSEC} (FUNCTION {TReadUnivText.}CREATE(object: TUTObject; IitsHeap: THeap; IitsTString: TUTString; IitsDataSize: INTEGER; ILevelOfGranularity: TLevelOfGranularity) q: TReadUnivText; {$ENDC} (PROCEDURE {TReadUnivText.}Free; OVERRIDE; (PROCEDURE {TReadUnivText.}ReadRun; { Returns one run of text each time called } (PROCEDURE {TReadUnivText.}Restart; { Resets the object to read from the begining } (PROCEDURE {TReadUnivText.}ScanTable(VAR rows, PtabColumns, PtabStopColumns: INTEGER); D{ Returns number of rows and colums of scrap if a valid table } (FUNCTION {TReadUnivText.}ReadField( maxFieldSize: INTEGER; LVAR fieldOverflow: BOOLEAN; LVAR fieldTerminator: CHAR; LVAR tabType: TTabTypes) c: BOOLEAN; P{ Returns one field of text each time called } (FUNCTION {TReadUnivText.}ReadLine( maxLineSize: INTEGER; KVAR lineOverflow: BOOLEAN; KVAR lineTerminator: CHAR) d: BOOLEAN; P{ Returns one line of text each time called } (FUNCTION {TReadUnivText.}GetParaPicture(heap: THeap) d: PicHandle; P{ Copies the picture for the current paragraph into heap } (END; {$IFC WithUObject} $TTKWriteUnivText = SUBCLASS OF TTKUnivText {$ELSEC} $TWriteUnivText = SUBCLASS OF TUnivText {$ENDC} {$IFC WithUObject} (FUNCTION {TWriteUnivText.}CREATE(object: TObject; JitsHeap: THeap; JitsTString: TString; JitsDataSize: INTEGER) _: TTKWriteUnivText; {$ELSEC} (FUNCTION {TWriteUnivText.}CREATE(object: TUTObject; JitsHeap: THeap; JitsTString: TUTString; JitsDataSize: INTEGER) _: TWriteUnivText; {$ENDC} (PROCEDURE {TWriteUnivText.}FillParagraph; {Writes one run of text each time called} (END; {$IFC NOT WithUObject} $FUNCTION NewUTObject(heap: THeap; itsClass: TClass): TUTObject; {$ENDC} {$IFC fUniversalTextTrace} VAR $fPrintSecrets: BOOLEAN; {$ENDC} IMPLEMENTATION {$IFC fDbgOk} {$R+} {$ELSEC} {$R-} {$ENDC} {$IFC fSymOk} {$D+} {$ELSEC} {$D-} {$ENDC} {$SETC doTraceUT := FALSE} {$SetC fTraceUT := doTraceUT AND fUniversalTextTrace} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {$I libut/UUnivText2.text} {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END. 3. "6F^5D!$ǐ^D&&; UNIT XFER; {Copyright 1983, 1984 Apple Computer, Inc.} ; {changed 01/20/83 2026 Added EqualBytes ; {changed 01/05/83 2149 Moved several routines to CLASLIB so they can go into PASLIB; ; Here we still have (in SgCLAres): ; LIntDivLint, LIntDivInt, LIntMulInt, LIntAndLInt, LIntOrLInt, ; XferLeft, XferRight, RotatePattern, EnterLisabug} ; {changed 01/01/83 2000 Added %_JmpTo, %_ExitCaller, %_ExitFunny, %_CallMethod, %_Super; ; Replaced IsJsr by %_NextMethod; ; Deleted XPNewMethod; ; Changed Segment from SgABCres to SgCLAres & added some SgCLAini procedures; ; Added $D information conditioned on DEBUGF flag; ; (Note: SP=A7)} ; {changed 09/13/83 1115 RELEASE TK7D TO TOOLKIT TEAM} ; {changed 08/30/83 2000 RELEASE TK7C TO TOOLKIT TEAM} ;============================================================================================= DEBUGF .EQU 1 ; 1 to include $D+ info, 0 to exclude it ;============================================================================================= (.MACRO HEAD *.IF DEBUGF ,LINK A6,#0 ; These two instructions form a slow no-op ,MOVE.L (SP)+,A6 *.ENDC (.ENDM (.MACRO TAIL *.IF DEBUGF ,UNLK A6 ,RTS ,.ASCII %1 *.ENDC (.ENDM ;============================================================================================= (.SEG 'SgXFER' ;============================================================================================= (.PROC XFERLEFT (HEAD ; PROCEDURE XferLeft(source, dest: TP; nBytes: INTEGER); ; ; uses A0,A1,D0,D1 ; (MOVE.L (SP)+,D1 ; POP RETURN ADDRESS (MOVE.W (SP)+,D0 ; D0 := NBYTES (MOVE.L (SP)+,A1 ; A1 := DEST (MOVE.L (SP)+,A0 ; A0 := SOURCE (MOVE.L D1,-(SP) ; PUSH RETURN ADDRESS FOR RTS (SUB.W #1,D0 ; DECREMENT NBYTES (BLT.S RTSLEFT ; NBYTES <= 0, SO EXIT XFER MOVE.B (A0)+,(A1)+ (DBF D0,XFER RTSLEFT RTS (TAIL 'XFERLEFT' ;============================================================================================= (.PROC XFERRIGH (HEAD ; PROCEDURE XferRight(source, dest: TP; nBytes: INTEGER); ; ; uses A0,A1,D0,D1 ; (MOVE.L (SP)+,D1 ; POP RETURN ADDRESS (MOVE.W (SP)+,D0 ; D0 := NBYTES (MOVE.L (SP)+,A1 ; A1 := DEST (MOVE.L (SP)+,A0 ; A0 := SOURCE (MOVE.L D1,-(SP) ; PUSH RETURN ADDRESS FOR RTS (TST.W D0 ; TEST NBYTES (BLE.S RTSRIGH ; NBYTES <= 0, SO EXIT (ADDA.W D0,A0 ; START AT RIGHT END (ADDA.W D0,A1 (SUB.W #1,D0 ; DECREMENT NBYTES XFER MOVE.B -(A0),-(A1) (DBF D0,XFER RTSRIGH RTS (TAIL 'XFERRIGH' ;============================================================================================= (.PROC EqualBytes (HEAD ; PROCEDURE EqualBytes(source, dest: TP; nBytes: INTEGER); ; ; uses A0,A1,D0,D1 ; (MOVE.L (SP)+,D1 ; POP RETURN ADDRESS (MOVE.W (SP)+,D0 ; D0 := NBYTES (MOVE.L (SP)+,A1 ; A1 := DEST (MOVE.L (SP)+,A0 ; A0 := SOURCE (MOVE.L D1,-(SP) ; PUSH RETURN ADDRESS FOR RTS (MOVE.B #1,4(SP) ; RETURN TRUE UNLESS PROVEN UNEQUAL (SUB.W #1,D0 ; DECREMENT NBYTES (BLT.S RTSEQUL ; NBYTES <= 0, SO EXIT XFER MOVE.B (A0)+,D1 (CMP.B (A1)+,D1 (BNE UNEQUL (DBF D0,XFER RTSEQUL RTS UNEQUL CLR.B 4(SP) ; RETURN FALSE (RTS (TAIL 'EQUALBYT' ;============================================================================================= (.PROC ROTATEPA (HEAD ; PROCEDURE RotatePattern(pInPat, pOutPat: ^Pattern; dh, dv: LONGINT); ; ; uses A0-A2,D0-D4 ; (MOVEM.L (SP)+,D0-D2/A0-A1 ; D0 := RETURN ADDRESS, D1 := dv; D2 := dh, A0 := pOutPat, A1 := pInPat (MOVE.L D0,-(SP) ; PUSH RETURN ADDRESS FOR RTS (MOVEM.L A2/D3-D4,-(SP) ; Save A2,D3,D4 (AND.L #7,D2 ; dh := dh MOD 8 ; ***** FOR D3 := 7 DOWNTO 0 DO ***** (MOVE.W #7,D3 ; Loop count ; ***** BEGIN ***** RLOOP MOVE.B $00(A1,D3.W),D0 ; D0 := next byte in inPat (ROL.B D2,D0 ; Rotate byte in D0 left by D2 (dh) (MOVE.W D3,D4 (SUB.W D1,D4 (AND.W #7,D4 ; D4 := (D3 - dv) MOD 8 (MOVE.B D0,$00(A0,D4.W) ; next byte in outPat := D0 (DBF D3,RLOOP ; ***** END; ***** (MOVEM.L (SP)+,A2/D3-D4 ; Restore A2,D3,D4 (RTS (TAIL 'ROTATEPA' ;============================================================================================= (.FUNC LINTDIVL (HEAD ; FUNCTION LIntDivLint(i, j: LONGINT): LONGINT; ; ; uses A0,D0,D1 ; (.REF LD (MOVE.L (SP)+,A0 ; Return address (MOVE.L (SP)+,D0 ; D0 := j (MOVE.L (SP)+,D1 ; D1 := i CHEK CMP.L #32767,D0 ; Is j too long to use LIntDivInt? (BGT TOOLONG ; Too big (CMP.L #-32768,D0 (BLT TOOLONG ; Too small (JMP LD ; Can't BGT LD in this assembler TOOLONG ASR.L #1,D0 (ASR.L #1,D1 (JMP CHEK (TAIL 'LINTDIVL' ;============================================================================================= (.FUNC LINTDIVI (HEAD ; FUNCTION LIntDivInt(i: LONGINT; j: INTEGER): LONGINT; ; ; uses A0,D0,D1,D2 ; (.DEF LD (MOVE.L (SP)+,A0 ; Return address (MOVE.W (SP)+,D0 ; D0 := j (MOVE.L (SP)+,D1 ; D1 := i LD CMP.W #1,D0 ; IF j = 1, return i (BEQ DV1 (MOVE.L D1,-(SP) ; Push i as LONGINT (MOVE.W D0,-(SP) ; Push j as INTEGER (CLR.L D1 (TST.W (SP) ; If j is negative, negate both (BGE JPOS (NEG.W (SP) ; negate j (NEG.L 2(SP) ; negate i JPOS TST.L 2(SP) ; If i is negative, negate it but remember it was (SMI D2 ; D2 := (i < 0) (BGE IPOS (NEG.L 2(SP) ; negate i IPOS MOVE.W 2(SP),D1 ; Divide MSW of i by j (DIVU (SP),D1 (MOVE.L D1,D0 ; Remainder becomes MSW of next Divide (MOVE.W 4(SP),D0 ; Divide ((preceding remainder) concat (LSW of i)) by j (DIVU (SP)+,D0 ; Pop j at the same time (SWAP D1 ; Quotient of first divide is MSW of result (MOVE.W D0,D1 ; Quotient of second divide is LSW of result (TST.B D2 ; Was i negative? (BEQ DUN (NEG.L D1 DUN ADD.L #4,SP ; Popeye DV1 MOVE.L D1,(SP) ; Store function result (JMP (A0) ; Return (TAIL 'LINTDIVI' ;============================================================================================= (.FUNC LINTMULI (HEAD ; FUNCTION LIntMulInt(i: LONGINT; j: INTEGER): LONGINT; ; ; uses A0,D0,D1,D2 ; (MOVE.L (SP)+,A0 ; Return address (MOVE.W (SP)+,D1 ; D1 := j (MOVE.L (SP)+,D0 ; D0 := i (CMP.W #1,D1 ; IF j = 1, return i (BEQ MU1 (MOVE.L D2,-(SP) ; Save D2 (MOVE.W D0,D2 ; D2 := LSW of I (SWAP D0 ; D0 := MSW of I (MULU D1,D0 ; D0 := D0 * j (LSL.L #8,D0 (LSL.L #8,D0 (MULU D1,D2 (ADD.L D2,D0 ; D0 := product (MOVE.L (SP)+,D2 ; restore D2 MU1 MOVE.L D0,(SP) ; Store function result (JMP (A0) ; Return (TAIL 'LINTMULI' ;============================================================================================= (.FUNC LINTANDL (HEAD ; FUNCTION LIntAndLInt(i, j: LONGINT): LONGINT; ; ; uses A0,D0 ; (MOVE.L (SP)+,A0 ; Return address (MOVE.L (SP)+,D0 ; D0 := j (AND.L (SP)+,D0 ; D0 := i AND j (MOVE.L D0,(SP) ; Store function result (JMP (A0) ; Return (TAIL 'LINTANDL' ;============================================================================================= (.FUNC LINTORLI (HEAD ; FUNCTION LIntOrLInt(i, j: LONGINT): LONGINT; ; ; uses A0,D0 ; (MOVE.L (SP)+,A0 ; Return address (MOVE.L (SP)+,D0 ; D0 := j (OR.L (SP)+,D0 ; D0 := i OR j (MOVE.L D0,(SP) ; Store function result (JMP (A0) ; Return (TAIL 'LINTORLI' ;============================================================================================= (.FUNC LINTXORL (HEAD ; FUNCTION LIntXorLInt(i, j: LONGINT): LONGINT; ; ; uses A0,D0, D1 ; (MOVE.L (SP)+,A0 ; Return address (MOVE.L (SP)+,D0 ; D0 := j (MOVE.L (SP)+,D1 ; D1 := i (EOR.L D1,D0 ; D0 := i XOR j (MOVE.L D0,(SP) ; Store function result (JMP (A0) ; Return (TAIL 'LINTXORL' ;============================================================================================= (.PROC ENTERLIS (HEAD ; PROCEDURE EnterLisabug; (TRAP #0 (RTS (TAIL 'ENTERLIS' ;============================================================================================= (.END 3. "6F^9x D!$ǐ^  0JKLSE IF isWordSelection THEN 0IF needSpRight THEN 4BEGIN 4newPara.InsertOneChar(' ', newLP); 4newLP (bpJF̓v̓zpJ@̓zFnpce}EP;(bpJ̓R̼D̓v̓zFFFpp|F.FPFP̍̓zÆFFxpJ@n3nĀZ̼DxFPF̍n̓zFFxFF.@ppJŊn3nUNIT UFixUText; {This unit fixes a bug with UText, where pasting universal text containing a 14 Point or $20 Pitch font would crash with a check range error, accessing the uvFont array. The $only access was made in TInsertionPoint.InsertText. To fix the problem we subclass $TInsertionPoint.InsertText, but install a pointer to the revised method in TInsertionPoint's $method table.} {$SETC CalcNumbers := FALSE} {IF TRUE, calculate level/method numbers, else use CONSTs} {$SETC Debug := FALSE} INTERFACE {$E ERRORS} {$E+} USES ${$U LIBPL/UCLASCAL} UClascal, ${$U UObject} UObject, ${$U QuickDraw} QuickDraw, ${$U UDraw} UDraw, ${$U UABC} UABC, ${$U UUnivText} UTKUniversalText, ${$U UText} UText; TYPE $TFixInsertionPoint = SUBCLASS OF TInsertionPoint (FUNCTION TFixInsertionPoint.CREATE: TFixInsertionPoint; ABSTRACT; (PROCEDURE TFixInsertionPoint.InsertText(text: TText; isParaSelection: BOOLEAN; TisWordSelection: BOOLEAN; TuniversalText: BOOLEAN); OVERRIDE; (END; IMPLEMENTATION {$IFC fSymOK AND Debug} {$D+} {$ELSEC} {$D-} {$ENDC} {$IFC fDbgOK AND Debug} {$R+} {$ELSEC} {$R-} {$ENDC} VAR uvFont: ARRAY[1..19] OF TFontRecord; $cFixInsertionPoint: TClass; {$S FixText1} {Caller and HackMethodTable must be in the same segment} {$IFC CalcNumbers} PROCEDURE Caller; $VAR ip: TInsertionPoint; (t: TText; BEGIN $ip.InsertText(t, TRUE, TRUE, TRUE); END; {$ENDC} PROCEDURE HackMethodTables; {$IFC CalcNumbers AND DEBUG} $LABEL 1,100; {$ELSEC} ${$IFC CalcNumbers} $LABEL 100; ${$ENDC} ${$IFC Debug} $LABEL 1; ${$ENDC} {$ENDC} {$IFC NOT CalcNumbers} $CONST (levNum = 6; (methNum = 2; {$ENDC} $TYPE (TMethodArray = ARRAY [1..256] OF LONGINT; (TPMethodArray = ^TMethodArray; (TSliceTable = ARRAY [0..255] OF TPMethodArray; (TPSliceTable = ^TSliceTable; $VAR myProc: LONGINT; ({$IFC CalcNumbers} (pc: TpInteger; (wd: INTEGER; (levNum: INTEGER; (methNum: INTEGER; ({$ENDC} (pSliceTable: TpSliceTable; BEGIN {$IFC Debug} 1: GOTO 1; {$ENDC} {$IFC CalcNumbers} ${Find out the method # & level # for TInsertionPoint.InsertText} $pc := TpInteger(@Caller); $WHILE ORD(pc) <= ORD(@HackMethodTables) DO (BEGIN (wd := pc^; (pc := TpInteger(ORD(pc)+2); (IF wd = $4E95 THEN {JSR (A5)} ,BEGIN ,wd := pc^; {get level/method # as an integer} ,levNum := wd DIV 256; {these 2 statements only work for <128 levels} ,methNum := wd MOD 256; {$IFC Debug} ,WriteLn(levNum, methNum); {***} {$ENDC} ,GOTO 100; ,END; (END; $HALT; {did not find the method call} 100: {$ENDC} $pSliceTable := TpSliceTable(cFixInsertionPoint); $myProc := pSliceTable^[levNum]^[methNum]; ,{The superclass pointers have not been installed yet, so need to use the arrays in UClascal.} $pSliceTable := TpSliceTable(pSTables^[pClasses^[numClasses].superIndex]); $pSliceTable^[levNum]^[methNum] := myProc; END; METHODS OF TFixInsertionPoint; {$S FixText2} $PROCEDURE TFixInsertionPoint.InsertText(text: TText; isParaSelection: BOOLEAN; isWordSelection: BOOLEAN; tuniversalText: BOOLEAN); $VAR s: TListScanner; (prevPara: TEditPara; (newPara: TEditPara; (aParagraph: TEditPara; (newLP: INTEGER; (textImage: TTextImage; (insertIt: BOOLEAN; (done: BOOLEAN; (newParaImage: TParaImage; (paraIndex: LONGINT; (delta: INTEGER; (numParas: INTEGER; (needSpRight: BOOLEAN; ({$IFC fUseUnivText} (readUnivText: TTKReadUnivText; (univPara: TEditPara; (univFormat: TParaFormat; ({$ENDC} (PROCEDURE StartPaste; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,IF universalText THEN 0BEGIN 0{$IFC fUseUnivText} 0univFormat := TParaFormat.CREATE(NIL, SELF.Heap, SELF.textImage.text.styleSheet); 0univPara := textImage.NewEditPara(0, prevPara.format); 0readUnivText := TTKReadUnivText.CREATE(NIL, SELF.Heap, NIL, 512, \[UTCharacters, UTParagraphs]); 0numParas := 0; 0{$ENDC} 0END ,ELSE 0BEGIN 0numParas := text.paragraphs.size; 0s := text.paragraphs.Scanner; 0END; ,{$IFC fTrace}EP;{$ENDC} (END; (PROCEDURE EndPaste; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,IF universalText THEN 0BEGIN 0{$IFC fUseUnivText} 0univPara.Free; 0readUnivText.Free; 0{$ENDC} 0END; ,{$IFC fTrace}EP;{$ENDC} (END; (FUNCTION GetParagraph(VAR paragraph: TEditPara): BOOLEAN; (VAR currPos: INTEGER; ,done: BOOLEAN; ,runSize: INTEGER; ,wasSomeText: BOOLEAN; ,ch: CHAR; ,typeStyle: TTypeStyle; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,If universalText THEN 0BEGIN 0{$IFC fUseUnivText} 0univPara.ReplPString(0, univPara.Size, NIL); 0currPos := 0; 0wasSomeText := FALSE; 0done := FALSE; 0REPEAT 4readUnivText.ReadRun; 4runSize := readUnivText.data.size; 4IF runSize > 0 THEN 8BEGIN 8IF NOT wasSomeText THEN  NIL) OR universalText THEN ,SELF.ChangeText(InsText, Adjust); ({$IFC fTrace}EP;{$ENDC} $END; {$S FixText1} BEGIN $cFixInsertionPoint := THISCLASS; $HackMethodTables; $uvFont[4].fontFamily := famModern; $uvFont[5].fontFamily := famModern; $uvFont[6].fontFamily := famModern; $uvFont[7].fontFamily := famModern; $uvFont[8].fontFamily := famModern; $uvFont[9].fontFamily := famModern; $uvFont[10].fontFamily := famClassic; $uvFont[11].fontFamily := famClassic; $uvFont[12].fontFamily := famClassic; $uvFont[13].fontFamily := famClassic; $uvFont[14].fontFamily := famClassic; $uvFont[15].fontFamily := famModern; {added} $uvFont[16].fontFamily := famClassic; {added} $uvFont[19].fontFamily := famModern; {added} $uvFont[4].fontSize := 5; $uvFont[5].fontSize := 7; $uvFont[6].fontSize := 8; $uvFont[7].fontSize := 2; $uvFont[8].fontSize := 3; $uvFont[9].fontSize := 4; $uvFont[10].fontSize := 5; $uvFont[11].fontSize := 7; $uvFont[12].fontSize := 8; $uvFont[13].fontSize := 3; $uvFont[14].fontSize := 6; $uvFont[15].fontSize := 6; {added} $uvFont[16].fontSize := 6; {added} $uvFont[19].fontSize := 1; {added} END; END. 3. "6F^5D!$ǐ^$EXEC {Assemble a module } {filename build/assemb.text} $ ${ %0 -- pathname of the module to assemble} ${ %1 -- (optional) pathname of the resulting object file. Default name is %0} ${ %2 -- (optional) segment name for the resulting object file. Default is 'blank' segment} $ $IF %0='' THEN #$WRITE 'File To Assemble? ' #$READLN %0 #$IF %1='' THEN &$WRITE "Name For Object File [ For %0]? " &$READLN %1 &$IF %2='' THEN )$WRITE 'Segment Name [ For Blank Segment]? ' )$READLN %2 &$ENDIF #$ENDIF $ENDIF $DEFAULT %1 to %0 A{ssemble}%0 {source file} 9{no listing file} %1 {object file} $IF %2<>'' THEN #R{un}changeseg {re-assign segmentation (optional)} #%1 #y%2 $ENDIF $ENDEXEC 3. "6F^9DED!$ǐ^tKblib]? ' ic.lib} TD3. "6F^$EXEC {Compile and Code Generate a Pascal Unit} {filename build/comp.text} $ ${ %0 -- pathname of the unit to compile} ${ %1 -- (optional) pathname of the resulting object file. Defaults to %0} ${ Destroys file 'temp/c.i'} ${ %2 -- (optional) pathname of intrinsic.lib. Defaults to -#boot-intrinsic.lib} $ $IF %0='' THEN #$WRITE 'File To Compile? ' #$READLN %0 #$IF %1='' THEN &$WRITE "Name For Object File [ For %0]? " &$READLN %1 &$IF %2='' THEN )$WRITE 'Name Of Intrinsic.lib [ For -#boot-intrinsic.lib]? ' )$READLN %2 &$ENDIF #$ENDIF $ENDIF $DEFAULT %1 TO %0 $DEFAULT %2 TO '-#boot-intrinsic.lib' P{ascal Compile}?{option flag} %2 {intrinsic.lib} %0 {source file} H{no listing file} %1 {object file} $ENDEXEC KbA TK Sources 4̆V{t̆^K :a$kTk\:)$ "#." #"##%& ! .3. "6F^9 S|B-N^""-L&-----------------'); LF.currStyleIndex:1); {Text Selections and Commands} END. 4IF currIndex <= textSelection.textRange.lastIndex THEN 8BEGIN 8currLP := 0; 8currStyleIndex := 1; 8{$H-} 8currPara := TEditPara(SELF.textSelection.textImage.text.paragraphs.At( \SELF.currIndex)); 8{$H+} 8currTStyles := currPar{UText3} {TStyleSheet, TText, TTextImage, TTextView, TTextWriteUnivText} {changed 05/11/84 1135 Changed TTextImage.InvalAll to call panel.InvalLRect} {changed 04/26/84 1308 Changed TTextWriteUnivText.FillRun to TTextWriteUnivText.FillParagraph} {changed 04/25/84 1250 Changed FilterAndDo calls back to filtering TParaImage for Compugraphic} {changed 04/25/84 1135 Do same for TText.MarkChanged as for HiliteParagraphs below} {changed 04/24/84 1637 Make TText.HiliteParagraphs use selection's textImage to call HiliteText} {changed 04/20/84 1102 Modified TTextImage.ImageWith so that if it finds an image whose endLP equals  NIL THEN { OR } ,SELF.paragraphs.FreeObject; {Just Free the list} (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TText.ChangeSelInOtherPanels(textSelection: TTextSelection); (PROCEDURE ChngPanelSel(obj: TObject); (VAR textImage: TTextImage; ,selection: TSelection; ,panel: TPanel; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,textImage := TTextImage(obj); ,panel := textImage.view.panel; ,selection := panel.selection; ,{We only unhighlight and replace the last non-NIL coSelection. In most cases, where -there is no coSelection, we unhighlight and replace the panel selection and -everything is hunky-dory} ,WHILE selection.coSelection <> NIL DO 0selection := selection.coSelection; ,{Don't change selection in same panel} ,IF selection.panel <> textSelection.panel THEN 0selection := selection.FreedAndReplacedBy(textSelection.ReplicateForOtherPanel(textImage)); ,{$IFC fTrace}EP;{$ENDC} (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.txtImgList.size > 1 THEN ,SELF.txtImgList.Each(ChngPanelSel); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TText.DelPara(delPara: TEditPara; fFree: BOOLEAN); $VAR (* (i: INTEGER; (numImages: INTEGER; (*) (s: TListScanner; (paraImage: TParaImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ((* (numImages := delPara.NumImages; (FOR i := 1 TO numImages DO (*) (s := delPara.images.Scanner; (WHILE s.Scan(paraImage) DO ,BEGIN ,(* ,paraImage := delPara.images[1]; ,*) ,paraImage.textImage.imageList.DelObject(paraImage, FALSE); ,s.Delete(FALSE); ,paraImage.Free; ,END; ({NOTE: We do not delete the paragraph from our own paragraphs list because this is usually /called while scanning that list and we would screw up its scanner if we removed the /paragraph from the list} (IF fFree THEN ,delPara.free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TText.Draw; (PROCEDURE DrawInImage(obj: TObject); (VAR textImage: TTextImage; ,PROCEDURE DrawOnPad; ,BEGIN 0textImage.Draw; ,END; (BEGIN ,textImage := TTextImage(obj); ,textImage.view.panel.OnAllPadsDo(DrawOnPad) (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.txtImgList.Each(DrawInImage); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TText.HiliteRange(highTransit: THighTransit; textRange: TTextRange; wholePara: BOOLEAN); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (WITH textRange DO ,{$H-} ,SELF.HiliteParagraphs(highTransit, firstIndex, firstLP, lastIndex, lastLP, wholePara); ,{$H+} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} ${ TText.HiliteParagraphs tells each text image to hilite its panel's text selection on each pad. It &calls TTextImage.HiliteText which assumes we are already focussed on a pad } $PROCEDURE TText.HiliteParagraphs(highTransit: THighTransit; PstartIndex: LONGINT; startLP: INTEGER; PendIndex: LONGINT; endLP: INTEGER; wholePara: BOOLEAN); (PROCEDURE HiliteInImage(obj: TObject); (VAR selection: TSelection; ,textImage: TTextImage; ,PROCEDURE HiliteOnPad; ,BEGIN 0textImage.HiliteText(highTransit, startIndex, startLP, endIndex, endLP, wholePara); ,END; (BEGIN ,selection := TTextImage(obj).view.panel.selection; ,WHILE selection.coSelection <> NIL DO 0selection := selection.coSelection; ,textImage := TTextSelection(selection).textImage; ,textImage.view.panel.OnAllPadsDo(HiliteOnPad); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.txtImgList.Each(HiliteInImage); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} $FUNCTION TText.DfltTextImage(view: TView; imageLRect: LRect; imgIsGrowable: BOOLEAN): TTextImage; $VAR textImage: TTextImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (textImage := TTextImage.CREATE(NIL, SELF.Heap, view, imageLRect, SELF, imgIsGrowable); (SELF.txtImgList.InsLast(textImage); (SELF.paragraphs.InsLast(textImage.NewEditPara(0, TParaFormat(SELF.styleSheet.formats.First))); (SELF.RecomputeImages; (DfltTextImage := textImage; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TText.InsParaAfter(existingPara: TEditPara; newPara: TEditPara); (PROCEDURE InsertPara(obj: TObject); (BEGIN ,TTextImage(obj).InsertNewPara(existingPara, newPara); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.txtImgList.Each(InsertPara); (SELF.paragraphs.InsAt(SELF.paragraphs.Pos(0, existingPara) + 1, newPara); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TText.Invalidate; (PROCEDURE InvalInImage(obj: TObject); (VAR textImage: TTextImage; ,PROCEDURE InvalOnPad; ,BEGIN 0textImage.Invalidate; ,END; (BEGIN ,textImage := TTextImage(obj); ,IF textImage.imageList.Size > 0 THEN 0textImage.view.panel.OnAllPadsDo(InvalOnPad); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.txtImgList.Each(InvalInImage); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TText.MarkChanged(textRange: TTextRange); (PROCEDURE Mark(obj: TObject); (VAR textImage: TTextImage; ,selection: TSelection; (BEGIN ,selection := TTextImage(obj).view.panel.selection; ,WHILE selection.coSelection <> NIL DO 0selection := selection.coSelection; ,textImage := TTextSelection(selection).textImage; ,WITH textRange DO 0{$H-} 0textImage.MarkChanged(firstIndex, firstLP, lastIndex, lastLP); 0{$H+} (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.txtImgList.Each(Mark); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TText.RecomputeImages; (PROCEDURE ReImage(obj: TObject); (VAR textImage: TTextImage; ,padCount: INTEGER; ,numPads: INTEGER; ,PROCEDURE ImageOnPad; ,BEGIN 0padCount := padCount+1; 0{The first parameter in textImage.RecomputeImages says we want to draw, but it will 1call view.OKToDrawIn to be sure its Okay. 1The last parameter is TRUE when we are drawing on the last pad. RecomputeImages 1and DrawOrInval will then set the valid bits on the images to TRUE} 0IF padCount = 1 THEN 4textImage.RecomputeImages(actionDraw, (numPads = 1)) 0ELSE 4textImage.DrawOrInval(padCount = numPads); ,END; (BEGIN ,textImage := TTextImage(obj); ,numPads := textImage.view.panel.panes.size; ,padCount := 0; ,textImage.view.panel.OnAllPadsDo(ImageOnPad); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.txtImgList.Each(ReImage); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $FUNCTION TText.SelectAll(textImage: TTextImage): TTextSelection; $VAR lastPara: TEditPara; (textSelection: TTextSelection; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (lastPara := TEditPara(SELF.paragraphs.Last); (textSelection := textImage.NewTextSelection(TEditPara(SELF.paragraphs.First), 1, 0, XlastPara, SELF.paragraphs.Size, lastPara.size); (SelectAll := textSelection; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} BEGIN $fTextTrace := FALSE; END; {Methods of TText} METHODS OF TTextImage; {$S SgTxtIni} $FUNCTION TTextImage.CREATE(object: TObject; heap: THeap; itsView: TView; DitsLRect: LRect; itsText: TText; isGrowable: BOOLEAN): TTextImage; $VAR imgList: TList; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TTextImage(TImage.CREATE(object, heap, itsLRect, itsView)); (imgList := TList.CREATE(NIL, heap, 0); (WITH SELF DO ,BEGIN ,text := itsText; ,imageList := imgList; ,tickCount := 0; ,growsDynamically := isGrowable; ,minHeight := itsLRect.bottom - itsLRect.top; ,formerBottom := itsLRect.top; ,updateLRect := zeroLRect; ,firstLinePixel := 0; ,useFirstPixel := FALSE; ,firstIndex := 1; ,startLP := 0; ,endLP := 0; ,{app must set these properly if using multiple linked text images} ,prevTxtImg := NIL; ,nextTxtImg := NIL; ,headTxtImg := SELF; ,tailTxtImg := SELF; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} ${This frees all text images and their paraImages in the text image chain. %It does NOT free any paragraphs, text objects, or paraFormats. Call this only once %for each text image chain (NOT for each text image in the chain} $PROCEDURE TTextImage.Free; $VAR textImage: TTextImage; (next: TTextImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.headTxtImg = SELF THEN ,{Think about freeing text here if this is its only text image, but beware of circular frees} 0BEGIN 0textImage := SELF; 0WHILE textImage <> NIL DO 4BEGIN 4textImage.imageList.Free; 4next := textImage.nextTxtImg; 4textImage.FreeObject; 4textImage := next; 4END; 0END (ELSE ,SELF.headTxtImg.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} ${Frees just one text image in the chain; pays no attention to links} $PROCEDURE TTextImage.FreeOneTextImage; $VAR textImage: TTextImage; (next: TTextImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.imageList.Free; (SELF.FreeObject; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fTextTrace} $PROCEDURE TTextImage.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('text: TText'); (Field('imageList: TList'); (Field('tickCount: INTEGER'); (Field('growsDynamically: BOOLEAN'); (Field('minHeight: INTEGER'); (Field('formerBottom: LONGINT'); (Field('updateLRect: LRect'); (Field('firstLinePixel: LONGINT'); (Field('useFirstPixel: BOOLEAN'); (Field('firstIndex: LONGINT'); (Field('startLP: INTEGER'); (Field('endLP: INTEGER'); (Field('prevTxtImg: TTextImage'); (Field('nextTxtImg: TTextImage'); (Field('headTxtImg: TTextImage'); (Field('tailTxtImg: TTextImage'); (Field(''); $END; {$ENDC} {$S SgTxtCld} $PROCEDURE TTextImage.AddImage(paraImage: TParaImage); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.imageList.InsLast(paraImage); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TTextImage.DelImagesWith(delPara: TEditPara); $VAR (* (i,j: INTEGER; (numImages: INTEGER; (*) (s: TListScanner; (paraImage: TParaImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (s := delPara.images.Scanner; (WHILE s.Scan(paraImage) DO ,IF paraImage.textImage.headTxtImg = SELF.headTxtImg THEN 0BEGIN 0paraImage.textImage.imageList.DelObject(paraImage, FALSE); 0s.Delete(FALSE); 0paraImage.Free; 0END; ((* (numImages := delPara.NumImages; (j := 1; (FOR i := 1 TO numImages DO ,BEGIN ,{paraImage.Free calls paragraph.DelImage which shifts rest -of images left so next image will always be at position j} ,paraImage := delPara.images[j]; ,IF paraImage.textImage.headTxtImg = SELF.headTxtImg THEN 0paraImage.textImage.imageList.DelObject(paraImage, TRUE) ,ELSE 0j := j + 1; ,END; (*) ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TTextImage.Draw; (PROCEDURE ReDraw(obj: TObject); (BEGIN ,IF LRectIsVisible(TParaImage(obj).extentLRect) THEN 0TParaImage(obj).RedrawLines(0, MAXINT); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (PicGrpBegin; (SELF.imageList.Each(ReDraw); ({Now tell the next textImage in the chain to draw itself} (IF SELF.nextTxtImg <> NIL THEN ,SELF.nextTxtImg.Draw; (PicGrpEnd; ({$IFC fTrace}EP;{$ENDC} $END; {Draw} {$S SgTxtCld} $PROCEDURE TTextImage.DrawImages(fDraw: BOOLEAN); (PROCEDURE ReDraw(obj: TObject); (BEGIN ,IF LRectIsVisible(TParaImage(obj).extentLRect) THEN 0TParaImage(obj).RedrawLines(0, MAXINT); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.imageList.Each(ReDraw); ({Now tell the next textImage in the chain to draw itself} (IF SELF.nextTxtImg <> NIL THEN ,SELF.nextTxtImg.DrawImages(fDraw); ({$IFC fTrace}EP;{$ENDC} $END; {DrawImages} {$S SgTxtCld} $PROCEDURE TTextImage.DrawOrInval(invalBits: BOOLEAN); $VAR fDraw: BOOLEAN; (r: LRect; (PROCEDURE DrawFiltImage(obj: TObject); (VAR paraImage: TParaImage; ,PROCEDURE DrawImage(obj: TObject); ,VAR leftPixel: LONGINT; 0rightPixel: LONGINT; 0styleIndex: INTEGER; 0PROCEDURE DrawLine(obj: TObject); 0VAR lineInfo: TLineInfo; 4dummy: INTEGER; 0BEGIN 4lineInfo := TLineInfo(obj); 4IF NOT lineInfo.valid THEN 8BEGIN 8r := lineInfo.lineLRect; 8r.left := lineInfo.leftCoord(leftPixel); 8r.right := lineInfo.leftCoord(rightPixel); 8IF fDraw THEN  lineInfo.lastDrawnLP THEN @BEGIN @MoveToL(lineInfo.lineLRect.left, lineInfo.lineLRect.top+lineInfo.lineAscent); @paraImage.FastDrawLine(lineInfo.startLP, lineInfo.lastDrawnLP, TRUE, XFALSE, dummy, styleIndex); @END;  NIL THEN ,SELF.nextTxtImg.DrawOrInval(invalBits); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TTextImage.FindParaAndLp(lPt: LPoint; VAR paraImage: TParaImage; WVAR paraIndex: LONGINT; VAR aLP: INTEGER); $VAR distanceDown: INTEGER; (s: TListScanner; ({$IFC fTextTrace} (str: STR255; ({$ENDC} $BEGIN ({$IFC fTrace}BP(9);{$ENDC} ({It is assumed that the caller of this routine has already determined that lPt is in this )textImage, so we will not check nextTextImg if the image list is exhausted} (distanceDown := SELF.extentLRect.top; (s := SELF.imageList.Scanner; (WHILE s.Scan(paraImage) DO ,BEGIN ,distanceDown := distanceDown + paraImage.height; ,paraIndex := s.Position; ,IF lPt.v <= distanceDown THEN 0s.Done; ,END; (paraIndex := paraIndex + SELF.firstIndex - 1; (IF lPt.v > distanceDown THEN ,paraImage := TParaImage(SELF.imageList.Last); (aLP := paraImage.LpWithLPt(lPt); ({$IFC fTextTrace} (IF fTextTrace THEN ,BEGIN ,LIntToHex(ORD(paraImage), @str); ,writeln('*** End FindParaAndLp: lPt= (',lPt.v:4, ',', lPt.h:4, '); paraImage, index, lp = (', Astr, ',', paraIndex:1, ',', aLP:3, ')'); ,END; ({$ENDC} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TTextImage.FindTextImage(VAR mouseLPt: LPoint; VAR firstTxtImg: TTextImage): TTextImage; $VAR textImage: TTextImage; (stillLooking: BOOLEAN; (foundIt: BOOLEAN; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} ({This looks around for a textImage that contains the mouseLPt and has some images. If it )finds a textImage that contains the point but does not have any images, then it )returns the first previous textImage that does have some images and changes mouseLPt to be )the bottom right point of that textImage. )If it doesn't find any textImages that contain the point it returns the first previous )textImage that does have some images. Also, it returns which of the textImages )(SELF or the found one) that comes first in the textImage chain} (firstTxtImg := SELF; ({Start with most common case and then try others} (IF (SELF.imageList.Size > 0) AND 0(LPtInLRect(mouseLPt, SELF.extentLRect) OR SELF.growsDynamically) THEN ,FindTextImage := SELF (ELSE ,BEGIN ,textImage := SELF; ,stillLooking := TRUE; ,foundIt := FALSE; ,WHILE stillLooking DO 0BEGIN 0{First look in following boxes} 0IF LPtInLRect(mouseLPt, textImage.extentLRect) THEN 4BEGIN 4{if box found but no images in it, then link back} 4WHILE (textImage <> textImage.headTxtImg) AND (textImage.imageList.Size = 0) DO 8BEGIN 8textImage := textImage.prevTxtImg; 8mouseLPt := textImage.extentLRect.botRight; 8END; 4foundIt := TRUE; 4stillLooking := FALSE; 4END 0ELSE IF textImage.nextTxtImg <> NIL THEN 4textImage := textImage.nextTxtImg 0ELSE stillLooking := FALSE; 0END; ,IF foundIt THEN 0FindTextImage := textImage ,ELSE 0{Still didn't find it? Look in previous boxes} 0BEGIN 0stillLooking := TRUE; 0WHILE stillLooking DO 4BEGIN 4IF LPtInLRect(mouseLPt, textImage.extentLRect) THEN 8BEGIN 8WHILE (textImage <> textImage.headTxtImg) AND (textImage.imageList.Size = 0) DO  NIL THEN 8textImage := textImage.prevTxtImg 4ELSE stillLooking := FALSE; 4END; 0IF foundIt THEN 4BEGIN 4FindTextImage := textImage; 4firstTxtImage := textImage; 4END 0ELSE 4BEGIN 4{mouseLPt didn't fall in any of the text images, so return SELF or the first previous 5text image that has a paraimage} 4textImage := SELF; 4WHILE (textImage <> textImage.headTxtImg) AND (textImage.imageList.Size = 0) DO 7BEGIN 7textImage := textImage.prevTxtImg; 7mouseLPt := textImage.extentLRect.botRight; 7END; 4FindTextImage := textImage; 4END; 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TTextImage.GetImageRange(firstIndex: LONGINT; VAR firstLP: INTEGER; JlastIndex: LONGINT; VAR lastLP: INTEGER; JVAR firstImage, lastImage: TParaImage); ${Diagram of input vs output: --- = characters not displayed by this textImage chain; Bxxx = characters that are displayed by this textImage chain; (------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx---------- *^ ^ ^ ^ ^ ^ ^ *1 2 3 4 5 6 7 (input imageWith output )1,2 N,N N,N )1,3 N,3 N,3 )1,4 N,4 3,4 )1,5 N,5 3,5 )1,6 N,N 3,5 )3,3 3,3 3,3 N = NIL )3,4 3,4 3,4 )4,5 4,5 4,5 )4,6 4,N 4,5 )5,5 5,5 5,5 )5,6 5,N 5,N )6,7 N,N N,N &} (FUNCTION GetFirstOrLast(index: LONGINT; VAR lp: INTEGER): TParaImage; (VAR paraImage: TParaImage; ,lastTxtImg: TTextImage; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,IF (index < SELF.headTxtImg.firstIndex) OR /((index = SELF.headTxtImg.firstIndex) AND (lp < SELF.headTxtImg.startLP)) THEN 0BEGIN 0paraImage := TParaImage(SELF.headTxtImg.imageList.First); 0lp := paraImage.startLP; 0END ,ELSE 0BEGIN 0lastTxtImg := SELF.tailTxtImg; 0WHILE lastTxtImg.imageList.Size <= 0 DO 4lastTxtImg := lastTxtImg.prevTxtImg; 0paraImage := TParaImage(lastTxtImg.imageList.Last); 0lp := paraImage.endLP; 0END; ,GetFirstOrLast := paraImage; ,{$IFC fTrace}EP;{$ENDC} (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (firstImage := SELF.ImageWith(TEditPara(SELF.text.paragraphs.At(firstIndex)), firstLP); (lastImage := SELF.ImageWith(TEditPara(SELF.text.paragraphs.At(lastIndex)), lastLP); (IF (firstImage = NIL) OR (lastImage = NIL) THEN ,BEGIN ,IF firstImage = NIL THEN 0IF lastImage <> NIL THEN 4BEGIN 4firstImage := GetFirstOrLast(firstIndex, firstLP); 4IF (firstImage = lastImage) THEN 8IF (firstLP = lastLP) THEN  SELF THEN  NIL) DO 4IF textImage.imageList.Size > 0 THEN 8BEGIN 8paraImage := TParaImage(textImage.imageList.First); 8IF paraImage.paragraph = lastImage.paragraph THEN  NIL DO ,BEGIN ,textImage.imageList.Each(Inval); ,r := textImage.extentLRect; ,InsetLRect(r, -1, 0); ,SELF.view.panel.InvalLRect(r); ,textImage := textImage.nextTxtImg; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TTextImage.Invalidate; $VAR r: LRect; (s, sLine: TListScanner; (paraImage: TParaImage; (lineInfo: TLineInfo; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (s := SELF.imageList.Scanner; (WHILE s.Scan(paraImage) DO ,IF paraImage.wasOffset THEN 0BEGIN 0r := paraImage.extentLRect; 0InsetLRect(r, -1, 0); 0thePad.InvalLRect(r); 0paraImage.wasOffset := FALSE; 0paraImage.changed := FALSE; 0END ,ELSE IF paraImage.changed THEN 0BEGIN 0paraImage.changed := FALSE; 0sLine := paraImage.lineList.Scanner; 0WHILE sLine.Scan(lineInfo) DO 4IF NOT lineInfo.valid THEN 8BEGIN 8lineInfo.valid := TRUE; 8r := lineInfo.lineLRect; 8r.left := paraImage.extentLRect.left; 8r.right := paraImage.extentLRect.right; 8InsetLRect(r, -1, 0); 8thePad.InvalLRect(r); 8END; 0END; (IF NOT EmptyLRect(SELF.updateLRect) THEN ,BEGIN ,thePad.InvalLRect(SELF.updateLRect); ,SELF.updateLRect := zeroLRect; ,END; (IF SELF.nextTxtImg <> NIL THEN ,SELF.nextTxtImg.Invalidate; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TTextImage.MarkChanged(startIndex: LONGINT; startLP: INTEGER; LendIndex: LONGINT; endLP: INTEGER); $VAR sImg: TListScanner; (firstImage: TParaImage; (lastImage: TParaImage; (paraImage: TParaImage; (found: BOOLEAN; (finished: BOOLEAN; (textImage: TTextImage; (tempLP: INTEGER; (stillOkay: BOOLEAN; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (stillOkay := TRUE; (IF (startIndex = endIndex) AND (startLP = endLP) THEN ,BEGIN ,firstImage := SELF.ImageWith(TEditPara(SELF.text.paragraphs.At(startIndex)), startLP); ,lastImage := firstImage; ,stillOkay := firstImage <> NIL; ,END (ELSE ,BEGIN ,SELF.GetImageRange(startIndex, startLP, endIndex, endLP, firstImage, lastImage); ,IF firstImage = NIL THEN 0IF lastImage = NIL THEN 4stillOkay := FALSE 0ELSE 4BEGIN 4firstImage := lastImage; 4startLP := endLP; 4END ,ELSE IF lastImage = NIL THEN 4BEGIN 4lastImage := firstImage; 4endLP := startLP; 4END; ,END; (IF stillOkay THEN ,BEGIN ,IF firstImage = lastImage THEN 0firstImage.InvalLinesWith(startLP, endLP) ,ELSE 0BEGIN 0textImage := firstImage.textImage; 0found := FALSE; 0finished := FALSE; 0WHILE NOT finished AND (textImage <> NIL) DO 4BEGIN 4sImg := textImage.imageList.Scanner; 4WHILE sImg.Scan(paraImage) DO 8BEGIN 8found := found OR (paraImage = firstImage); 8IF found THEN  NIL DO ,selection := selection.coSelection; (IF (clickState.fShift OR (clickState.clickCount > 1)) AND InClass(selection, TTextSelection) THEN ,{ let the selection extend itself } ,selection.MousePress(mouseLPt) (ELSE ,BEGIN ,textImage := SELF.FindTextImage(mouseLPt, firstTxtImg); ,textImage.FindParaAndLp(mouseLPt, currParaImage, paraIndex, currLP); ,{If we are a coSelection then BeginSelection should already have been called when -panel selection was created} ,IF SELF.view.panel.selection.coSelection = NIL THEN 0SELF.view.panel.BeginSelection ,ELSE 0selection.Highlight(hOnToOff); ,selection := selection.FreedAndReplacedBy(TInsertionPoint.CREATE(NIL, LSELF.Heap, SELF.view, textImage, mouseLPt, LcurrParaImage.paragraph, paraIndex, currLP)); ,SELF.text.ChangeSelInOtherPanels(TTextSelection(selection)); ,SELF.text.HiliteParagraphs(hOffToOn, paraIndex, currLP, paraIndex, currLP, FALSE); ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TTextImage.NewEditPara(initialSize: INTEGER; itsFormat: TParaFormat): TEditPara; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (NewEditPara := TEditPara.CREATE(NIL, SELF.Heap, initialSize, itsFormat); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TTextImage.NewParaImage(itsParagraph: TEditPara; itsLRect: LRect; DlineTop: LONGINT; lineLeft: LONGINT): TParaImage; $VAR paraImage: TParaImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (paraImage := TParaImage.CREATE(NIL, SELF.Heap, SELF.view, itsParagraph, itsLRect, lineTop, lineLeft); (paraImage.textImage := SELF; (itsParagraph.InsImage(paraImage); (NewParaImage := paraImage; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TTextImage.NewTextImage(heap: THeap; itsView: TView; itsLRect: LRect; PitsText:TText; isGrowable: BOOLEAN): TTextImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (NewTextImage := TTextImage.CREATE(NIL, heap, itsView, itsLRect, itsText, isGrowable); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TTextImage.NewTextSelection(firstPara: TEditPara; firstIndex: LONGINT; firstLP: INTEGER; LlastPara: TEditPara; lastIndex: LONGINT; lastLP: INTEGER L): TTextSelection; $VAR textSel: TTextSelection; (heap: THeap; (view: TView; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (heap := SELF.Heap; (view := SELF.view; (IF firstPara = lastPara THEN ,IF firstLP = lastLP THEN 0textSel := TInsertionPoint.CREATE(NIL, heap, view, SELF, zeroLPt, XfirstPara, firstIndex, firstLP) ,ELSE 0textSel := TOneParaSelection.CREATE(NIL, heap, view, SELF, zeroLPt, XfirstPara, firstIndex, firstLP, lastLP) (ELSE ,textSel := TMultiParaSelection.CREATE(NIL, heap, view, SELF, zeroLPt, XfirstPara, firstIndex, firstLP, XlastPara, lastIndex, lastLP, TRUE); (NewTextSelection := textSel; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TTextImage.OffsetBy(deltaLPt: LPoint); ${ Can be used to quickly move a text image } (PROCEDURE OffsetImage(obj: TObject); (BEGIN ,TParaImage(obj).OffsetBy(deltaLPt); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (WITH deltaLPt DO ,{$H-} OffsetLRect(SELF.extentLRect, h, v); {$H+} (SELF.imageList.Each(OffsetImage); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TTextImage.RecomputeImages(drawAction: TDrawAction; invalBits: BOOLEAN); $LABEL 1; $VAR drawLRect: LRect; (lastLP: INTEGER; (lastDrawnImage: TParaImage; (nextTxtImg: TTextImage; (paraImage: TParaImage; (s: TListScanner; (tempList: TList; (beginAtLP: INTEGER; (returnLRect: LRect; (lastImage: TParaImage; (firstImage: TParaImage; (lastOneChanged: BOOLEAN; (deltaLPt: LPoint; (currParaIndex: LONGINT; (paragraph: TEditPara; (newBottom: LONGINT; (realAction: TDrawAction; (r: LRect; ({$IFC fTextTrace} (str: STR255; ({$ENDC} (FUNCTION OnlyPartDrawn(pImage: TParaImage): BOOLEAN; (VAR wontFit: BOOLEAN; ,sLine: TListScanner; ,deleteRest: BOOLEAN; ,lineInfo: TLineInfo; ,PROCEDURE DrawPImage(obj: TObject); ,VAR action: TDrawAction; 0bits: BOOLEAN; ,BEGIN 0{$IFC fTrace}BP(10);{$ENDC} 0bits := invalBits; 0action := realAction; 0{If the paragraph was offset, we don't want DrawPara to draw the changed lines, so 1we display the offset paragraph case below and pass actionNone to DrawPara. 1However, we must pass FALSE for invalBits since we still need the wasOffset flag 1set for the display code below} 0IF pImage.wasOffset THEN 4BEGIN 4action := actionNone; 4bits := FALSE; 4END; 0pImage.DrawParaImage(drawLRect, beginAtLP, action, bits, returnLRect); 0{$IFC fTrace}EP;{$ENDC} ,END; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,wontFit := FALSE; ,lastOneChanged := FALSE; ,pImage.textImage := SELF; ,{$IFC fTextTrace} ,IF fTextTrace THEN 0BEGIN 0LIntToHex(ORD(pImage), @str); 0WriteLn('++ Entering OnlyPartDrawn: pImage =', str); 0WriteLn('++ : deltaLPt.v =', deltaLPt.v:1, ' drawLRect.top = ', LdrawLRect.top:1); 0END; ,{$ENDC} ,{offset pImage before recalculating so that unchanged lineInfo's get offset} ,IF drawLRect.top <> pImage.extentLRect.top THEN 0BEGIN 0deltaLPt.v := drawLRect.top - pImage.extentLRect.top; 0pImage.OffsetBy(deltaLPt); 0pImage.wasOffset := TRUE; {so that we know what to redraw/invalidate} 0{If we moved the last paraImage up, maybe more will fit, so force call to DrawPara 1by setting changed TRUE} 0IF (deltaLPt.v < 0) AND (pImage = SELF.imageList.Last) THEN 4BEGIN 4lastOneChanged := TRUE; 4pImage.changed := TRUE; 4END; 0END; ,IF pImage.changed THEN 0BEGIN 0lastLP := pImage.endLP; 0{$IFC fTextTrace} 0IF fTextTrace THEN 4WriteLn('++ OnlyPartDrawn: pImage changed, about to call DrawPara; old endLP =', PlastLP:1); 0{$ENDC} 0SELF.FilterAndDo(pImage, DrawPImage); 0{$IFC fTextTrace} 0IF fTextTrace THEN 4WriteLn('++ OnlyPartDrawn: DrawPara just called; pImage.endLP =', PpImage.endLP:1, ' para size = ', pImage.paragraph.size:1); 0{$ENDC} 0lastOneChanged := lastOneChanged OR (pImage.endLP <> lastLP); 0END ,ELSE IF deltaLPt.v > 0 THEN 0BEGIN 0{$IFC fTextTrace} 0IF fTextTrace THEN 4WriteLn('++ OnlyPartDrawn: pImage.extentLRect.bottom =', pImage.extentLRect.bottom:1, @' drawLRect.bottom = ', drawLRect.bottom:1); 0{$ENDC} 0wontFit := pImage.extentLRect.bottom > drawLRect.bottom; 0IF wontFit THEN 4BEGIN 4{Ideally, if textImages are same width, just insert extra lineInfo's 5into first paraImage of next textImage; If they are not same width, we 5still insert them but mark them invalid. For now just delete them} 4lastOneChanged := TRUE; 4sLine := pImage.lineList.Scanner; 4deleteRest := FALSE; 4WHILE sLine.Scan(lineInfo) DO 8IF deleteRest THEN  drawLRect.bottom THEN  pImage.paragraph.size); ,IF pImage.wasOffset AND (lastLP >= 0) THEN 0BEGIN 0r := pImage.extentLRect; 0InsetLRect(r, -1, 0); 0IF realAction = actionDraw THEN 4BEGIN 4FillLRect(r, lPatWhite); 4pImage.RedrawLines(0, MAXINT); 4END 0ELSE IF realAction = actionInval THEN 4thePad.InvalLRect(r); 0pImage.wasOffset := NOT invalBits; 0pImage.changed := FALSE; 0END; ,{after the first paragraph is drawn, reset beginAtLP} ,beginAtLP := 0; ,IF NOT wontFit THEN 0currParaIndex := currParaIndex + 1; ,{$IFC fTextTrace} ,IF fTextTrace THEN 0WriteLn('++ EXITING OnlyPartDrawn: deltaLPt.v =', deltaLPt.v:1, ' wontFit = ', wontFit); ,{$ENDC} ,{return TRUE when a paragraph does not get completely displayed} ,OnlyPartDrawn := wontFit; ,{$IFC fTrace}EP;{$ENDC} (END; $BEGIN {RecomputeIMages} ({$IFC fTrace}BP(10);{$ENDC} (IF SELF = SELF.headTxtImg THEN ,SELF.SetFirstIndex; (currParaIndex := SELF.firstIndex; (drawLRect := SELF.extentLRect; (IF SELF.growsDynamically THEN ,drawLRect.bottom := SELF.view.extentLRect.bottom; (realAction := drawAction; (IF drawAction = actionDraw THEN ,IF NOT SELF.view.OKToDrawIn(drawLRect) OR deferUpdate THEN 0realAction := actionInval; (beginAtLP := SELF.startLP; (deltaLPt := zeroLPt; ({Recompute paragraphs until we reach the end of our imageList or no more will fit} ({Use GOTO so we can hold on to the scanner if needed} (s := SELF.imageList.Scanner; (WHILE s.Scan(lastDrawnImage) DO ,IF OnlyPartDrawn(lastDrawnImage) THEN 0GOTO 1; (1: ({$IFC fTextTrace} (IF fTextTrace THEN ,BEGIN ,LIntToHex(ORD(lastDrawnImage), @str); ,WriteLn('++ RecomputeImages: Just fell out of OnlyPartDrawn loop: lastDrawnImage=',  NIL THEN 8BEGIN 8s := nextTxtImg.imageList.Scanner; 8{Delete the first paraImage in the next textImage if it pointed to the same 9paragraph as the current textImage's last paraImage, since, if we got to 9this point, we must have already displayed the whole paragraph} 8IF (nextTxtImg.imageList.Size > 0) AND (SELF.imageList.Size > 0) THEN = 0) THEN DBEGIN DSELF.imageList.InsLast(lastDrawnImage); DparaImage := nextTxtImg.NewParaImage(lastDrawnImage.paragraph, XlastDrawnImage.extentLRect, 0, 0); Ds.Replace(paraImage, FALSE); DEND; @s.Done; @END  NIL) OR (nextTxtImg = NIL); ,IF lastDrawnImage = NIL THEN 0BEGIN 0{We exhausted all of the images and there is still potentially some room, so 1look at the paragraph list and see if there are some paragraphs for which no 1paraImages have yet been generated. 1NOTE: this is where initial imaging of text without paraImages will be routed} 0IF currParaIndex <= SELF.text.paragraphs.Size THEN 4BEGIN 4s := SELF.text.paragraphs.ScannerFrom(currParaIndex-1, scanForward); 4WHILE s.Scan(paragraph) DO 8BEGIN 8lastDrawnImage := SELF.NewParaImage(paragraph, drawLRect, 0, 0); 8IF OnlyPartDrawn(lastDrawnImage) THEN = 0 THEN  NIL THEN ,BEGIN ,IF lastOneChanged THEN 0BEGIN 0{we stopped displaying in the middle of a paragraph, so give the rest of our 1paraImages to the next textImage (note that the scanner (s) is still valid 1because we jumped out of scan loop above)} 0{put rest of SELF.imageList paraImages in tempList, then insert tempList into nextTxtImg} 0tempList := TList.CREATE(NIL, SELF.Heap, 0); 0{if we didn't display any of the current paraImage then delete it from this list} 0IF lastLP < 0 THEN 4BEGIN 4{$IFC fTextTrace} 4IF fTextTrace THEN 8BEGIN 8LIntToHex(ORD(lastDrawnImage), @str); 8WriteLn('++ RecomputeImages: lastLP < 0; lastdrawnImage=', str); 8END; 4{$ENDC} 4s.Delete(FALSE); 4paraImage := lastDrawnImage; 4paraImage.endLP := 0; 4END 0ELSE 4BEGIN 4paraImage := nextTxtImg.NewParaImage(lastDrawnImage.paragraph, TlastDrawnImage.extentLRect, 0, 0); 4{$IFC fTextTrace} 4IF fTextTrace THEN 8BEGIN 8LIntToHex(ORD(paraImage), @str); 8WriteLn('++ RecomputeImages: copy of lastDrawnImage =', str); 8END; 4{$ENDC} 4END; 0tempList.InsLast(paraImage); 0{put the paraImages into tempList in reverse order so that we can scan it and insert 1the images at the beginning of nextTxtImg.imageList (a double-reverse)} 0WHILE s.Scan(paraImage) DO 4BEGIN 4{$IFC fTextTrace} 4IF fTextTrace THEN 7BEGIN 7LIntToHex(ORD(paraImage), @str); 7WriteLn('++ RecomputeImages: appending to tempList and deleting from SELF pImg=', str); 7END; 4{$ENDC} 4tempList.InsFirst(paraImage); 4s.Delete(FALSE); 4END; 0{Delete the last paraImage inserted in the tempList if it pointed to the same 1paragraph as the next textImage's first paraImage} 0IF nextTxtImg.imageList.Size > 0 THEN 4BEGIN 4firstImage := TParaImage(nextTxtImg.imageList.First); 4lastImage := TParaImage(tempList.First); 4IF firstImage.paragraph = lastImage.paragraph THEN 8BEGIN 8firstImage.InvalLinesWith(0, MAXINT); 7{$IFC fTextTrace} 8IF fTextTrace THEN  Entering FillRun: Current fields are:'); ,WriteLn('<-> currIndex = ', SELF.currIndex:1, ' currStyleIndex = ', SELF.currStyleIndex:1); ,WriteLn('<-> currLP = ', SELF.currLP:1); ,END; ({$ENDC} (SELF.data.DelAll; (IF SELF.currIndex <= SELF.textSelection.textRange.lastIndex THEN ,BEGIN ,WITH SELF.paragraphDescriptor, SELF.currPara.format DO 0BEGIN 0paragraphStart := SELF.textSelection.isParaSelection AND {LSR} H(SELF.currLP = 0); 0firstLineMargin := firstIndent; 0bodyMargin := leftIndent; 0rightMargin := rightMargin - rightIndent; {????} 0paraLeading := spaceBelowPara; 0END; ,IF SELF.currPara.size = 0 THEN 0BEGIN 0endPos := 0; 0numChars := 0; 0END ,ELSE 0BEGIN 0REPEAT 4SELF.currTStyles.GetAt(SELF.currStyleIndex, @currChange); 4WITH SELF.characterDescriptor DO 8BEGIN 8{$H-} 8font := QDFontNumber(currChange.newStyle); 8{$H+} 8face := currChange.newStyle.onFaces; 8END; 4startPos := Max(SELF.currLP, currChange.lp) + 1; 4SELF.currTStyles.GetAt(SELF.currStyleIndex+1, @nextChange); 4endPos := Min(SELF.currPara.size, nextChange.lp); 4numChars := endPos - startPos + 1; 4IF numChars = 0 THEN 8SELF.currStyleIndex := SELF.currStyleIndex + 1; 0UNTIL numChars > 0; 0SELF.data.InsManyAt(1, SELF.currPara, startPos, numChars); 0END; ,IF endPos = SELF.currPara.size THEN 0BEGIN 0SELF.currIndex := SELF.currIndex + 1; 0WITH SELF DO 4IF currIndex <= textSelection.textRange.lastIndex THEN 8BEGIN 8currLP := 0; 8currStyleIndex := 1; 8{$H-} 8currPara := TEditPara(SELF.textSelection.textImage.text.paragraphs.At( \SELF.currIndex)); 8{$H+} 8currTStyles := currPara.typeStyles; 8{$H-} 8SELF.data.InsAt(numChars+1, CHR(ascReturn)); {last statement in IF!!} 8{$H+} 8END 4ELSE IF textSelection.isParaSelection THEN 8{$H-} 8SELF.data.InsAt(numChars+1, CHR(ascReturn)); {last statement in IF!!} 8{$H+} 0END ,ELSE 0BEGIN 0SELF.currLP := SELF.currLP + numChars; 0SELF.paragraphDescriptor.additionalChrInParagraph := {LSR} 8SELF.currPara.size - endPos + 1; 0END; ,END; ({$IFC fTextTrace} (IF fTextTrace THEN ,BEGIN ,WriteLn; ,WriteLn('>-< EXITING FillRun: Current fields are:'); ,WriteLn('>-< currIndex = ', SELF.currIndex:1, ' currStyleIndex = ', SELF.currStyleIndex:1); ,WriteLn('>-< currLP = ', SELF.currLP:1); ,WriteLn('----------------------------------------------------------------'); ,END; ({$ENDC} ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {Methods of TTextWriteUnivText} {$ENDC} {$S SgTxtIni} 3. "6F^9 S$S SgABCres}^5eLءndex, insertionPt.textRange.firstLP))); )); {Text Selections and Commands} END. 0IF cmdPhase = doPhase THEN 4BEGIN 4WITH insertionPoint DO 8BEGIN 8amTyping := TRUE; 8typingCmd := SELF; 8IF TFakeTStyle(currTypeStyle) <> TFakeTStyle(typeStyle) THEN = 0" to "IF firstLP > 0"} {changed 04/16/84 1414 Set viewLRect origined at (0,0) in TTextSelection.CutCopy} {changed 04/16/84 1322 Set textImage.minHeight to 0 in TOnePara and TMultiPara.CopySelf} {changed 04/16/84 1024 Call recomputeImages in TOnePara and TMultiPara.CopySelf to set clipView size} {changed 04/13/84 1736 First parameter decremented in calls to TParagraph.StyleAt; 8No longer set unHighlightBefore[doPhase] to FALSE in typingCmd; 8Set TInsertionPoint.justReturned to FALSE in all Key methods (except KeyReturn); 8Call StyleFromContext in TStyleCmd.Perform} {changed 04/13/84 1531 TStyleCmd.FilterAndDo now filters a TEditPara rather than a TParaImage; 8Call StyleFromContext through a filter in TTextSelection.CREATE} {changed 04/13/84 1102 TInsertion.MousePress: Allow selecting of word when double click on last half  0 THEN 8IF firstPara.At(firstLp) = ' ' THEN hNone) AND (centiSeconds > SELF.nextTransitTime) THEN ,BEGIN ,SELF.textImage.text.HiliteRange(SELF.nextHighTransit, SELF.textRange, FALSE); ,WITH SELF DO 0IF nextHighTransit = hOnToOff THEN 4BEGIN 4nextHighTransit := hOffToOn; 4nextTransitTime := centiSeconds+blinkOffCentiSecs; 4END 0ELSE 4BEGIN 4nextHighTransit := hOnToOff; 4nextTransitTime := centiSeconds+blinkOnCentiSecs; 4END; 0END; (SUPERSELF.IdleContinue(centiSeconds); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TInsertionPoint.IdleEnd(centiSeconds: LONGINT); ({ end with highlighting on } $BEGIN ({$IFC fTrace}BP(6);{$ENDC} (IF SELF.nextHighTransit=hOffToOn THEN ,SELF.textImage.text.HiliteRange(hOffToOn, SELF.textRange, FALSE); (SELF.nextHighTransit := hNone; (SUPERSELF.IdleEnd(centiSeconds); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TInsertionPoint.InsertText(text: TText; isParaSelection: BOOLEAN; isWordSelection: BOOLEAN; tuniversalText: BOOLEAN); $VAR s: TListScanner; (prevPara: TEditPara; (newPara: TEditPara; (aParagraph: TEditPara; (newLP: INTEGER; (textImage: TTextImage; (insertIt: BOOLEAN; (done: BOOLEAN; (newParaImage: TParaImage; (paraIndex: LONGINT; (delta: INTEGER; (numParas: INTEGER; (needSpRight: BOOLEAN; ({$IFC fUseUnivText} (readUnivText: TTKReadUnivText; (univPara: TEditPara; (univFormat: TParaFormat; ({$ENDC} (PROCEDURE StartPaste; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,IF universalText THEN 0BEGIN 0{$IFC fUseUnivText} 0univFormat := TParaFormat.CREATE(NIL, SELF.Heap, SELF.textImage.text.styleSheet); 0univPara := textImage.NewEditPara(0, prevPara.format); 0readUnivText := TTKReadUnivText.CREATE(NIL, SELF.Heap, NIL, 512, \[UTCharacters, UTParagraphs]); 0numParas := 0; 0{$ENDC} 0END ,ELSE 0BEGIN 0numParas := text.paragraphs.size; 0s := text.paragraphs.Scanner; 0END; ,{$IFC fTrace}EP;{$ENDC} (END; (PROCEDURE EndPaste; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,IF universalText THEN 0BEGIN 0{$IFC fUseUnivText} 0univPara.Free; 0readUnivText.Free; 0{$ENDC} 0END; ,{$IFC fTrace}EP;{$ENDC} (END; (FUNCTION GetParagraph(VAR paragraph: TEditPara): BOOLEAN; (VAR currPos: INTEGER; ,done: BOOLEAN; ,runSize: INTEGER; ,wasSomeText: BOOLEAN; ,ch: CHAR; ,typeStyle: TTypeStyle; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,If universalText THEN 0BEGIN 0{$IFC fUseUnivText} 0univPara.ReplPString(0, univPara.Size, NIL); 0currPos := 0; 0wasSomeText := FALSE; 0done := FALSE; 0REPEAT 4readUnivText.ReadRun; 4runSize := readUnivText.data.size; 4IF runSize > 0 THEN 8BEGIN 8IF NOT wasSomeText THEN  NIL) OR universalText THEN ,SELF.ChangeText(InsText, Adjust); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TInsertionPoint.KeyBack(fWord: BOOLEAN); $VAR paragraph: TEditPara; (savedPara: TEditPara; (lp: INTEGER; (typingCmd: TTypingCmd; (prevPara: TEditPara; (textRange: TTextRange; (PROCEDURE Adjust; ,VAR c: CHAR; ,PROCEDURE DelOne(paraImage: TParaImage); ,BEGIN 0paraImage.AdjustLineLPs(lp, -1); ,END; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,paragraph := SELF.textRange.firstPara; ,lp := SELF.newestLP; ,IF fWord THEN 0{&&& Move textRange.firstLP back to start of word}; ,paragraph.BeginInsertion(lp, 0); ,IF (paragraph.holeStart < 1) AND (SELF.textRange.firstIndex = 1) THEN 0SELF.CantDoIt ,ELSE 0BEGIN 0prevPara := NIL; 0IF paragraph.holeStart < 1 THEN 4BEGIN 4{Backspacing over beginning of paragraph} 4textRange := SELF.textRange; 4textRange.firstIndex := textRange.firstIndex - 1; 4prevPara := TEditPara(SELF.textImage.text.paragraphs.At(textRange.firstIndex)); 4WITH textRange DO 8BEGIN 8firstPara := prevPara; 8firstLP := prevPara.size; 8lastIndex := firstIndex; 8lastPara := firstPara; 8lastLP := firstLP; 8SELF.newestLP := firstLP; 8END; 4prevPara.ReplPara(prevPara.size, 0, paragraph, 0, paragraph.size); 4SELF.textImage.text.DelPara(paragraph, FALSE); 4SELF.textImage.text.paragraphs.DelObject(paragraph, FALSE); 4END 0ELSE 4BEGIN 4paragraph.bsCount := paragraph.bsCount + 1; 4c := paragraph.At(paragraph.holeStart); 4paragraph.DelAt(paragraph.holeStart); 4paragraph.UpdateRuns(lp-1, 1, 0); 4SELF.newestLP := lp-1; 4END; 0typingCmd := SELF.typingCmd; 0IF prevPara = NIL THEN 4BEGIN 4typingCmd.newCharCount := typingCmd.newCharCount - 1; 4IF typingCmd.newCharCount < 0 THEN 8BEGIN 8typingCmd.typingRange.firstLP := typingCmd.typingRange.firstLP - 1; 8typingCmd.newCharCount := 0; 8savedPara := TEditPara(typingCmd.savedText.paragraphs.First); 8{$R-} 8savedPara.InsertOneChar(c, 0); 8{$IFC fRngText}{$R+}{$ENDC} 8END; 4END 0ELSE 4BEGIN 4typingCmd.newParaCount := typingCmd.newParaCount - 1; 4IF typingCmd.newParaCount < 0 THEN 8BEGIN 8typingCmd.typingRange.firstIndex := textRange.firstIndex; 8typingCmd.typingRange.firstPara := textRange.firstPara; 8typingCmd.typingRange.firstLP := textRange.firstLP; 8typingCmd.savedText.paragraphs.InsFirst(paragraph); 8paragraph.ReplPString(0, paragraph.size, NIL); 8typingCmd.newCharCount := 0; 8typingCmd.newParaCount := 0; 8END 4ELSE 8paragraph.Free; 4END; 0deferUpdate := TRUE; 0SELF.justReturned := FALSE; 0END; ,{$IFC fTrace}EP;{$ENDC} (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.KeyText; (Adjust; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TInsertionPoint.KeyChar(ch: CHAR); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.KeyText; (SELF.textRange.firstPara.InsertOneChar(ch, SELF.newestLP); (IF SELF.styleCmdNumber <> 0 THEN ,BEGIN ,SELF.textRange.firstPara.NewStyle(SELF.newestLP, SELF.newestLP+1, SELF.currTypeStyle); ,SELF.styleCmdNumber := 0; ,END; (WITH SELF.typingCmd DO ,newCharCount := newCharCount + 1; (SELF.newestLP := SELF.newestLP + 1; (SELF.justReturned := FALSE; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TInsertionPoint.KeyEnter; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.textImage.text.RecomputeImages; ((*SELF.textImage.text.Invalidate;*) (deferUpdate := FALSE; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TInsertionPoint.KeyForward(fWord: BOOLEAN); $VAR paragraph: TEditPara; (savedPara: TEditPara; (lp: INTEGER; ${NOTE: This first stab at KeyForward does NOT properly restore typestyles !!} (PROCEDURE Adjust; ,PROCEDURE AddOne(paraImage: TParaImage); ,BEGIN 0paraImage.AdjustLineLPs(lp, 1); ,END; (BEGIN ,paragraph := SELF.textRange.firstPara; ,lp := SELF.newestLP; ,IF (lp = paragraph.holeStart) AND (paragraph.bsCount > 0) THEN 0BEGIN 0IF fWord THEN 4{&&& Recover word}; 0WITH paragraph DO 4BEGIN 4bsCount := paragraph.bsCount - 1; 4holeStart := paragraph.holeStart + 1; 4holeSize := paragraph.holeSize - 1; 4size := size + 1; 4END; 0paragraph.UpdateRuns(lp-1, 0, 1); 0SELF.newestLP := lp+1; 0WITH SELF.typingCmd DO 4newCharCount := newCharCount + 1; 0deferUpdate := TRUE; 0END; ,SELF.justReturned := FALSE; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.KeyText; (Adjust; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TInsertionPoint.KeyPause; ${Called by ToolKit when there are no keystrokes pending} $VAR text: TText; (diff: INTEGER; (lp: INTEGER; (textImage: TTextImage; (paraImage: TParaImage; (startLine: INTEGER; (startPixel: LONGINT; (PROCEDURE AddDiff(paraImage: TParaImage); (BEGIN ,paraImage.AdjustLineLPs(lp, diff); (END; (PROCEDURE AdjustOtherInsPts(obj: TObject); (VAR insertPt: TInsertionPoint; (BEGIN ,insertPt := TInsertionPoint(obj); ,paraImage := insertPt.textImage.ImageWith(SELF.textRange.firstPara, lp); ,IF paraImage <> NIL THEN 0BEGIN 0paraImage.LocateLP(lp, startLine, startPixel); 0insertPt.textImage.firstLinePixel := startPixel; 0insertPt.textImage.useFirstPixel := TRUE; 0END ,ELSE 0insertPt.textImage.useFirstPixel := FALSE; ,WITH SELF, insertPt.textRange DO 0BEGIN 0firstLP := newestLP; 0lastLP := newestLP; 0IF firstIndex <> textRange.firstIndex THEN 4BEGIN 4firstIndex := textRange.firstIndex; 4lastIndex := textRange.lastIndex; 4firstPara := textRange.firstPara; 4lastPara := textRange.lastPara; 4END; 0END; (END; (PROCEDURE HiliteOtherInsPts(obj: TObject); (VAR insertPt: TInsertionPoint; (BEGIN ,insertPt := TInsertionPoint(obj); ,IF insertPt.view.OKToDrawIn(insertPt.textImage.extentLRect) THEN 0insertPt.panel.Highlight(insertPt, hOffToOn); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.amTyping AND NOT SELF.justReturned THEN ,BEGIN ,textImage := SELF.textImage; ,text := textImage.text; ,diff := SELF.newestLP - SELF.textRange.firstLP; ,lp := Min(SELF.textRange.firstLP, SELF.newestLP); ,SELF.MarkChanged; ,SELF.textRange.firstPara.EachImage(AddDiff); ,{set up textImage fields for minimum rectangle erase of first update line} ,paraImage := textImage.ImageWith(SELF.textRange.firstPara, lp); ,IF paraImage <> NIL THEN 0BEGIN 0paraImage.LocateLP(lp, startLine, startPixel); 0textImage.firstLinePixel := startPixel; 0textImage.useFirstPixel := TRUE; 0END ,ELSE 0textImage.useFirstPixel := FALSE; ,SELF.textRange.firstLP := SELF.newestLP; ,SELF.textRange.lastLP := SELF.newestLP; ,IF SELF.typingCmd <> NIL THEN 0IF SELF.typingCmd.otherInsPts <> NIL THEN 4SELF.typingCmd.otherInsPts.Each(AdjustOtherInsPts); ,text.RecomputeImages; ,{If view.OKToDrawIn was TRUE then we won't be going through the update cycle and hence the -ToolKit won't tell us to highlight, so we'll have to highlight ourselves} ,IF SELF.view.OKToDrawIn(SELF.textImage.extentLRect) THEN 0SELF.panel.Highlight(SELF, hOffToOn); ,IF SELF.typingCmd <> NIL THEN 0IF SELF.typingCmd.otherInsPts <> NIL THEN 4SELF.typingCmd.otherInsPts.Each(HiliteOtherInsPts); ,END; (deferUpdate := FALSE; (SELF.justReturned := FALSE; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TInsertionPoint.KeyReturn; $VAR para1: TEditPara; (newPara: TEditPara; (selSize: INTEGER; (PROCEDURE InsPara; (VAR styleChange: TStyleChange; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,para1 := SELF.textRange.firstPara; ,selSize := para1.size - SELF.textRange.firstLP; ,newPara := SELF.textImage.NewEditPara(selSize, para1.format); ,newPara.StartEdit(newPara.GrowSize); ,newPara.ReplPara(0, 0, para1, SELF.textRange.firstLP, selSize); ,IF TFakeTStyle(newPara.format.dfltTStyle) <> TFakeTStyle(SELF.currTypeStyle) THEN 0BEGIN 0styleChange.lp := -1; 0styleChange.newStyle := SELF.currTypeStyle; 0newPara.typeStyles.PutAt(1, @styleChange); 0END; ,para1.ReplPString(SELF.textRange.firstLP, selSize, NIL); ,para1.StopEdit; ,SELF.textImage.text.InsParaAfter(para1, newPara); ,{$IFC fTrace}EP;{$ENDC} (END; (PROCEDURE Adjust; ,PROCEDURE AdjustOtherInsPts(obj: TObject); ,VAR insertPt: TInsertionPoint; ,BEGIN 0insertPt := TInsertionPoint(obj); 0WITH insertPt, textRange DO 4BEGIN 4firstLP := 0; 4lastLP := 0; 4firstIndex := SELF.textRange.firstIndex; 4lastIndex := firstIndex; 4firstPara := newPara; 4lastPara := newPara; 4END; ,END; (BEGIN ,{$IFC fTrace}BP(10);{$ENDC} ,WITH SELF.textRange DO 0BEGIN 0firstPara := newPara; 0lastPara := newPara; 0firstIndex := firstIndex + 1; 0lastIndex := firstIndex; 0firstLP := 0; 0lastLP := 0; 0END; ,SELF.newestLP := 0; ,SELF.justReturned := TRUE; ,WITH SELF.typingCmd DO 0newParaCount := newParaCount + 1; ,IF SELF.typingCmd.otherInsPts <> NIL THEN 0SELF.typingCmd.otherInsPts.Each(AdjustOtherInsPts); ,deferUpdate := FALSE; ,SELF.textImage.useFirstPixel := FALSE; ,{$IFC fTrace}EP;{$ENDC} (END; (PROCEDURE HiliteOtherInsPts(obj: TObject); (VAR insertPt: TInsertionPoint; (BEGIN ,insertPt := TInsertionPoint(obj); ,IF insertPt.view.OKToDrawIn(insertPt.textImage.extentLRect) THEN 0insertPt.panel.Highlight(insertPt, hOffToOn); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.KeyText; (SELF.ChangeText(InsPara, Adjust); ({If view.OKToDrawIn was TRUE then we won't be going through the update cycle and hence the )ToolKit won't tell us to highlight, so we'll have to highlight ourselves} (IF SELF.view.OKToDrawIn(SELF.textImage.extentLRect) THEN ,SELF.panel.Highlight(SELF, hOffToOn); (IF SELF.typingCmd.otherInsPts <> NIL THEN ,SELF.typingCmd.otherInsPts.Each(HiliteOtherInsPts); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TInsertionPoint.KeyTab; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.KeyChar(' '); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TInsertionPoint.MarkChanged; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.newestLP < SELF.textRange.firstLP THEN ,BEGIN ,SELF.textRange.firstLP := SELF.newestLP; ,SELF.textRange.lastLP := SELF.newestLP; ,SUPERSELF.MarkChanged; ,END (ELSE ,BEGIN ,SUPERSELF.MarkChanged; ,SELF.textRange.firstLP := SELF.newestLP; ,SELF.textRange.lastLP := SELF.newestLP; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TInsertionPoint.MouseMove(mouseLPt: LPoint); $VAR currPImage: TParaImage; (currLP: INTEGER; (multiParaSelection: TMultiParaSelection; (oneParaSelection: TOneParaSelection; (textImage: TTextImage; (firstTxtImg: TTextImage; (paraIndex: LONGINT; (wasParaSel: BOOLEAN; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.currLPt := mouseLPt; (IF NOT EqualLPt(mouseLPt, SELF.anchorLPt) THEN ,BEGIN ,textImage := SELF.textImage.FindTextImage(mouseLPt, firstTxtImg); ,textImage.FindParaAndLp(mouseLPt, currPImage, paraIndex, currLP); ,IF (currPImage.paragraph <> SELF.textRange.firstPara) THEN 0BEGIN 0{Turn insertion point off if necessary} 0wasParaSel := SELF.isParaSelection; 0IF NOT wasParaSel AND (paraIndex > SELF.textRange.firstIndex) THEN 4SELF.textImage.text.HiliteRange(hOnToOff, SELF.textRange, FALSE); 0{call new with same paragraph, followed by MouseMove so highlighting will work correctly 1and so MouseMove can figure out if currPImage is before of after SELF.textRange.firstPara} 0WITH SELF, textRange DO 4{$H-} {ought to be safe: no VAR params, etc} 4multiParaSelection := TMultiParaSelection(SELF.FreedAndReplacedBy( LTMultiParaSelection.CREATE(NIL, SELF.Heap, Pview, firstTxtImg, anchorLPt, PfirstPara, firstIndex, firstLP, PfirstPara, firstIndex, firstLP, TRUE))); 4{$H+} 0multiParaSelection.isParaSelection := wasParaSel; 0multiParaSelection.MouseMove(mouseLPt); 0END ,ELSE IF (currLP <> SELF.textRange.firstLP) THEN 0BEGIN 0{Turn insertion point off first} 0SELF.textImage.text.HiliteRange(hOnToOff, SELF.textRange, FALSE); 0{call CREATE with same LP for begin and end, 4followed by MouseMove so highlighting will work correctly} 0WITH SELF, textRange DO 4{$H-} {ought to be safe: no VAR params, etc} 4oneParaSelection := TOneParaSelection(SELF.FreedAndReplacedBy( LTOneParaSelection.CREATE(NIL, SELF.Heap, Pview, firstTxtImg, anchorLPt, PfirstPara, firstIndex, firstLP, firstLP))); 4{$H+} 0oneParaSelection.MouseMove(mouseLPt); 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtWrm} $PROCEDURE TInsertionPoint.MousePress(mouseLPt: LPoint); $VAR first, last: INTEGER; (oneParaSelection: TOneParaSelection; (funnnyInsPoint: TInsertionPoint; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF clickState.fShift THEN ,SELF.MouseMove(mouseLPt) (ELSE IF clickState.clickCount = 2 THEN {double click} ,BEGIN ,{This check should solve the problem of double clicking on the last half of the last -character of a word and not getting the word selected} ,WITH SELF.textRange DO 0BEGIN 0first := firstLP; 0{$H-} 0IF NOT firstPara.Qualifies(first) THEN 4IF first > 0 THEN 8first := first - 1; 0{$H+} 0END; ,SELF.textRange.firstPara.FindWordBounds(first, first, last); ,IF first <> last THEN 0BEGIN 0{Turn insertion point off first} 0SELF.textImage.text.HiliteRange(hOnToOff, SELF.textRange, FALSE); 0WITH SELF, textRange DO 4{$H-} 4oneParaSelection := TOneParaSelection(SELF.FreedAndReplacedBy( LTOneParaSelection.CREATE(NIL, SELF.Heap, Pview, textImage, anchorLPt, PfirstPara, firstIndex, first, last))); 4{$H+} 0WITH oneParaSelection DO 4BEGIN 4anchorbegin := first; 4anchorEnd := last; 4isWordSelection := TRUE; 4END; 0oneParaSelection.textImage.text.HiliteRange(hOffToOn, oneParaSelection.textRange, FALSE); 0END; ,END (ELSE IF clickState.clickCount = 3 THEN {triple click, happens if double click didn't select word} ,BEGIN ,{Turn insertion point off first} ,SELF.textImage.text.HiliteRange(hOnToOff, SELF.textRange, SELF.isParaSelection); ,IF SELF.textRange.firstPara.size = 0 THEN ,{This case precipitates the odd notion of an "insertion point" the width of the textImage; -(ie. when one triple clicks on an empty paragraph) A special check in IdleBegin makes sure -it doesn't blink.} 0BEGIN 0WITH SELF, textRange DO 4{$H-} 4funnnyInsPoint := TInsertionPoint(SELF.FreedAndReplacedBy( LTInsertionPoint.CREATE(NIL, SELF.Heap, Pview, textImage, anchorLPt, PfirstPara, firstIndex, 0))); 4{$H+} 0WITH funnnyInsPoint DO 4BEGIN 4isParaSelection := TRUE; 4isWordSelection := FALSE; 4END; 0funnnyInsPoint.textImage.text.HiliteRange(hOffToOn, SELF.textRange, TRUE); 0END ,ELSE 0BEGIN 0WITH SELF, textRange DO 4{$H-} 4oneParaSelection := TOneParaSelection(SELF.FreedAndReplacedBy( LTOneParaSelection.CREATE(NIL, SELF.Heap, Pview, textImage, anchorLPt, PfirstPara, firstIndex, 0, firstPara.size))); 4{$H+} 0WITH oneParaSelection DO 4BEGIN 4isParaSelection := TRUE; 4isWordSelection := FALSE; 4anchorBegin := 0; 4anchorEnd := textRange.lastLP; 4END; 0oneParaSelection.textImage.text.HiliteRange(hOffToOn, oneParaSelection.textRange, TRUE); 0END; ,END (ELSE ,SELF.textImage.MousePress(mouseLPt); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TInsertionPoint.NewStyleCmd(heap: THeap; cmdNumber: TCmdNumber; DtextImage: TTextImage): TCommand; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} ({Do stuff but set NewStyleCmd NIL so last cmd not committed}; (SELF.styleCmdNumber := cmdNumber; (WITH SELF.currTypeStyle, font DO ,CASE cmdNumber OF 0uPlain: 4onFaces := []; 0uBold: 4onFaces := onFaces + [bold]; 0uItalic: 4onFaces := onFaces + [italic]; 0uUnderline: 4onFaces := onFaces + [underlined]; 0uShadow: 4onFaces := onFaces + [shadow]; 0uOutline: 4onFaces := onFaces + [outline]; 0uModern, uClassic: 4font.fontFamily := cmdNumber - uModern + 1; 0{$IFC LibraryVersion <= 20} 0uFnt0, uFnt1, uFnt2, uFnt3, uFnt4, uFnt5, uFnt6, uFnt7, uFnt8, uFnt9, uFnt10, uFnt11: 4CASE cmdNumber OF 8uFnt0: fontFamily := famSystem; 8uFnt1:  SELF.textImage.text.paragraphs.size) THEN 0BEGIN 0SELF.textImage.text.DelPara(SELF.textRange.firstPara, FALSE); 0SELF.textImage.text.paragraphs.DelObject(SELF.textRange.firstPara, TRUE); 0END ,ELSE 0SELF.textRange.firstPara.ReplPString(SELF.textRange.firstLP, @SELF.textRange.lastLP-SELF.textRange.firstLP, NIL); (END; (PROCEDURE Adjust; ,PROCEDURE Subtract(paraImage: TParaImage); ,BEGIN 0paraImage.AdjustLineLPs(SELF.textRange.firstLP, delta); ,END; (BEGIN ,IF NOT SELF.isParaSelection THEN 0BEGIN 0delta := SELF.textRange.firstLP - SELF.textRange.lastLP; 0SELF.textRange.firstPara.EachImage(Subtract); 0END; ,WITH SELF.textRange DO 0BEGIN 0IF SELF.isParaSelection THEN 4BEGIN 4{$H-} 4firstPara := TEditPara(SELF.textImage.text.paragraphs.At(firstIndex)); 4{$H+} 4firstLP := 0; 4lastPara := firstPara; 4END; 0lastLP := firstLP; 0END; (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.ChangeText(DelText, Adjust); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $FUNCTION TOneParaSelection.DeleteButSave: TText; $VAR oldPara: TEditPara; (selSize: INTEGER; (newPara: TEditPara; (text: TText; (PROCEDURE DelText; (BEGIN ,oldPara := SELF.textRange.firstPara; ,IF SELF.isParaSelection AND 8(SELF.textRange.firstIndex <> SELF.textImage.text.paragraphs.size) THEN 0BEGIN 0SELF.textImage.text.DelPara(oldPara, FALSE); 0SELF.textImage.text.paragraphs.DelObject(oldPara, FALSE); 0newPara := oldPara; 0END ,ELSE 0BEGIN 0selSize := SELF.textRange.lastLP-SELF.textRange.firstLP; 0newPara := SELF.textImage.NewEditPara(selSize, oldPara.format); 0newPara.ReplPara(0, 0, oldPara, SELF.textRange.firstLP, selSize); 0oldPara.ReplPString(SELF.textRange.firstLP, selSize, NIL); 0END; ,text := TText.CREATE(NIL, SELF.Heap, NIL); ,text.paragraphs.InsLast(newpara); (END; (PROCEDURE Adjust; ,PROCEDURE Subtract(paraImage: TParaImage); ,BEGIN 0paraImage.AdjustLineLPs(SELF.textRange.firstLP, -selSize); ,END; (BEGIN ,WITH SELF.textRange DO 0BEGIN 0IF SELF.isParaSelection THEN 4BEGIN 4{$H-} 4firstPara := TEditPara(SELF.textImage.text.paragraphs.At(firstIndex)); 4{$H+} 4firstLP := 0; 4lastPara := firstPara; 4END; 0lastLP := firstLP; 0END; ,IF NOT SELF.isParaSelection THEN 0SELF.textRange.firstPara.EachImage(Subtract); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.ChangeText(DelText, Adjust); (DeleteButSave := text; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TOneParaSelection.MouseMove(mouseLPt: LPoint); ({ assumes highlighting is ON } $VAR currPImage: TParaImage; (currLP: INTEGER; (oldLP: INTEGER; { end (ie. not the anchor) of indication } (multiParaSelection: TMultiParaSelection; (textImage: TTextImage; (firstTxtImg: TTextImage; (first, last: INTEGER; (paraSelect: BOOLEAN; (paraIndex: LONGINT; (PROCEDURE HiExtOnPads(highTransit: THighTransit; startLP,endLP: INTEGER); (BEGIN ,SELF.textImage.text.HiliteParagraphs(highTransit, SELF.textRange.firstIndex, startLP, ^SELF.textRange.firstIndex, endLP, ^SELF.isParaSelection); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.currLPt := mouseLPt; (textImage := SELF.textImage.FindTextImage(mouseLPt, firstTxtImg); (textImage.FindParaAndLp(mouseLPt, currPImage, paraIndex, currLP); (IF currPImage.paragraph <> SELF.textRange.firstPara THEN ,BEGIN ,{call new with same paraImage, followed by MouseMove so highlighting will work correctly} ,paraSelect := SELF.isParaSelection; ,first := SELF.anchorBegin; ,last := SELF.anchorEnd; ,WITH SELF, textRange DO 0{$H-} 0multiParaSelection := TMultiParaSelection(SELF.FreedAndReplacedBy( HTMultiParaSelection.CREATE(NIL, SELF.Heap, Lview, firstTxtImg, anchorLPt, LfirstPara, firstIndex, firstLP, LfirstPara, firstIndex, lastLP, firstLP = anchorBegin))); 0{$H+} ,WITH multiParaSelection DO 0BEGIN 0isParaSelection := paraSelect; 0anchorBegin := first; 0anchorEnd := last; 0isWordSelection := NOT paraSelect AND (first <> last); 0END; ,multiParaSelection.MouseMove(mouseLPt); ,END (ELSE IF NOT SELF.isParaSelection THEN ,BEGIN ,IF SELF.isWordSelection THEN 0BEGIN 0{So dragging over last half of last character of word doesn't select space} 0WITH SELF.textRange DO 4BEGIN 4{$H-} 4IF NOT firstPara.Qualifies(currLP) THEN 8IF currLP > 0 THEN  SELF.textRange.lastLP THEN 4HiExtOnPads(hOnToOff, SELF.anchorEnd, SELF.textRange.lastLP); 0SELF.textRange.firstLP := currLP; 0SELF.textRange.lastLP := SELF.anchorEnd; 0END ,ELSE 0BEGIN 0oldLP := SELF.textRange.lastLP; 0IF SELF.anchorBegin <> SELF.textRange.firstLP THEN 4HiExtOnPads(hOnToOff, SELF.textRange.firstLP, SELF.anchorBegin); 0SELF.textRange.firstLP := SELF.anchorBegin; 0SELF.textRange.lastLP := currLP; 0END; ,IF currLP <> oldLP THEN 0IF currLP < oldLP THEN 4HiExtOnPads(hOffToOn, currLP, oldLP) 0ELSE 4HiExtOnPads(hOffToOn, oldLP, currLP); ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TOneParaSelection.MousePress(mouseLPt: LPoint); $VAR first, last: INTEGER; (oneParaSelection: TOneParaSelection; (multiParaSelection: TMultiParaSelection; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF clickState.fShift THEN ,SELF.MouseMove(mouseLPt) (ELSE IF clickState.clickCount = 2 THEN {double click} ,BEGIN ,{should select words at beginning and end of current selection (later)} ,SELF.textRange.firstPara.FindWordBounds(SELF.anchorBegin, first, last); ,SELF.textImage.text.HiliteRange(hOnToOff, SELF.textRange, SELF.isParaSelection); ,WITH SELF, textRange DO 0{$H-} 0oneParaSelection := TOneParaSelection(SELF.FreedAndReplacedBy( HTOneParaSelection.CREATE(NIL, SELF.Heap, Lview, textImage, anchorLPt, LfirstPara, firstIndex, first, last))); 0{$H+} ,WITH oneParaSelection DO 0BEGIN 0anchorBegin := first; 0anchorEnd := last; 0isWordSelection := TRUE; 0END; ,oneParaSelection.textImage.text.HiliteRange(hOnToOff, oneParaSelection.textRange, lSELF.isParaSelection); ,END (ELSE IF clickState.clickCount = 3 THEN {triple click} ,BEGIN ,{Turn current highlighting off first} ,SELF.textImage.text.HiliteRange(hOnToOff, SELF.textRange, SELF.isParaSelection); ,WITH SELF, textRange DO 0{$H-} 0oneParaSelection := TOneParaSelection(SELF.FreedAndReplacedBy( HTOneParaSelection.CREATE(NIL, SELF.Heap, Lview, textImage, anchorLPt, LfirstPara, firstIndex, 0, firstPara.size))); 0{$H+} ,WITH oneParaSelection DO 0BEGIN 0isParaSelection := TRUE; 0isWordSelection := FALSE; 0anchorBegin := 0; 0anchorEnd := textRange.lastLP; 0END; ,oneParaSelection.textImage.text.HiliteRange(hOnToOff, oneParaSelection.textRange, TRUE); ,END (ELSE ,SELF.textImage.MousePress(mouseLPt); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TOneParaSelection.MouseRelease; $VAR insPt: TInsertionPoint; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.textRange.firstLP = SELF.textRange.lastLP THEN ,BEGIN ,insPt := SELF.BecomeInsertionPoint; ,insPt.textImage.text.HiliteRange(hOffToOn, insPt.textRange, SELF.isParaSelection); ,END (ELSE ,SELF.textImage.text.ChangeSelInOtherPanels(SELF); (SUPERSELF.MouseRelease; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TOneParaSelection.SelSize: INTEGER; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} (SelSize := SELF.textRange.lastLP - SELF.textRange.firstLP; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtHot} $PROCEDURE TOneParaSelection.StyleFromContext; $VAR typeStyle: TTypeStyle; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} (SELF.textRange.firstPara.StyleAt(SELF.textRange.firstLP, typeStyle); (SELF.currTypeStyle := typeStyle; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {Methods of TOneParaSelection} METHODS OF TMultiParaSelection; {$S SgTxtCld} $FUNCTION TMultiParaSelection.CREATE(object: TObject; heap: THeap; itsView: TView; HitsTextImage: TTextImage; itsAnchorLPt: LPoint; HbeginPara: TEditPara; beginIndex: LONGINT; beginLP: INTEGER; HendPara: TEditPara; endIndex: LONGINT; endLP: INTEGER; HbeginIsAnchor: BOOLEAN): TMultiParaSelection; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TMultiParaSelection(TTextSelection.CREATE(object, heap, itsView, itsTextImage, itsAnchorLPt, LbeginPara, beginIndex, beginLP, LendPara, endIndex, endLP)); (WITH SELF DO ,BEGIN ,IF beginIsAnchor THEN 0BEGIN 0anchorPara := beginPara; 0anchorIndex := beginIndex; 0anchorBegin := beginLP; 0anchorEnd := beginLP; 0END ,ELSE 0BEGIN 0anchorPara := endPara; 0anchorIndex := endIndex; 0anchorBegin := endLP; 0anchorEnd := endLP; 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fTextTrace} $PROCEDURE TMultiParaSelection.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (TTextSelection.Fields(Field); (Field('anchorPara: TEditPara'); (Field('anchorIndex: LONGINT'); (Field('anchorBegin: INTEGER'); (Field('anchorEnd: INTEGER'); (Field(''); $END; {$ENDC} {$S SgTxtCld} $PROCEDURE TMultiParaSelection.ChangeStyle(cmdNumber: TCmdNumber); $VAR newTypeStyle: TTypeStyle; (s: TListScanner; (paragraph: TEditPara; (lastPara: TEditPara; (endRng: INTEGER; (paraImage: TParaImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (newTypeStyle := SELF.currTypeStyle; (lastPara := SELF.textRange.lastPara; (s := SELF.textImage.text.paragraphs.ScannerFrom(SELF.textRange.firstIndex-1, scanForward); (WHILE s.Scan(paragraph) DO ,IF paragraph = SELF.textRange.firstPara THEN 0BEGIN 0SELF.DoChangeStyle(cmdNumber, paragraph, SELF.textRange.firstLP, Hparagraph.size, newTypeStyle); 0SELF.currTypeStyle := newTypeStyle; 0IF paragraph = lastPara THEN 4s.Done; 0END ,ELSE 0BEGIN 0IF paragraph = lastPara THEN 4BEGIN 4endRng := SELF.textRange.lastLP; 4s.Done; 4END 0ELSE 4endRng := paragraph.size; 0SELF.DoChangeStyle(cmdNumber, paragraph, 0, endRng, newTypeStyle); 0END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} ${CopySelf is used for copying to the clipboard} $FUNCTION TMultiParaSelection.CopySelf(heap: THeap; view: TView): TMultiParaSelection; $VAR srcPara: TEditPara; (cpyPara: TEditPara; (cpyFirstPara: TEditPara; (srcLastPara: TEditPara; (cpyLastPara: TEditPara; (selSize1: INTEGER; (selSize2: INTEGER; (textImage: TTextImage; (s: TListScanner; (text: TText; (textRange: TTextRange; (imageLRect: LRect; $BEGIN ({$IFC fTrace}BP(11);{$ENDC} (text := TText.CREATE(NIL, heap, TStyleSheet.CREATE(NIL, heap)); (imageLRect := view.extentLRect; (InsetLRect(imageLRect, cHorizMargin, cVertMargin); (textImage := SELF.textImage.TxtImgForClipBoard(heap, view, imageLRect, text, TRUE); (textImage.minHeight := 0; (text.txtImgList.InsLast(textImage); (textRange := SELF.textRange; (srcPara := textRange.firstPara; (selSize1 := srcPara.size-textRange.firstLP; (cpyPara := textImage.NewEditPara(selSize1, TParaFormat(srcPara.format.clone(heap))); (cpyPara.ReplPara(0, 0, srcPara, textRange.firstLP, selSize1); (cpyFirstPara := cpyPara; (textImage.text.paragraphs.InsLast(cpyFirstPara); (IF textRange.firstPara <> textRange.lastPara THEN ,BEGIN ,srcLastPara := textRange.lastPara; ,selSize2 := textRange.lastLP; ,cpyLastPara := textImage.NewEditPara(selSize2, TParaFormat(srcLastPara.format.clone(heap))); ,cpyLastPara.ReplPara(0, 0, srcLastPara, 0, selSize2); ,{skip first paragraph by not subtracting one from firstIndex} ,s := SELF.textImage.text.paragraphs.ScannerFrom(textRange.firstIndex, scanForward); ,WHILE s.Scan(srcPara) DO 0BEGIN 0IF srcPara = textRange.lastPara THEN 4BEGIN 4cpyPara := cpyLastPara; 4s.Done; 4END 0ELSE 4BEGIN 4cpyPara := textImage.NewEditPara(srcPara.size, HTParaFormat(srcPara.format.clone(heap))); 4cpyPara.ReplPara(0, 0, srcPara, 0, srcPara.size); 4END; 0textImage.text.paragraphs.InsLast(cpyPara); 0END; ,END; (textImage.RecomputeImages(actionNone, TRUE); (WITH textImage.extentLRect DO ,view.extentLRect.bottom := bottom - top + 2 * cVertMargin; (CopySelf := TMultiParaSelection.CREATE(NIL, heap, view, textImage, zeroLPt, LTEditPara(textImage.text.paragraphs.First), 1, 0, LTEditPara(textImage.text.paragraphs.Last), LtextRange.lastIndex - textRange.firstIndex + 1, LselSize2, TRUE); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TMultiParaSelection.Delete(saveIt: BOOLEAN): TText; $VAR firstPara: TEditPara; (lastPara: TEditPara; (paragraph: TEditPara; (text: TText; (paraList: TList; (s: TListScanner; (selSize: INTEGER; (textRange: TTextRange; (numParas: INTEGER; (PROCEDURE DelText; (BEGIN ,{$IFC fTrace}BP(11);{$ENDC} ,{If saveIt is TRUE, we want to save the text we're deleting, so create a text object} ,IF saveIt THEN 0BEGIN 0text := TText.CREATE(NIL, SELF.Heap, NIL); 0paraList := text.paragraphs; 0END ,ELSE 0text := NIL; ,textRange := SELF.textRange; ,firstPara := textRange.firstPara; ,lastPara := textRange.lastPara; ,numParas := SELF.textImage.text.paragraphs.size; ,{If the last paragraph is selected, treat this like a non-para selection, so that one -empty para will be left at the end after the delete} ,IF textRange.lastIndex = numParas THEN 0SELF.isParaSelection := FALSE; ,s := SELF.textImage.text.paragraphs.ScannerFrom(textRange.firstIndex-1, scanForward); ,WHILE s.Scan(paragraph) DO 0IF paragraph = firstPara THEN 4BEGIN 4IF SELF.isParaSelection THEN 8{If isParaSelection is TRUE then insert it in our save list and 9delete it from the textImage's list} 8BEGIN 8IF saveIt THEN  1 THEN 0BEGIN 0newIndex := oldIndex - 1; 0newLP := TEditPara(SELF.textImage.text.paragraphs.At(newIndex)).size; 0END ,ELSE 0BEGIN 0newIndex := oldIndex; 0newLP := oldLP; 0END; (END; (PROCEDURE HiExtOnPads(highTransit: THighTransit; DstartIndex: LONGINT; startLP: INTEGER; DendIndex: LONGINT; endLP: INTEGER); (BEGIN ,SELF.textImage.text.HiliteParagraphs(highTransit, startIndex, startLP, endIndex, endLP, lSELF.isParaSelection); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.currLPt := mouseLPt; ({$IFC fTextTrace} (IF fTextTrace THEN ,BEGIN ,LIntToHex(ORD(SELF.textRange.firstPara), @str1); ,LIntToHex(ORD(SELF.textRange.lastPara), @str2); ,Writeln; ,Writeln('*** MultiPara MouseMove: firstPara, lastPara = (', str1, ',', str2, ')'); ,Writeln('*** About to call FindParaAndLp'); ,END; ({$ENDC} (textRange := SELF.textRange; (textImage := SELF.textImage.FindTextImage(mouseLPt, firstTxtImg); (SELF.textImage := firstTxtImg; (textImage.FindParaAndLp(mouseLPt, currPImage, currIndex, currLP); (currPara := currPImage.paragraph; (IF SELF.isParaSelection THEN ,BEGIN ,IF currIndex < SELF.anchorIndex THEN 0currLP := 0 ,ELSE 0currLP := currPara.size; ,END (ELSE IF SELF.isWordSelection THEN ,BEGIN ,currPara.FindWordBounds(currLP, first, last); ,IF currIndex < SELF.anchorIndex THEN 0currLP := first ,ELSE IF currIndex > SELF.anchorIndex THEN 0currLP := last ,ELSE IF first <= SELF.anchorBegin THEN 0currLP := first ,ELSE 0currLP := last; ,END; (IF currIndex = SELF.anchorIndex THEN ,mouseBeforeAnchor := currLP < SELF.anchorBegin (ELSE ,mouseBeforeAnchor := currIndex < SELF.anchorIndex; (beginIsAnchor := (textRange.firstIndex = SELF.anchorIndex) AND (textRange.firstLP = SELF.anchorBegin); ({After determining if the mouse is before or after the anchor position, set up variables for )higlighting below and dehilite any text that was on other side of the anchor previous to this )mouse move} (IF mouseBeforeAnchor THEN ,BEGIN ,oldIndex := textRange.firstIndex; ,oldLP := textRange.firstLP; ,IF beginIsAnchor THEN 0{current Position is on other side of anchor, so must dehighlight} 0BEGIN 0IF SELF.isParaSelection THEN 4IF SELF.anchorIndex = textRange.lastIndex THEN 8startIndex := -1 4ELSE 8NextIndex(SELF.anchorIndex, SELF.anchorEnd, startIndex, startLP) 0ELSE 4BEGIN 4startIndex := SELF.anchorIndex; 4startLP := SELF.anchorEnd; 4END; 0IF startIndex > 0 THEN 4HiExtOnPads(hOnToOff, startIndex, startLP, textRange.lastIndex, textRange.lastLP); 0END; ,WITH SELF, textRange DO 0BEGIN 0firstPara := currPara; 0firstIndex := currIndex; 0lastPara := anchorPara; 0lastIndex := anchorIndex; 0firstLP := currLP; 0lastLP := anchorEnd; 0END; ,END (ELSE ,BEGIN ,oldIndex := textRange.lastIndex; ,oldLp := textRange.lastLP; ,IF NOT beginIsAnchor THEN 0BEGIN 0{current Position is on other side of anchor, so must dehighlight} 0IF SELF.isParaSelection THEN 4PrevIndex(SELF.anchorIndex, SELF.anchorBegin, startIndex, startLP) 0ELSE 4BEGIN 4startIndex := SELF.anchorIndex; 4startLP := SELF.anchorBegin; 4END; 0HiExtOnPads(hOnToOff, textRange.firstIndex, textRange.firstLP, startIndex, startLP); 0END; ,WITH SELF, textRange DO 0BEGIN 0lastPara := currPara; 0lastIndex := currIndex; 0firstPara := anchorPara; 0firstIndex := anchorIndex; 0firstLP := anchorBegin; 0lastLP := currLP; 0END; ,END; (IF mouseBeforeAnchor = beginIsAnchor THEN ,oldBeforeCurr := NOT mouseBeforeAnchor (ELSE IF currIndex = oldIndex THEN ,oldBeforeCurr := oldLP < currLP (ELSE ,oldBeforeCurr := oldIndex < currIndex; (IF oldBeforeCurr THEN ,BEGIN ,startIndex := oldIndex; ,startLP := oldLP; ,endIndex := currIndex; ,endLP := currLP; ,END (ELSE ,BEGIN ,startIndex := currIndex; ,startLP := currLP; ,endIndex := oldIndex; ,endLP := oldLP; ,END; (selChanged := TRUE; (IF SELF.isParaSelection THEN ,IF startIndex = endIndex THEN 0selChanged := FALSE ,ELSE IF mouseBeforeAnchor THEN 0PrevIndex(endIndex, endLP, endIndex, endLP) ,ELSE 0NextIndex(startIndex, startLP, startIndex, startLP) (ELSE ,selChanged := (startIndex <> endIndex) OR (startLP <> endLP); (IF selChanged THEN ,HiExtOnPads(hOffToOn, startIndex, startLP, endIndex, endLP); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TMultiParaSelection.MousePress(mouseLPt: LPoint); $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF clickState.fShift THEN ,SELF.MouseMove(mouseLPt) (ELSE IF clickState.clickCount > 1 THEN ,BEGIN ,{For now do nothing if some jerk starts double/triple clicking while dragging} ,END (ELSE ,SELF.textImage.MousePress(mouseLPt); ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TMultiParaSelection.MouseRelease; $VAR insPt: TInsertionPoint; (oneParaSel: TOneParaSelection; (first,last: INTEGER; (isPara: BOOLEAN; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.textRange.firstPara = SELF.textRange.lastPara THEN ,BEGIN ,isPara := SELF.isParaSelection; ,IF SELF.textRange.firstLP = SELF.textRange.lastLP THEN 0BEGIN 0insPt := SELF.BecomeInsertionPoint; 0insPt.isParaSelection := isPara; 0IF NOT isPara THEN 4insPt.textImage.text.HiliteRange(hOffToOn, insPt.textRange, FALSE); 0END ,ELSE 0BEGIN 0first := SELF.anchorBegin; 0last := SELF.anchorEnd; 0WITH SELF, textRange DO 4{$H-} 4oneParaSel := TOneParaSelection(SELF.FreedAndReplacedBy(TOneParaSelection.CREATE(NIL, LSELF.Heap, view, textImage, anchorLPoint, LfirstPara, firstIndex, firstLP, lastLP))); 4{$H+} 0WITH oneParaSel DO 4BEGIN 4anchorBegin := first; 4anchorEnd := last; 4isParaSelection := isPara; 4isWordSelection := NOT isPara AND (first <> last); 4END; 0SELF.textImage.text.ChangeSelInOtherPanels(oneParaSel); 0END; ,END (ELSE ,SELF.textImage.text.ChangeSelInOtherPanels(SELF); (SUPERSELF.MouseRelease; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $FUNCTION TMultiParaSelection.SelSize: INTEGER; $VAR size: INTEGER; (s: TListScanner; (paragraph: TEditPara; $BEGIN ({$IFC fTrace}BP(9);{$ENDC} (IF SELF.textRange.firstPara = SELF.textRange.lastPara THEN ,size := SELF.textRange.lastLP - SELF.textRange.firstLP (ELSE ,BEGIN ,size := SELF.textRange.firstPara.size - SELF.textRange.firstLP; ,{skip first paragraph by not subtracting one from firstIndex} ,s := SELF.textImage.text.paragraphs.ScannerFrom(SELF.textRange.firstIndex, scanForward); ,WHILE s.Scan(paragraph) DO 0IF paragraph = SELF.textRange.lastPara THEN 4BEGIN 4size := size + SELF.textRange.lastLP; 4s.Done; 4END 0ELSE 4size := size + paragraph.size; ,END; (SelSize := size; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} $PROCEDURE TMultiParaSelection.StyleFromContext; $VAR typeStyle: TTypeStyle; $BEGIN ({$IFC fTrace}BP(8);{$ENDC} (SELF.textRange.firstPara.StyleAt(SELF.textRange.firstLP, typeStyle); (SELF.currTypeStyle := typeStyle; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {Methods of TMultiParaSelection} {$S SgTxtCld} METHODS OF TClearTextCmd; $FUNCTION TClearTextCmd.CREATE(object: TObject; heap: THeap; itsCmdNumber: TCmdNumber; HitsImage: TImage; itsText: TText): TClearTextCmd; $BEGIN ({$IFC fTrace}BP(11);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TClearTextCmd(TCommand.CREATE(object, heap, itsCmdNumber, itsImage, TRUE, revealAll)); (WITH SELF DO ,BEGIN ,savedText := NIL; ,text := itsText; ,END; ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TClearTextCmd.Free; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (IF SELF.savedText <> NIL THEN ,SELF.savedText.FreeSelf(FALSE); (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$IFC fTextTrace} $PROCEDURE TClearTextCmd.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('savedText: TText'); (Field('text: TText'); (Field(''); $END; {$ENDC} $PROCEDURE TClearTextCmd.Commit; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (Free(SELF.savedText); (SELF.savedText := NIL; ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TClearTextCmd.Perform(cmdPhase: TCmdPhase); $var textSel: TTextSelection; (insertionPt: TInsertionPoint; (text: TText; (selection: TSelection; (panel: TPanel; ({$IFC fTextTrace} (junk: TObject; (str1: STR255; (str2: STR255; ({$ENDC} $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (panel := SELF.image.view.panel; (text := SELF.text; (CASE cmdPhase OF ,doPhase, redoPhase: 0BEGIN 0selection := panel.selection; 0WHILE selection.coSelection <> NIL DO 4selection := selection.coSelection; 0{$IFC fTextTrace} 0IF fTextTrace THEN 4BEGIN 4LIntToHex(ORD(selection), @str1); 4Writeln('*** Clear Cmd Perfrom; panel last coselection = ', str1); 4junk := SELF.text.paragraphs.First; {So can set break point here} 4END; 0{$ENDC} 0textSel := TTextSelection(selection.FreedAndReplacedBy( Dtext.SelectAll(TTextSelection(selection).textImage))); 0text.ChangeSelInOtherPanels(textSel); 0text.HiliteRange(hOffToOn, textSel.textRange, FALSE); 0text := textSel.DeleteButSave; 0SELF.savedText := text; 0insertionPt := textSel.BecomeInsertionPoint; 0{$IFC fTextTrace} 0IF fTextTrace THEN 4BEGIN 4LIntToHex(ORD(insertionPt), @str1); 4Writeln('*** Clear Cmd Perfrom; final insertionPt = ', str1); 4junk := SELF.text.paragraphs.First; {So can set break point here} 4END; 0{$ENDC} 0END; ,undoPhase: 0BEGIN 0selection := panel.selection; 0WHILE selection.coSelection <> NIL DO 4selection := selection.coSelection; 0insertionPt := TInsertionPoint(selection); 0insertionPt.InsertText(SELF.savedText, FALSE, FALSE, FALSE); 0Free(SELF.savedText); 0SELF.savedtext := NIL; 0{$$ Need to hilte before, after?} 0SELF.text.ChangeSelInOtherPanels(insertionPt); 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {METHODS OF TClearTextCmd} {$S SgTxtCld} METHODS OF TStyleCmd; $FUNCTION TStyleCmd.CREATE(object: TObject; heap: THeap; itsCmdNumber: TCmdNumber; @itsImage: TImage; @itsFirstIndex: LONGINT; itsLastIndex: LONGINT; @itsLPFirst: INTEGER; itsLPLast: INTEGER; @itsSelection: TTextSelection): TStyleCmd; $VAR sel: TTextSelection; $BEGIN ({$IFC fTrace}BP(11);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TStyleCmd(TCommand.CREATE(object, heap, itsCmdNumber, itsImage, TRUE, revealSome)); (sel := TTextSelection(itsSelection.Clone(SELF.Heap)); (WITH SELF DO ,BEGIN ,textSelection := sel; ,text := sel.textImage.text; ,firstFiltParaIndex := itsFirstIndex; ,lastFiltParaIndex := itsLastIndex; ,filtFirstLP := itsLPFirst; ,filtLastLP := itsLPLast; ,currFilteredPara := NIL; ,filteredStyles := NIL; ,END; ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TStyleCmd.Free; $VAR sPar: TListScanner; (paragraph: TEditPara; (paraImage: TParaImage; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (sPar := SELF.text.paragraphs.ScannerFrom(SELF.firstFiltParaIndex - 1, scanForward); (WHILE sPar.Scan(paragraph) DO ,BEGIN ,paragraph.beingFiltered := FALSE; ,IF sPar.position = SELF.lastFiltParaIndex THEN 0sPar.Done; ,END; (SELF.textSelection.Free; (Free(SELF.filteredStyles); (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$IFC fTextTrace} $PROCEDURE TStyleCmd.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('text: TText'); (Field('textSelection: TTextSelection'); (Field('firstFiltParaIndex: LONGINT'); (Field('lastFiltParaIndex: LONGINT'); (Field('filtFirstLP: INTEGER'); (Field('filtLastLP: INTEGER'); (Field('currFilteredPara: TEditPara'); (Field('filteredStyles: TArray'); (Field(''); $END; {$ENDC} $PROCEDURE TStyleCmd.Commit; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (SELF.textSelection.ChangeStyle(SELF.cmdNumber); ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TStyleCmd.FilterAndDo(actualObject: TObject; HPROCEDURE DoToObject(filteredObject: TObject)); $VAR savedStyles: TArray; (paragraph: TEditPara; (typeStyle: TTypeStyle; (firstLP: INTEGER; (lastLP: INTEGER; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (paragraph := TParaImage(actualObject).paragraph; (IF paragraph.beingFiltered THEN ,BEGIN ,IF paragraph = SELF.currFilteredPara THEN 0BEGIN 0savedStyles := paragraph.typeStyles; 0paragraph.typeStyles := SELF.filteredStyles; 0END ,ELSE 0BEGIN 0IF paragraph = TEditPara(SELF.text.paragraphs.At(SELF.firstFiltParaIndex)) THEN 4firstLP := SELF.filtFirstLP 0ELSE 4firstLP := 0; 0IF paragraph = TEditPara(SELF.text.paragraphs.At(SELF.lastFiltParaIndex)) THEN 4lastLP := SELF.filtLastLP 0ELSE 4lastLP := paragraph.size; 0Free(SELF.filteredStyles); 0savedStyles := TArray(paragraph.typeStyles.Clone(SELF.heap)); 0SELF.textSelection.DoChangeStyle(SELF.cmdNumber, paragraph, firstLP, lastLP, typeStyle); 0SELF.currFilteredPara := paragraph; 0SELF.filteredStyles := paragraph.typeStyles; 0END; ,DoToObject(TParaImage(actualObject)); ,paragraph.typeStyles := savedStyles; ,END (ELSE ,DoToObject(TParaImage(actualObject)); ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TStyleCmd.Perform(cmdPhase: TCmdPhase); $VAR textSelection: TTextSelection; (selection: TSelection; (sPar: TListScanner; (paragraph: TEditPara; ({Need to filter paragraph before asking about its type styles} (PROCEDURE FindFilteredStyle(obj: TObject); ,BEGIN ,textSelection.StyleFromContext; ,END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (selection := SELF.image.view.panel.selection; (WHILE selection.coSelection <> NIL DO ,selection := selection.coSelection; (textSelection := TTextSelection(selection); (IF cmdPhase = doPhase THEN ,BEGIN ,sPar := SELF.text.paragraphs.ScannerFrom(SELF.firstFiltParaIndex - 1, scanForward); ,WHILE sPar.Scan(paragraph) DO 0BEGIN 0paragraph.beingFiltered := TRUE; 0IF sPar.position = SELF.lastFiltParaIndex THEN 4sPar.Done; 0END; ,END; (textSelection.MarkChanged; (textSelection.textImage.text.RecomputeImages; (SELF.FilterAndDo(TParaImage(TEditPara(SELF.text.paragraphs.At(  NIL DO 4selection := selection.coSelection; 0textSel := TTextSelection(selection); 0IF (cmdPhase = redoPhase) AND deleteOriginal THEN 4SELF.text.HiliteRange(hOffToOn, textSel.textRange, textSel.isParaSelection); 0textSel.CutCopy(clipSelection, deleteOriginal); 0END; ,undoPhase: 0BEGIN 0IF deleteOriginal THEN 4BEGIN 4selection := panel.selection; 4WHILE selection.coSelection <> NIL DO 8selection := selection.coSelection; 4insertionPt := TInsertionPoint(selection); 4firstPara := insertionPt.textRange.firstPara; 4firstLP := insertionPt.textRange.firstLP; 4firstIndex := insertionPt.textRange.firstIndex; 4{get the cut text from the clipboard and insert it back into the text} 4multiParaSel := TMultiParaSelection(clipSelection); 4insertionPt.InsertText(multiParaSel.textImage.text, multiParaSel.isParaSelection, dmultiParaSel.isWordSelection, FALSE); 4IF multiParaSel.isParaSelection THEN 8BEGIN 8WITH insertionPt DO  1 THEN >BEGIN >textRange.firstIndex := textRange.firstIndex - 1; >{$H-} >textRange.firstPara := TEditPara(SELF.text.paragraphs.At(textRange.firstIndex)); >textRange.firstLP := textRange.firstPara.size; >{$H+} >END; 8END 4ELSE IF multiParaSel.isWordSelection THEN 8{don't want to select extra blank generated by insert} 8WITH insertionPt DO <{$H-}  NIL THEN ,SELF.savedText.FreeSelf(FALSE); (Free(SELF.pasteRange); (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$IFC fTextTrace} $PROCEDURE TTextPaste.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field('savedText: TText'); (Field('pasteRange: TTextRange'); (Field('text: TText'); (Field('origIsPara: BOOLEAN'); (Field('origIsWord: BOOLEAN'); (Field('clipIsPara: BOOLEAN'); (Field(''); $END; {$ENDC} $PROCEDURE TTextPaste.Commit; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (Free(SELF.savedText); (SELF.savedText := NIL; ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TTextPaste.DoPaste(clipSelection: TSelection; pic: PicHandle; cmdPhase: TCmdPhase); $VAR heap: THeap; (textSel: TTextSelection; (saveTextSel: TTextSelection; (insertionPt: TInsertionPoint; (insPtBefore: TInsertionPoint; (insPtAfter: TInsertionPoint; (text: TText; (firstPara: TEditPara; {bad choice of var names; change later (screws up WITH's)} (firstLP: INTEGER; (firstIndex: LONGINT; (panel: TPanel; (selection: TSelection; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (heap := SELF.Heap; (panel := SELF.image.view.panel; (CASE cmdPhase OF ,doPhase, redoPhase: 0BEGIN 0IF InClass(clipSelection, TTextSelection) OR (clipBoard.hasUniversalText) THEN 4BEGIN 4selection := panel.selection; 4{we know that the last coSelection must be the textSelection since textSelections 5do not have coSelections} 4WHILE selection.coSelection <> NIL DO 8selection := selection.coSelection; 4textSel := TTextSelection(selection); 4SELF.origIsPara := textSel.isParaSelection; 4SELF.origIsWord := textSel.isWordSelection; 4IF InClass(clipSelection, TTextSelection) THEN 8SELF.clipIsPara := TTextSelection(clipSelection).isParaSelection; 4{delete the selected text, leaving an insertion point} 4text := textSel.DeleteButSave; 4SELF.savedText := text; 4insertionPt := textSel.BecomeInsertionPoint; 4WITH SELF, insertionPt DO 8BEGIN 8pasteRange.firstPara := textRange.firstPara; 8pasteRange.firstIndex := textRange.firstIndex; 8pasteRange.firstLP := textRange.firstLP; 8END; 4insertionPt.FinishPaste(clipSelection, pic); 4WITH SELF, insertionPt DO 8IF clipIsPara THEN  NIL DO 4selection := selection.coSelection; 0{build original selection (ie before the paste)} 0textSel := TTextSelection(selection.FreedAndReplacedBy( DinsertionPt.textImage.NewTextSelection( HfirstPara, firstIndex, firstLP, insertionPt.textRange.firstPara, HinsertionPt.textRange.firstIndex, insertionPt.textRange.firstLP))); 0textSel.isParaSelection := SELF.origIsPara; 0textSel.isWordSelection := SELF.origIsWord; 0SELF.text.ChangeSelInOtherPanels(textSel); 0insertionPt.Free; 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {METHODS OF TTextPaste} {$S SgTxtHot} METHODS OF TTypingCmd; $FUNCTION TTypingCmd.CREATE(object: TObject; heap: THeap; itsImage: TImage; DitsText: TText): TTypingCmd; $VAR range: TTextRange; $BEGIN ({$IFC fTrace}BP(11);{$ENDC} (IF object = NIL THEN ,object := NewObject(heap, THISCLASS); (SELF := TTypingCmd(TCommand.CREATE(object, heap, uTyping, itsImage, TRUE, revealAll)); (range := TTextRange.CREATE(NIL, heap, NIL, 0, 0, NIL, 0, 0); {Perform initializes} (WITH SELF DO ,BEGIN ,newCharCount := 0; ,newParaCount := 0; ,text := itsText; ,savedText := NIL; ,typingRange := range; ,otherInsPts := NIL; ,hiliteAfter[doPhase] := FALSE; ,END; ({$IFC fTrace}EP;{$ENDC} $END; $PROCEDURE TTypingCmd.Free; $VAR selection: TSelection; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (Free(SELF.savedText); (selection := SELF.image.view.panel.selection; (WHILE selection.coSelection <> NIL DO ,selection := selection.coSelection; (IF InClass(selection, TInsertionPoint) THEN ,BEGIN ,TInsertionPoint(selection).typingCmd := NIL; ,TInsertionPoint(selection).amTyping := FALSE; ,END; (SELF.typingRange.Free; (IF SELF.otherInsPts <> NIL THEN ,SELF.otherInsPts.FreeObject; (SUPERSELF.Free; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtCld} {$IFC fTextTrace} $PROCEDURE TTypingCmd.Fields(PROCEDURE Field(nameAndType: S255)); $BEGIN (SUPERSELF.Fields(Field); (Field(''); (Field('savedText: TText'); (Field('text: TText'); (Field('newCharCount: INTEGER'); (Field('newParaCount: INTEGER'); (Field('typingRange: TTextRange'); (Field('otherInsPts: TList'); (Field(''); $END; {$ENDC} {$S SgTxtHot} $PROCEDURE TTypingCmd.Perform(cmdPhase: TCmdPhase); $VAR text: TText; (insertionPt: TInsertionPoint; (selection: TSelection; (heap: THeap; (firstPara: TEditPara; (firstLP: INTEGER; (textSel: TTextSelection; (panel: TPanel; (firstIndex: LONGINT; (aList: TList; (typeStyle: TTypeStyle; (PROCEDURE InstallInsPts(obj: TObject); (VAR selection: TSelection; (BEGIN ,selection := TTextImage(obj).view.panel.selection; ,WHILE selection.coSelection <> NIL DO 0selection := selection.coSelection; ,IF selection <> insertionPt THEN 0aList.InsLast(selection); (END; $BEGIN ({$IFC fTrace}BP(10);{$ENDC} (heap := SELF.Heap; (panel := SELF.image.view.panel; (CASE cmdPhase OF ,doPhase, redoPhase: 0BEGIN 0selection := panel.selection; 0WHILE selection.coSelection <> NIL DO 4selection := selection.coSelection; 0textSel := TTextSelection(selection); 0typeStyle := textSel.currTypeStyle; 0{We don't want to delete the entire paragraph if we're typing over it, 1so set isParaSelection to FALSE} 0textSel.isParaSelection := FALSE; (***** Changed following line 4/27/84 13:07 LSR ,BUG: redo of backspace (?) leaves garbage 0deferUpdate := TRUE; *****) 0deferUpdate := (cmdPhase = doPhase) OR (SELF.savedText <> NIL); 0text := textSel.DeleteButSave; 0insertionPt := textSel.BecomeInsertionPoint; 0WITH SELF.typingRange DO 4BEGIN 4firstPara := insertionPt.textRange.firstPara; 4firstIndex := insertionPt.textRange.firstIndex; 4firstLP := insertionPt.textRange.firstLP; 4lastPara := firstPara; 4lastIndex := firstIndex; 4lastLP := firstLP; 4END; 0IF cmdPhase = doPhase THEN 4BEGIN 4WITH insertionPoint DO 8BEGIN 8amTyping := TRUE; 8typingCmd := SELF; 8IF TFakeTStyle(currTypeStyle) <> TFakeTStyle(typeStyle) THEN  1 THEN 8BEGIN 8aList := TList.CREATE(NIL, heap, 0); 8SELF.text.txtImgList.Each(InstallInsPt); 8SELF.otherInsPts := aList; 8END; 4insertionPt.textRange.firstPara.StartEdit(insertionPt.textRange.firstPara.GrowSize); 4END 0ELSE 4BEGIN 4firstPara := insertionPt.textRange.firstPara; 4firstLP := insertionPt.textRange.firstLP; 4firstIndex := insertionPt.textRange.firstIndex; 4{put back the typed text} 4deferUpdate := FALSE; 4insertionPt.InsertText(SELF.savedText, FALSE, FALSE, FALSE); 4Free(SELF.savedText); 4WITH SELF.typingRange DO 8BEGIN 8lastPara := insertionPt.textRange.firstPara; 8lastIndex := insertionPt.textRange.firstIndex; 8lastLP := insertionPt.textRange.firstLP; 8END; 4{build typed selection} 4textSel := TTextSelection(insertionPt.FreedAndReplacedBy( HinsertionPt.textImage.NewTextSelection( KfirstPara, firstIndex, firstLP, insertionPt.textRange.firstPara, KinsertionPt.textRange.firstIndex, insertionPt.textRange.firstLP))); 4SELF.text.ChangeSelInOtherPanels(textSel); 4END; 0{We always need a valid savedText object, even if no characters were initially typed 1over, in case previous characters get backspaced over. See code in KeyBack } 0IF text = NIL THEN 4BEGIN 4text := TText.CREATE(NIL, heap, NIL); 4text.paragraphs.InsLast( @TTextImage(SELF.image).NewEditPara(0, SELF.typingRange.firstPara.format)); 4END; 0SELF.savedText := text; 0END; ,undoPhase: 0BEGIN 0WITH SELF.typingRange DO 4{$H-} 4textSel := TTextImage(SELF.image).NewTextSelection(firstPara, firstIndex, firstLP, glastPara, lastIndex, lastLP); 4{$H+} 0{user feedback: highlight typed text} 0SELF.text.HiliteRange(hOffToOn, SELF.typingRange, textSel.isParaSelection); 0{delete but save typed text} 0text := textSel.DeleteButSave; 0insertionPt := textSel.BecomeInsertionPoint; 0firstPara := insertionPt.textRange.firstPara; 0firstLP := insertionPt.textRange.firstLP; 0firstIndex := insertionPt.textRange.firstIndex; 0{put back any text that was typed over} 0insertionPt.InsertText(SELF.savedText, FALSE, FALSE, FALSE); 0Free(SELF.savedText); 0SELF.savedText := text; 0selection := panel.selection; 0WHILE selection.coSelection <> NIL DO 4selection := selection.coSelection; 0{build original selection (before typing)} 0textSel := TTextSelection(selection.FreedAndReplacedBy( DinsertionPt.textImage.NewTextSelection( HfirstPara, firstIndex, firstLP, insertionPt.textRange.firstPara, HinsertionPt.textRange.firstIndex, insertionPt.textRange.firstLP))); 0SELF.text.ChangeSelInOtherPanels(textSel); 0insertionPt.Free; 0END; ,END; ({$IFC fTrace}EP;{$ENDC} $END; {$S SgTxtIni} END; {METHODS OF TTypingCmd} {$S SgTxtCld} 3. "6F^7F.^=KYKYl!9StartGetScrap(error); (IF error <> 0 THEN ,ABCBreak('StartGetScrap Error',error); (PutCsScrap(index, error); (IF error <> 0 THEN ,ABCBreak('PutCsScrap Error',error); (freeics(index); (EndGetScrap(error); (IF error <> 0 THEN ,ABCBreak('EndGetScrap Error',error); (UnbindUTDseg(error); (IF error <> 0 THEN ,ABCBreak('UnbindUTDseg Error',error); ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTWrite} {$EL{$SETC PasteTrace := PasteTrace AND fUniversalTextTrace} CONST $magicTabMax= itbdLst; {The maximum number of tabstops on a ruler allowed by LisaWrite and its ilk} $maxBacking = 12; {Maximum number of chars saved for backing up the lpLim during Write UT} TYPE $TPtrToolKitUT = ^ToolKitUT; $ToolKitUT = Tcs; $TSavedPara = RECORD (firstLp: TLp; (theArce: TArce; (theArpe: TArpe; {$IFC WithUObject} (theText: TString; {$ELSEC} (theText: TUTString; {$ENDC} 4END; $PSavedPara = ^TSavedPara; $HSavedPara = ^PSavedPara; {$IFC NOT WithUObject} $Byte = -128..127; $TpLONGINT = ^LONGINT; $TPByte = ^Byte; {$ENDC} {private types not used in the Toolkit; used in place of the Toolkit's type coercion to a (Handle, since a Handle outside of the Toolkit is a double-indeirect pointer to a byte} $UTpLongint = ^LONGINT; $UTppLongint = ^UTpLongint; "{ Carefull, carefull, carefull here kids. Since I can't have private fields and/or methods in my classes $inorder to resolve a few types I am forced to do this thing to keep you innocents from having to $include an ugly list of units. Only one instance of these variabes exists ever! Therefore I can only $do things one at a time.} $TSecretThings = RECORD ,streamArrayIndex: Byte; ,lpd: TALpd; ,achad: TAchad; ,END; VAR {$IFC WithUObject} $activeStream: TTKWriteUnivText; {$ELSEC} $activeStream: TWriteUnivText; {$ENDC} $secrets: TSecretThings; $currentLpd: TLpd; $dataIndex: INTEGER; $dataLp: TLp; $savedPara: ARRAY [1..maxBacking] OF HSavedPara; $nOfSavedPara: 0..maxBacking; {$IFC WithUObject} $theData: TString; {$ELSEC} $theData: TUTString; {$ENDC} {$IFC NOT WithUObject} {The following is a ToolKit to avoid including lots of code that is not used by non-ToolKit applications.} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE UTXferRight(source, dest: Ptr; nBytes: INTEGER); EXTERNAL; PROCEDURE UTXferLeft(source, dest: Ptr; nBytes: INTEGER); EXTERNAL; {--------------------------------------------------------------------------------------------------------} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} FUNCTION Min(i, j: LONGINT): LONGINT; {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $IF i < j THEN (Min := i $ELSE (Min := j; END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} FUNCTION Max(i, j: LONGINT): LONGINT; {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $IF i > j THEN (Max := i $ELSE (Max := j; END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE ABCBreak(s: S255; errCode: LONGINT); {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fDbgObject} $WriteLn; $Write(CHR(7), s); {Beep} $IF errCode <> 0 THEN (Write(': ', errCode:1); $WriteLn; ${$ENDC} $HALT; END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE SetCp(object: TUTObject; itsClass: TClass); {--------------------------------------------------------------------------------------------------------} $VAR index: INTEGER; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $UTppLongint(object)^^ := ORD(itsClass); {Install slice table pointer} $index := CiOfCp(TPSliceTable(itsClass)); {Determine its class index} $IF index < 256 THEN {If it will fit in a byte, store it...} (TPByte(UTppLongint(object)^)^ := index; {...to speed version conversion (cf ConvertHeap: FindClasses)} END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} FUNCTION NewDynObject(heap: THeap; itsClass: TClass; dynBytes: INTEGER): TUTObject; {--------------------------------------------------------------------------------------------------------} $VAR nBytes: INTEGER; (object: TUTObject; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $nBytes := SizeOfCp(TPSliceTable(itsClass)) + dynBytes; $object := POINTER(ORD(HAllocate(THz(heap), nBytes))); {TUTObject() won't work until after SetCp} $IF ORD(object) = ORD(hNIL) THEN 'ABCBreak('NewObject: Heap full, can''t make an object of size', nBytes); $SetCp(object, itsClass); $NewDynObject := object; END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} FUNCTION NewUTObject(heap: THeap; itsClass: TClass): TUTObject; {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $NewUTObject := NewDynObject(heap, itsClass, 0); END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE ResizeDynObject(object: TUTObject; newTotalBytes: INTEGER); {--------------------------------------------------------------------------------------------------------} $VAR i: INTEGER; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $IF (newTotalBytes < 0) OR (newTotalBytes > (MAXINT-20)) THEN (ABCBreak('New size must lie between 0 and 32K-20, not', newTotalBytes); $ChangeSizeH(THz(object.Heap), TH(object), newTotalBytes); $IF CbDataOfH(THz(object.Heap), TH(object)) < newTotalBytes THEN 'ABCBreak('ResizeDynObject: Heap full, size can''t change to', newTotalBytes); END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} FUNCTION ClassPtr(hndl: UTppLongint): TClass; {--------------------------------------------------------------------------------------------------------} $VAR stp: RECORD 0CASE INTEGER OF 41: (asLong: LONGINT); 42: (asBytes: PACKED ARRAY [0..3] OF TByte); 43: (asClass: TClass); 4END; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $stp.asLong := hndl^^; $stp.asBytes[0] := 0; $ClassPtr := stp.asClass; END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} FUNCTION SizeOfClass(class: TClass): INTEGER; {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $SizeOfClass := SizeOfCp(TPSliceTable(class)); END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE InitObject; {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${Do very little for the time beeing} END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE ClascalError(error: INTEGER); {called with error = 0 after successful Clascal initialization} {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} $IF error > 0 THEN (ABCBreak('Some kind of Clascal error', error); END; METHODS OF TUTObject; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TObject.}Free; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.FreeObject; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TObject.}FreeObject; ${----------------------------------------------------------------------------------------------------} (VAR heap: THeap; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (heap := SELF.Heap; (FreeH(THz(heap), TH(SELF)); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TObject.}Heap: THeap; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (Heap := THeap(HzFromH(TH(SELF))); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TObject.}Class: TClass; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (Class := ClassPtr(UTppLongint(SELF)); $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} BEGIN {Class Initialization} {$IFC fTraceUT} LogCall; {$ENDC} $InitClascal(ClascalError); {Provide an error routine in case of errors in Clascal run-time support} $InitObject; {Do remaining initialization} END; METHODS OF TUTCollection; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TCollection.}CREATE(object: TUTObject; heap: THeap; initialSlack: INTEGER): TUTCollection; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF object = NIL THEN ,ABCBreak('TUTCollection.CREATE must be passed an already-allocated object by a subclass CREATE', 0); (SELF := TUTCollection(object); (WITH SELF DO ,BEGIN ,size := 0; &{$H-} dynStart := SizeOfClass(SELF.Class); {$H+} ,holeStart := 0; ,holeSize := initialSlack; ,holeStd := 0; ,END; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TCollection.}AddrMember(i: LONGINT): LONGINT; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF i > SELF.holeStart THEN ,i := i + SELF.holeSize; (AddrMember := TpLONGINT(SELF)^ + SELF.dynStart + (SELF.MemberBytes * (i - 1)); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TCollection.}EditAt(atIndex: LONGINT; deltaMembers: INTEGER); ${----------------------------------------------------------------------------------------------------} (VAR oldHoSize: INTEGER; ,newHoSize: INTEGER; ,oldHoStart: INTEGER; ,newHoStart: INTEGER; ,maxHoStart: INTEGER; ,minHoStart: INTEGER; ,size: INTEGER; ,b: 0..1; $BEGIN {Removes any hole it creates unless holdStd <> 0} {$IFC fTraceUT} LogCall; {$ENDC} (oldHoSize := SELF.holeSize; (oldHoStart := SELF.holeStart; (IF (deltaMembers < 0) AND ((oldHoStart + 1) = atIndex) THEN {the hole is right before the deletion} ,SELF.holeStart := oldHoStart - deltaMembers (ELSE ,BEGIN ,newHoStart := atIndex - 1 - Min(deltaMembers, 0); ,IF (deltaMembers > oldHoSize) OR (newHoStart <> oldHoStart) THEN 0BEGIN 0maxHoStart := Max(oldHoStart, newHoStart); 0newHoSize := Max(oldHoSize, deltaMembers); 0IF newHoSize > oldHoSize THEN 4BEGIN 4size := SELF.size; 4newHoSize := Max(newHoSize, SELF.holeStd); 4SELF.ResizeColl(size + newHoSize); 4SELF.ShiftColl(maxHoStart + oldHoSize, maxHoStart + newHoSize, size - maxHoStart); 4END; 0IF newHoStart <> oldHoStart THEN 4BEGIN 4b := ORD(newHoStart > oldHoStart); {1 if hole is moving right and data is moving left} 4minHoStart := Min(oldHoStart, newHoStart); 4SELF.ShiftColl(minHoStart + oldHoSize*b, minHoStart + newHoSize*(1-b), maxHoStart - minHoStart); 4END; 0SELF.holeStart := newHoStart; 0SELF.holeSize := newHoSize; 0END; ,END; (WITH SELF DO ,BEGIN ,size := size + deltaMembers; ,holeSize := holeSize - deltaMembers; ,holeStart := holeStart + deltaMembers; ,IF oldHoSize = 0 THEN 0IF holeStd = 0 THEN 4IF holeSize > 0 THEN 0{$H-} SELF.StopEdit; {$H+} ,END; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TCollection.}InsManyAt(i: LONGINT; otherCollection: TUTCollection; index, howMany: LONGINT); ${----------------------------------------------------------------------------------------------------} (VAR memberBytes: INTEGER; ,beforeHole: INTEGER; ,srcAddr: LONGINT; ,dstAddr: LONGINT; ,j: INTEGER; ,offset: INTEGER; $BEGIN {Stops edit if it wasn't explicitly started} {$IFC fTraceUT} LogCall; {$ENDC} (memberBytes := SELF.memberBytes; (SELF.EditAt(i, howMany); (IF howMany > 0 THEN ,IF otherCollection.Class = SELF.Class THEN {Can do it with at most two Xfers} 0BEGIN 0beforeHole := Min(howMany, otherCollection.holeStart + 1 - index); 0srcAddr := otherCollection.AddrMember(index); 0dstAddr := SELF.AddrMember(i); 0IF beforeHole > 0 THEN 4BEGIN 4UTXferLeft(Ptr(srcAddr), Ptr(dstAddr), beforeHole * memberBytes); 4IF beforeHole < howMany THEN 8BEGIN 8srcAddr := srcAddr + (beforeHole + otherCollection.holeSize) * memberBytes; 8dstAddr := dstAddr + beforeHole * memberBytes; 8UTXferLeft(Ptr(srcAddr), Ptr(dstAddr), (howMany - beforeHole) * memberBytes); 8END; 4END 0ELSE 4UTXferLeft(Ptr(srcAddr), Ptr(dstAddr), howMany * memberBytes); 0END ,ELSE {Must Xfer each member separately} 0BEGIN 0offset := SELF.dynStart + (i - 1) * memberBytes; {AddrMember may even compact for all we know} 0FOR j := 1 TO howMany DO 4BEGIN 4UTXferLeft(Ptr(otherCollection.AddrMember(j)), Ptr(TpLONGINT(SELF)^ + offset), memberBytes); 4offset := offset + memberBytes; 4END; 0END; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TCollection.}ResizeColl(membersPlusHole: INTEGER); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF membersPlusHole <> (SELF.size + SELF.holeSize) THEN ,ResizeDynObject(SELF, SELF.dynStart + (membersPlusHole * SELF.MemberBytes)); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TCollection.}ShiftColl(afterSrcIndex, afterDstIndex, howMany: INTEGER); ${----------------------------------------------------------------------------------------------------} (VAR memberBytes: INTEGER; ,numBytes: INTEGER; ,startAddr: LONGINT; ,srcAddr: LONGINT; ,dstAddr: LONGINT; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF (howMany > 0) AND (afterSrcIndex <> afterDstIndex) THEN ,BEGIN ,memberBytes := SELF.MemberBytes; ,numBytes := howMany * memberBytes; ,startAddr := TpLONGINT(SELF)^ + SELF.dynStart; ,srcAddr := startAddr + afterSrcIndex * memberBytes; ,dstAddr := startAddr + afterDstIndex * memberBytes; ,IF afterSrcIndex < afterDstIndex THEN 0UTXferRight(Ptr(srcAddr), Ptr(dstAddr), numBytes) ,ELSE 0UTXferLeft(Ptr(srcAddr), Ptr(dstAddr), numBytes); ,END; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TCollection.}StartEdit(withSlack: INTEGER); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.holeStd := withSlack; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TCollection.}StopEdit; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF SELF.holeStart < SELF.size THEN ,SELF.EditAt(SELF.size + 1, 0); (SELF.ResizeColl(SELF.size); (SELF.holeStd := 0; (SELF.holeSize := 0; $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END; METHODS OF TUTArray; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TArray.}CREATE(object: TUTObject; heap: THeap; initialSlack, bytesPerRecord: INTEGER): TUTArray; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF ODD(bytesPerRecord) THEN ,bytesPerRecord := bytesPerRecord + 1; (IF object = NIL THEN ,object := NewDynObject(heap, THISCLASS, initialSlack * bytesPerRecord); (SELF := TUTArray(TUTCollection.CREATE(object, heap, initialSlack)); (SELF.recordBytes := bytesPerRecord; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TArray.}MemberBytes: INTEGER; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (MemberBytes := SELF.recordBytes; $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TArray.}At(i: LONGINT): Ptr; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} '{ At := Ptr(SELF.AddrMember(i)); but for speed...} (IF i > SELF.holeStart THEN ,i := i + SELF.holeSize; (At := Ptr(TpLONGINT(SELF)^ + SELF.dynStart + (SELF.recordBytes * (i - 1))); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TArray.}DelAll; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(1, -SELF.size); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TArray.}DelAt(i: LONGINT); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, -1); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TArray.}DelManyAt(i, howMany: LONGINT); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, -howMany); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TArray.}PutAt(i: LONGINT; pRecord: Ptr); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (UTXferLeft(pRecord, Ptr(SELF.AddrMember(i)), SELF.recordBytes); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TArray.}InsAt(i: LONGINT; pRecord: Ptr); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, 1); (SELF.PutAt(i, pRecord); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TArray.}InsLast(pRecord: Ptr); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(3);{$ENDC} (SELF.InsAt(SELF.size + 1, pRecord); ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END; METHODS OF TUTString; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TString.}CREATE(object: TUTObject; heap: THeap; initialSlack: INTEGER): TUTString; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (IF ODD(initialSlack) THEN ,initialSlack := initialSlack + 1; (IF object = NIL THEN ,object := NewDynObject(heap, THISCLASS, initialSlack); (SELF := TUTString(TUTCollection.CREATE(object, heap, initialSlack)); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TString.}At(i: LONGINT): CHAR; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} '{At := CHAR(TPByte(SELF.AddrMember(i))^); but for speed...} (IF i > SELF.holeStart THEN ,i := i + SELF.holeSize; (At := CHAR(TPByte(TpLONGINT(SELF)^ + SELF.dynStart + (i - 1))^); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TString.}DelAt(i: LONGINT); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, -1); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TString.}DelAll; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(1, -SELF.size); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TString.}DelManyAt(i, howMany: LONGINT); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, -howMany); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TString.}InsAt(i: LONGINT; character: CHAR); ${----------------------------------------------------------------------------------------------------} (VAR pByte: TPByte; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, 1); '{TPByte(SELF.AddrMember(i))^ := PByte(character); but for speed...} (pByte := TPByte(TpLONGINT(SELF)^ + SELF.dynStart + (i - 1)); (pByte^ := TByte(character); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TString.}InsPAOCAt(i: LONGINT; pPackedArrayOfCharacter: Ptr; howMany: LONGINT); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i, howMany); (UTXferLeft(pPackedArrayOfCharacter, Ptr(SELF.AddrMember(i)), howMany); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TString.}ToPAOCAt(i, howMany: LONGINT; pPackedArrayOfCharacter: Ptr); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SELF.EditAt(i + howMany, 0); (UTXferLeft(Ptr(SELF.AddrMember(i)), pPackedArrayOfCharacter, howMany); $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TString.}MemberBytes: INTEGER; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (MemberBytes := 1; $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END; {$ENDC} {$IFC fUniversalTextTrace} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE PrintRun; {--------------------------------------------------------------------------------------------------------} VAR i: INTEGER; $tab: TTabDescritor; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fTrce}BP(11);{$ENDC} ${lpd, achad} $WRITELN('the character Descriptor is '); $FOR i := 1 TO activeStream.data.size DO (WRITE(activeStream.data.At(i)); $WRITELN; $WRITELN(' maxDataSize ', activeStream.maxDataSize); {$H-} $WITH activeStream.characterDescriptor DO (BEGIN (WRITELN(' font ', font); (WRITELN(' face '); (WRITELN(' Superscript ', Superscript); (WRITELN(' keepOnSamePage ', keepOnSamePage); (END; $WRITELN('the paragraph Descriptor is '); $WITH activeStream.paragraphDescriptor DO (BEGIN (WRITELN(' paraGraphStart ', paraGraphStart); (WRITELN(' firstLineMargin ', firstLineMargin); (WRITELN(' bodyMargin ', bodyMargin); (WRITELN(' rightMargin ', rightMargin); (WRITELN(' paraLeading ', paraLeading); (WRITELN(' lineSpacing ', lineSpacing); (WRITELN(' ', tabTable.size:2,' Tabs '); (FOR i := 1 TO tabTable.size DO ,BEGIN ,tab := TTabDescritor(tabTable.At(i)); ,WITH tab DO 0BEGIN 0WRITELN(' position ', position); 0WRITE (' fillBetweenTabs '); 0CASE fillBetweenTabs OF 4tNoFill: WRITELN('No fill'); 4tDotFill: WRITELN('Dot fill'); 4tHyphenFill: WRITELN('Hyphen fill'); 4tUnderLineFill: WRITELN('Underline fill'); 0END;{CASE} 0WRITE (' tabType '); 0CASE tabType OF 4qLeftTab: WRITELN('Left tab'); 4qCenterTab: WRITELN('Center tab'); 4qRightTab: WRITELN('Right tab'); 4qPeriodTab: WRITELN('Decimal period tab'); 4qCommaTab: WRITELN('Decimal comma tab'); 0END;{CASE} 0END; ,END; (WRITE (' paraType '); (CASE paraType OF ,qLeftPara: WRITELN('Left aligned'); ,qCenterPara: WRITELN('Centered'); ,qRightPara: WRITELN('Right aligned'); ,qJustPara: WRITELN('Justified'); (END;{CASE} (WRITELN(' hasPicture ', hasPicture); (END; {$H+} ${$IFC fTrce}EP;{$ENDC} END; {$ENDC} {$IFC fUniversalTextTrace} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE PrintLpd(theLpd: TALpd); {--------------------------------------------------------------------------------------------------------} $PROCEDURE WriteQuad(quad: TQuad); $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (CASE quad OF ,quadL: WRITELN('quadL'); ,quadC: WRITELN('quadC'); ,quadR: WRITELN('quadR'); ,quadJ: WRITELN('quadJ'); (END; $END; $PROCEDURE WriteTArpe(arpe: TArpe); $VAR i: INTEGER; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (WITH arpe DO ,BEGIN ,WRITELN(' cb: ', cb:1); ,WRITELN(' sy: ', sy:1); ,WRITELN(' xLftFst: ', xLftFst:1); ,WRITELN(' xLftBody: ', xLftBody:1); ,WRITELN(' xRt: ', xRt:1); ,WRITELN(' yLd: ', yLd:1); ,WRITELN(' fill1: ', fill1:1); ,WRITELN(' yLine: ', yLine:1); ,WRITE (' quad: '); ,WriteQuad(quad); ,WRITELN(' itbLim: ', itbLim:1); ,WRITELN(' argtbd:'); ,FOR i := 0 TO itbLim - 1 DO 0{$R-} 0WITH argtbd[i] DO 4BEGIN 4WRITELN(' [',i:0,']:'); 4WRITELN(' x: ', x:1); 0(* WRITELN(' fill4: ', fill4:1); *) 4WRITE (' quad: '); 4WriteQuad(argtbd[i].quad); 4WRITE (' tyfill: '); 4CASE tyfill OF 8tyfillNil: WRITELN('tyfillNil'); 8tyfillDots: WRITELN('tyfillDots'); 8tyfillHyph: WRITELN('tyfillHyph'); 8tyfillUL: WRITELN('tyfillUL'); 4END; 4WRITELN(' chLdr: ', chLdr:1); 4END; 0{$R+} ,END; $END; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fTrce}BP(11);{$ENDC} $WRITELN(' Lpd '); $WITH theLpd DO (BEGIN (WRITELN('ics: ', ics:1); (WRITELN('ilpd: ', ilpd:1); (WRITELN('fParSt: ', fParSt); (WRITELN('lp: ', lp:1); (WRITELN('lplim ', lplim:1); (WRITELN('lpson: ', lpson:1); (WRITELN('icsson: ', icsson:1); (WRITELN('tyset:'); (WITH tyset DO ,BEGIN ,WRITELN(' fRce: ', tyset.fRce); ,WRITELN(' fParBnds: ', tyset.fParBnds); ,WRITELN(' fRpe: ', tyset.fRpe); ,END; (WRITELN('lpFstPar: ', lpFstPar:1); (WRITELN('lpLimPar: ', lpLimPar:1); (IF tyset.fRpe THEN ,IF rpe = NIL THEN 0WRITELN('rpe: NIL') ,ELSE 0WITH rpe^ DO 0BEGIN 0WRITELN('rpe:'); 0WriteTArpe(rpe^); 0END; (IF tyset.fRce THEN ,WITH arce DO 0BEGIN 0WRITELN('arce:'); 0WRITELN(' cb: ', cb:1); 0WRITELN(' fVan: ', fVan:1); 0WRITELN(' fBold: ', fBold:1); 0WRITELN(' fItalic: ', fItalic:1); 0WRITELN(' fUnderline: ', fUnderline:1); 0WRITELN(' fill4: ', fill4:1); 0WRITELN(' cbSuperscript: ', cbSuperscript:1); 0WRITELN(' ifnt: ', ifnt:1); 0WRITELN(' fKeep: ', fKeep:1); 0WRITELN(' fOutLine: ', fOutLine:1); 0WRITELN(' fShadow: ', fShadow:1); 0WRITELN(' fFillB: ', fFillB:1); 0WRITELN(' fFillC: ', fFillC:1); 0WRITELN(' fFillD: ', fFillD:1); 0WRITELN(' fFillE: ', fFillE:1); 0WRITELN(' fFillF: ', fFillF:1); 0END; (IF tyset.fRpe THEN 0BEGIN 0WRITELN('arpe:'); 0WriteTArpe(arpe); 0END; (END; $WRITELN(''); $WRITELN; ${$IFC fTrce}EP;{$ENDC} END; {$ENDC} {$IFC fUniversalTextTrace} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE PrintAchad(achad: TAchad); {--------------------------------------------------------------------------------------------------------} VAR i: INTEGER; $size: INTEGER; BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fTrce}BP(11);{$ENDC} $WITH achad DO (BEGIN (WRITELN(' Achad '); (WRITELN('ichFst: ', ichFst:1); (WRITELN('ichLim: ', ichLim:1); (IF rgch <> NIL THEN ,BEGIN ,size := ichlim - ichFst - 1; ,IF size >= 80 THEN 0size := 79; ,FOR i := ichFst TO ichFst + size DO 0{$R-} 0IF rgch^[i] >= 32 THEN 4WRITE(CHR(rgch^[i])) 0ELSE 4WRITE('<', rgch^[i]:0, '>'); 0{$R+} ,WRITELN; ,IF ichlim - ichFst >= 79 THEN 0WRITELN('etc, etc...'); ,END; (WRITELN(''); (WRITELN; (END; ${$IFC fTrce}EP;{$ENDC} END; {$ENDC} {$IFC fUniversalTextTrace} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE PrintSecrets(achad: TAchad; theLpd: TALpd); {--------------------------------------------------------------------------------------------------------} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fTrce}BP(11);{$ENDC} $WRITELN('streamArrayIndex is ', secrets.streamArrayIndex); $PrintLpd(theLpd); $PrintAchad(achad); ${$IFC fTrce}EP;{$ENDC} END; {$ENDC} {$IFC WithUObject} {$S TKUTWrite} {$ELSEC} {$S UTWrite} {$ENDC} {--------------------------------------------------------------------------------------------------------} PROCEDURE SeqLpdUTBB(Lpd: TLpd; var achad: Tachad); {--------------------------------------------------------------------------------------------------------} VAR howMany: INTEGER; $done: BOOLEAN; $index: INTEGER; $backUp: INTEGER; $newPara: BOOLEAN; {$IFC WithUObject} $newData: TString; {$ELSEC} $newData: TUTString; {$ENDC} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fTrce}BP(11);{$ENDC} 0{LSR: put the next assignment and the WITH before the debugging code because 8PrintSecrets depends on it.} $currentLpd := lpd; { Remember the lpd for RunToStream } $WITH lpd^ DO { Make shure the lpd is set up OK } (BEGIN (rpe := @arpe; (rce := @arce; (END; ${$IFC fUniversalTextTrace} $IF fPrintSecrets THEN (BEGIN (WRITELN(' SeqLpdUTBB '); (PrintSecrets(achad, currentLpd^); (WRITELN('dataLp = ', dataLp:0); (WRITELN('dataIndex = ', dataIndex:0); (WRITELN('nOfSavedPara = ', nOfSavedPara:0); (END; ${$ENDC} $newPara := FALSE; {Assume no new para} X{ Compute if we have to back up } $backUp := MIN(maxBacking, MAX(dataLp - lpd^.lpLim, 0)); ${$IFC fUniversalTextTrace} $IF fPrintSecrets THEN (WRITELN('backUp = ', backUp:0); ${$ENDC} $IF backUp > 0 THEN (BEGIN (index := 1; (done := FALSE; (WHILE (NOT done) AND (index <= nOfSavedPara) DO ,WITH savedPara[index]^^, lpd^ DO 0IF firstLp <= lpLim THEN 4BEGIN 4{$IFC fUniversalTextTrace} 4IF fPrintSecrets THEN 8WRITELN('Backing up... to saved paragraph #', index:0); 4{$ENDC} 4lpLim := MAX(firstLp, lpLim); 4theData := theText; 4dataIndex := lpLim - firstLp; 4arpe := theArpe; 4IF dataIndex <> 0 THEN 8fParSt := FALSE; 4arce := theArce; 4done := TRUE; 4END 0ELSE 4index := index + 1; (IF NOT done THEN { This is FATAL !!!} ,BEGIN ,{$IFC fUniversalTextTrace} ,WRITELN('Fatal back up attempt in SeqLpdUTBB'); ,PrintSecrets(achad, lpd^); ,{$ENDC} ,HALT; {Die rather than fuck up} ,END; (END $ELSE (BEGIN (IF activeStream.data.Size = 0 THEN { Test if there is anything left in the buffer, } ,BEGIN ,newPara := TRUE; ,activeStream.ParagraphDescriptor.paraGraphStart := TRUE; {$IFC WithUObject} ,activeStream.ParagraphDescriptor.additionalChrInParagraph := 0; {$ENDC} ,activeStream.FillParagraph; { if not then try to get one more paragraph } ,activeStream.data.StopEdit; { Remove any holes from data } ,{$IFC fUniversalTextTrace} ,IF fPrintSecrets THEN 0BEGIN 0WRITELN('FillRun returns:'); 0PrintRun; 0END; ,{$ENDC} ,dataIndex := 0; { Reset the index to the begining of the text} ,WITH lpd^ DO { Pre-fill the lpd with standard data } 0BEGIN *{$H-} MoveRgch(@arpe, @arpeStd, arpeStd.cb); {$H+} *{$H-} MoveRgch(@arce, @arceStd, arceStd.cb); {$H+} 0dataLp := lpLim; 0END; ,activeStream.RunToStream; { Convert into stream format } ,END (ELSE ,BEGIN ,{$IFC fUniversalTextTrace} ,IF fPrintSecrets THEN 0WRITELN('Procede with the rest of the old run:'); ,{$ENDC} ,dataIndex := Lpd^.lpLim - dataLp; ,IF dataIndex <> 0 THEN 0lpd^.fParSt := FALSE; ,END; (theData := activeStream.data; (END; X{ Compute how many bytes to transfer this time } $howMany := MIN(achad.ichLim - achad.ichFst, theData.size - dataIndex); ${$IFC fUniversalTextTrace} $IF fPrintSecrets THEN (BEGIN (WRITELN('theData.size = ', theData.size:0); (WRITELN('dataLp = ', dataLp:0); (WRITELN('dataIndex = ', dataIndex:0); (WRITELN('howMany = ', howMany:0); (WRITELN('newPara = ', newPara:0); (END; ${$ENDC} $WITH lpd^ DO (BEGIN (lp := lpLim; (lplim := lp + howMany; (END; $WITH secrets.achad DO { Build our own achad just in case... } (BEGIN (rgch := POINTER(ORD4(theData.AddrMember(1)) + dataIndex); (ichfst := 0; (ichLim := howMany; (END; X{ Copy the achad } X{ Check for NIL rgch.} X{ If NIL then pass data else copy the data } $IF achad.rgch = NIL THEN (achad := secrets.achad $ELSE (BEGIN (achad.ichlim := achad.ichFst + howMany; (MoveAchad(achad, secrets.achad); (END; $IF howMany = 0 THEN { We are done, kill all saved stuff } (FOR index := 1 TO nOfSavedPara DO ,BEGIN ,savedPara[index]^^.theText.Free; ,FreeH(HzFromH(TH(savedPara[index])), TH(savedPara[index])); ,END $ELSE (BEGIN (IF newPara THEN { New text in activeStream.data... } ,BEGIN ,done := FALSE; ,index := nOfSavedPara; ,WHILE (NOT done) AND (index > 0) DO { Get ridd of old stuff } 0WITH savedPara[index]^^ DO 4IF (lpd^.lpLim - (firstLp + theText.size) ) >= maxBacking THEN {LSR} 8BEGIN 8theText.Free; 8FreeH(HzFromH(TH(savedPara[index])), TH(savedPara[index])); 8index := index - 1; 8nOfSavedPara := nOfSavedPara - 1; 8END 4ELSE 8done := true; 5{LSR: changed direction of following loop} ,FOR index := nOfSavedPara DOWNTO 1 DO { Shift everything to free the first one } 0savedPara[index + 1] := savedPara[index]; ,nOfSavedPara := nOfSavedPara + 1; \{ Make a new place to save old paragraphs } ,savedPara[1] := POINTER(HAllocate(THz(activeStream.Heap), SIZEOF(TSavedPara))); ,WITH savedPara[1]^^, lpd^ DO 0BEGIN 0firstLp := lp; 0theArpe := arpe; 0theArce := arce; 0theText := activeStream.data; 0END; ,END; (IF (dataIndex + howMany) >= activeStream.data.Size THEN ,BEGIN { Make a fresh string, the old one is in savedPara[1] } 8{LSR: break up the assignment to activeStream.data to prevent dereferenced handles} {$IFC WithUObject} ,newData := TString.CREATE(NIL, activeStream.heap, activeStream.maxDataSize); {$ELSEC} ,newData := TUTString.CREATE(NIL, activeStream.heap, activeStream.maxDataSize); {$ENDC} ,activeStream.data := newData; ,activeStream.data.StartEdit(50); {Allow holes} ,dataLp := lpd^.lpLim; {Make shure backUp will compute to zero} ,END; (END; ${$IFC fUniversalTextTrace} $IF fPrintSecrets THEN (BEGIN (PrintSecrets(achad, currentLpd^); (WRITELN('dataLp = ', dataLp:0); (WRITELN('dataIndex = ', dataIndex:0); (WRITELN('nOfSavedPara = ', nOfSavedPara:0); (WRITELN(''); (WRITELN; (WRITELN; (END; ${$ENDC} ${$IFC fTrce}EP;{$ENDC} END; {$IFC WithUObject} METHODS OF TTKUnivText {$ELSEC} METHODS OF TUnivText {$ENDC} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} {$IFC WithUObject} $FUNCTION {TUnivText.}CREATE(object: TObject; AitsHeap: THeap; AitsTString: TString; AitsDataSize: INTEGER) V: TTKUnivText; {$ELSEC} $FUNCTION {TUnivText.}CREATE(object: TUTObject; AitsHeap: THeap; AitsTString: TUTString; AitsDataSize: INTEGER) V: TUnivText; {$ENDC} ${----------------------------------------------------------------------------------------------------} {$IFC WithUObject} $VAR thisTabTable: TArray; {$ELSEC} $VAR thisTabTable: TUTArray; {$ENDC} (thisString: ^Tsp; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (IF object = NIL THEN {$IFC WithUObject} ,object := NewObject(itsHeap, THISCLASS); {$ELSEC} ,object := NewUTObject(itsHeap, THISCLASS); {$ENDC} {$IFC WithUObject} (SELF := TTKUnivText(object); {$ELSEC} (SELF := TUnivText(object); {$ENDC} ({ Get the stream } (SELF.itsOurTString := itsTString = NIL; (IF SELF.itsOurTString THEN {$IFC WithUObject} ,itsTString := TString.CREATE(NIL, itsHeap, itsDataSize); {$ELSEC} ,itsTString := TUTString.CREATE(NIL, itsHeap, itsDataSize); {$ENDC} (itsTString.StartEdit(50); {Allow holes} (SELF.data := itsTString; (SELF.maxDataSize := itsDataSize; {$IFC WithUObject} (thisTabTable := TArray.CREATE(NIL, itsHeap, 0, SIZEOF(TTabDescriptor)); {$ELSEC} (thisTabTable := TUTArray.CREATE(NIL, itsHeap, 0, SIZEOF(TTabDescriptor)); {$ENDC} (thisTabTable.StartEdit(5); (SELF.paragraphDescriptor.tabTable := thisTabTable; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TUnivText.}Free; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} ({If the dynamic array was not passed in then free it} (IF SELF.itsOurTString THEN ,SELF.data.Free; (SELF.paragraphDescriptor.tabTable.Free; (SUPERSELF.Free; ({$IFC fTrce}EP;{$ENDC} $END; ${$IFC fDebugMethods} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TUnivText.}Fields(PROCEDURE Field(nameAndType: S255)); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SUPERSELF.Fields(Field); (Field('paraGraphStart: BOOLEAN'); {$IFC WithUObject} (Field('additionalChrInParagraph: INTEGER'); {$ENDC} (Field('firstLineMargin: INTEGER'); (Field('bodyMargin: INTEGER'); (Field('rightMargin: INTEGER'); (Field('paraLeading: INTEGER'); (Field('lineSpacing: BYTE'); {$IFC WithUObject} (Field('tabTable: TArray'); {$ELSEC} (Field('tabTable: TUTArray'); {$ENDC} (Field('paraType: BYTE'); (Field('hasPicture: BOOLEAN'); (Field('font: INTEGER'); (Field('face: BYTE'); (Field('superscript: BYTE'); (Field('keepOnSamePage: BOOLEAN'); (Field('maxDataSize: INTEGER'); {$IFC WithUObject} (Field('data: TString'); {$ELSEC} (Field('data: TUTString'); {$ENDC} (Field('itsOurTString: BOOLEAN'); (Field(''); $END; ${$ENDC} {$IFC WithUObject} {$S TKUTWrite} {$ELSEC} {$S UTWrite} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TUnivText.}RunToStream; ${----------------------------------------------------------------------------------------------------} $VAR i: INTEGER; (found: BOOLEAN; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (IF currentLpd^.tyset.fRce THEN *{ Convert the character descriptor } ,WITH SELF.characterDescriptor, currentLpd^.rce^ DO 0BEGIN .{ Set the face fields } 0fbold := bold IN face; 0fitalic := italic IN face; 0funderline := underline IN face; 0foutline := outline IN face; 0fshadow := shadow IN face; 0fvan := FALSE; {No vanished runs} .{ Because of the way lotus does fonts we have to convert the a real font to a lotus font } 0found := FALSE; 0i := 0; 0WHILE (i <= ifntlst) AND NOT(found) DO 4BEGIN 4IF argfam[i] = font THEN 8BEGIN 8ifnt := i; 8found := TRUE; 8END; 4i := i + 1; 4END; 0IF NOT found THEN ifnt := 0; 0cbSuperscript := superscript; 0fKeep := keepOnSamePage; 0END; { with } &{ Convert the paragraph descriptor } (WITH SELF.ParagraphDescriptor, currentLpd^, rpe^ DO ,BEGIN ,fParSt := paraGraphStart; ,IF paraGraphStart THEN 0BEGIN 8{LSR: added lpLim to the right side of each of the following assignments} 0lpFstPar := lpLim; {$IFC WithUObject} 0lpLimPar := lpLim + SELF.data.Size + additionalChrInParagraph; {$ELSEC} 0lpLimPar := lpLim + SELF.data.Size; {$ENDC} 0END; ,IF tyset.fRpe THEN 0BEGIN 0xLftFst := firstLineMargin; 0xLftBody := bodyMargin; 0xRt := rightMargin; 0yLd := paraLeading; 0yLine := lineSpacing; 0CASE paraType OF 4qLeftPara: quad := quadL; 4qCenterPara: quad := quadC; 4qRightPara: quad := quadR; 4qJustPara: quad := quadJ; 4OTHERWISE quad := quadL; 0END;{CASE} 0itbLim := tabTable.Size - 1; *{$H-} SELF.TabTableToArgTbd; {$H+} { This invalidates WITH statement!! } 0END; ,END; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TUnivText.}StreamToRun; ${----------------------------------------------------------------------------------------------------} $VAR ifnt: INTEGER; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} &{ do the format stuff } (IF secrets.lpd.tyset.frce THEN ,WITH SELF.characterDescriptor, secrets.lpd.rce^ DO 0BEGIN 0font := argfam[ifnt]; 0face := []; 0IF fbold THEN 4face := face + [bold]; 0IF fitalic THEN 4face := face + [italic]; 0IF funderline THEN 4face := face + [underline]; 0IF foutline THEN 4face := face + [outline]; 0IF fshadow THEN 4face := face + [shadow]; 0superscript := cbSuperscript; 0keepOnSamePage := fKeep; 0END; (IF secrets.lpd.tyset.frpe THEN ,BEGIN ,WITH SELF.paragraphDescriptor, secrets.lpd.rpe^ DO 0BEGIN 0paraGraphStart := secrets.lpd.fParSt; 0firstLineMargin := xLftFst; 0bodyMargin := xLftBody; 0rightMargin := xRt; 0paraLeading := yLd; 0lineSpacing := yLine; 0hasPicture := FALSE; {not yet implemented} 0CASE quad OF 4quadL: paraType := qLeftPara; 4quadC: paraType := qCenterPara; 4quadR: paraType := qRightPara; 4quadJ: paraType := qJustPara; 4OTHERWISE paraType := qLeftPara; 0END;{CASE} 0IF itbLim < 0 THEN { Resize the tab table and move the data } 4itbLim := -1; 0END; ,SELF.ArgTbdToTabTable; ,END; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTWrite} {$ELSEC} {$S UTWrite} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TUnivText.}TabTableToArgTbd; ${----------------------------------------------------------------------------------------------------} $VAR i: INTEGER; (temp: INTEGER; (ptrToTab: Ptr; (tab: TTabDescriptor; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (temp := MIN(SELF.paragraphDescriptor.tabTable.size, magicTabMax); (FOR i:= 1 to temp DO ,BEGIN ,tab := TTabDescriptor(SELF.paragraphDescriptor.tabTable.At(i)); ,{R$-} ,WITH tab, currentLpd^.rpe^.argTbd[i-1] DO 0BEGIN 0x := position; 0CASE tabType OF 4qLeftTab: 8quad := quadL; 4qCenterTab: 8quad := quadC; 4qRightTab: 8quad := quadR; 4qPeriodTab: 8BEGIN 8quad := quadJ; 8fDecimalComma := FALSE; 8END; 4qCommaTab: 8BEGIN 8quad := quadJ; 8fDecimalComma := TRUE; 8END; 4OTHERWISE 8quad := quadL; 0END;{CASE} 0CASE fillBetweenTabs OF 4tNoFill: 8BEGIN 8tyFill := tyFillNil; 8chLdr := ORD(' '); 8END; 4tDotFill: 8BEGIN 8tyFill := tyFillDots; 8chLdr := ORD('.'); 8END; 4tHyphenFill: 8BEGIN 8tyFill := tyFillHyph; 8chLdr := ORD('-'); 8END; 4tUnderLineFill: 8BEGIN 8tyFill := tyFillUL; 8chLdr := ORD('_'); 8END; 4OTHERWISE 8BEGIN 8tyFill := tyFillNil; 8chLdr := ORD(' '); 8END; 0END;{CASE} 0END; ,{$R+} ,END; (currentLpd^.rpe^.itbLim := temp - 1; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TUnivText.}ArgTbdToTabTable; ${----------------------------------------------------------------------------------------------------} $VAR i: INTEGER; (tab: TTabDescriptor; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} ({ Size down the tab array for writing } (SELF.paragraphDescriptor.tabTable.DelAll; (FOR i := 0 to secrets.lpd.rpe^.itbLim - 1 DO ,BEGIN ,{$R-} ,WITH tab, secrets.lpd.rpe^.argTbd[i] DO 0BEGIN 0position := x; 0CASE quad OF 4quadL: tabType := qLeftTab; 4quadC: tabType := qCenterTab; 4quadR: tabType := qRightTab; 4quadJ: IF fDecimalComma THEN DtabType := qCommaTab @ELSE DtabType := qPeriodTab; 4OTHERWISE tabType := qLeftTab; 0END;{CASE} 0CASE tyFill OF 4tyFillNil: fillBetweentabs := tNoFill; 4tyFillDots: fillBetweentabs := tDotFill; 4tyFillHyph: fillBetweentabs := tHyphenFill; 4tyFillUL: fillBetweentabs := tUnderLineFill; 4OTHERWISE fillBetweentabs := tNoFill; 0END;{CASE} 0{$IFC fUniversalTextTrace} 0IF fPrintSecrets THEN 4BEGIN 4WRITELN('Tab #', i + 1:0, ', tabType =', ORD(tabType):0, ', quad =', ORD(quad):0); 4END; 0{$ENDC} 0END; ,{$R+} ,SELF.paragraphDescriptor.tabTable.InsLast(@tab); ,END; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ${$IFC fUniversalTextTrace} $fPrintSecrets := FALSE; ${$ENDC} END; {$IFC WithUObject} METHODS OF TTKReadUnivText {$ELSEC} METHODS OF TReadUnivText {$ENDC} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} {$IFC WithUObject} $FUNCTION {TReadUnivText.}CREATE(object: TObject; EitsHeap: THeap; EitsTString: TString; EitsDataSize: INTEGER; ELevelOfGranularity: TLevelOfGranularity) m: TTKReadUnivText; {$ELSEC} $FUNCTION {TReadUnivText.}CREATE(object: TUTObject; EitsHeap: THeap; EitsTString: TUTString; EitsDataSize: INTEGER; ELevelOfGranularity: TLevelOfGranularity) m: TReadUnivText; {$ENDC} ${----------------------------------------------------------------------------------------------------} $VAR index: TB; {$IFC WithUObject} (thisList: TString; {$ELSEC} (thisList: TUTString; {$ENDC} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} &{ Establish the level of granularity for reading } (WITH secrets.lpd.tyset DO ,BEGIN ,frce := UTCharacters IN LevelOfGranularity; ,frpe := UTparagraphs IN LevelOfGranularity; ,fParBnds := FALSE; ,END; (GetCSScrap(index); (IF index = 0 THEN ,SELF := NIL (ELSE ,BEGIN ,secrets.streamArrayIndex := index; ,IF object = NIL THEN {$IFC WithUObject} 0object := NewObject(itsHeap, THISCLASS); {$ELSEC} 0object := NewUTObject(itsHeap, THISCLASS); {$ENDC} {$IFC WithUObject} ,SELF := TTKReadUnivText(TTKUnivText.CREATE(object, itsHeap, itsTString, itsDataSize)); {$ELSEC} ,SELF := TReadUnivText(TUnivText.CREATE(object, itsHeap, itsTString, itsDataSize)); {$ENDC} {$IFC WithUObject} ,thisList := TString.CREATE(NIL, itsHeap, itsDataSize); {$ELSEC} ,thisList := TUTString.CREATE(NIL, itsHeap, itsDataSize); {$ENDC} ,thisList.StartEdit(50); {Allow holes} ,SELF.buffer := thisList; ,SELF.dataBeforeTab := TRUE; ,SELF.Restart; { Set up for reading from the beginning} ,END; ({$IFC fTrce}EP;{$ENDC} $END; ${$IFC fDebugMethods} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TReadUnivText.}Fields(PROCEDURE Field(nameAndType: S255)); ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (SUPERSELF.Fields(Field); {$IFC WithUObject} (Field('buffer: TString'); {$ELSEC} (Field('buffer: TUTString'); {$ENDC} (Field(''); $END; ${$ENDC} {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TReadUnivText.}Free; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (SELF.buffer.Free; (SUPERSELF.Free; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TReadUnivText.}Restart; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} ({ Set up the Achad for reading from the beginning} (WITH secrets.achad DO ,BEGIN ,ichFst := 0; ,ichLim := SELF.data.size; ,END; (secrets.lpd.lpLim := 0; (SELF.columnCount := 0; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TReadUnivText.}ScanTable(VAR rows, tabColumns, tabStopColumns: INTEGER); ${----------------------------------------------------------------------------------------------------} $VAR (fieldOverflow: BOOLEAN; (fieldTerminator: CHAR; (lastTerminator: CHAR; (tabType: TTabTypes; (columnsInThisRow: INTEGER; (dataBeforeTab: BOOLEAN; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} (rows := 0; (tabColumns := 1; (tabStopColumns := 0; (columnsInThisRow := 1; {There is at least one column} (SELF.dataBeforeTab := TRUE; {Make shure ReadField doesn't skip any fields} (dataBeforeTab := FALSE; (SELF.Restart; (WHILE SELF.ReadField(1, fieldOverflow, fieldTerminator, tabType) DO ,BEGIN ,IF columnsInThisRow = 1 THEN 0BEGIN 0IF SELF.data.size > 0 THEN 4dataBeforeTab := TRUE; 0IF tabStopColumns < SELF.paragraphDescriptor.tabTable.size THEN 4tabStopColumns := SELF.paragraphDescriptor.tabTable.size; 0END; ,lastTerminatior := fieldTerminator; ,IF fieldTerminator = CHR(chCr) THEN 0BEGIN 0rows := rows + 1; 0columnsInThisRow := 1; 0{Check the tab table here} 0END ,ELSE 0IF fieldTerminator = CHR(chTab) THEN 4BEGIN 4columnsInThisRow := columnsInThisRow + 1; 4IF columnsInThisRow > tabColumns THEN 8tabColumns := columnsInThisRow; 4END; ,END; (SELF.Restart; (IF (NOT dataBeforeTab) AND (tabColumn > 0) THEN ,tabColumns := tabColumns - 1; (SELF.dataBeforeTab := dataBeforeTab; (IF lastTerminatior <> CHR(chCr) THEN ,rows := rows + 1; ({$IFC fUniversalTextTrace} (IF fPrintSecrets THEN ,BEGIN ,WRITELN('ScanTable:'); ,WRITELN(' dataBeforeTab: ', dataBeforeTab); ,WRITELN(' tabColumns: ', tabColumns); ,WRITELN(' tabStopColumns: ', tabStopColumns); ,WRITELN(' rows: ', rows); ,END; ({$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TReadUnivText.}ReadField( maxFieldSize: INTEGER; HVAR fieldOverflow: BOOLEAN; HVAR fieldTerminator: CHAR; HVAR tabType: TTabTypes) _: BOOLEAN; ${----------------------------------------------------------------------------------------------------} {$IFC WithUObject} $VAR data: TString; (buffer: TString; {$ELSEC} $VAR data: TUTString; (buffer: TUTString; {$ENDC} (i: INTEGER; (terminatorFound: BOOLEAN; (result: BOOLEAN; (oldSize: INTEGER; (newSize: INTEGER; (columnNr: INTEGER; (tab: TTabDescriptor; (ch: CHAR; (PROCEDURE ReadBuffer; (BEGIN ,SELF.data := buffer; ,SELF.ReadRun; ,SELF.data := data; (END; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (REPEAT ,buffer := SELF.buffer; ,data := SELF.data; ,IF buffer.Size = 0 THEN { If there is no data then get some } 0ReadBuffer; ,fieldTerminator := CHR(0); ,fieldOverflow := FALSE; ,data.DelAll; ,terminatorFound := FALSE; ,IF buffer.Size > 0 THEN { If there is still text to paste } 0BEGIN 0tabType := qLeftTab; { Default tab type } 0IF SELF.columnCount > 0 THEN 4IF SELF.paragraphDescriptor.tabTable.size >= SELF.columnCount THEN 8tabType := TTabDescriptor( HSELF.paragraphDescriptor.tabTable.At(SELF.columnCount) R).tabType; 0SELF.columnCount := SELF.columnCount + 1; 0columnNr := SELF.columnCount; 0result := TRUE; 0REPEAT 4i := 0; 4WHILE (i < buffer.Size) AND (NOT terminatorFound) DO 8BEGIN 8i := i + 1; 8ch := buffer.At(i); 8IF (ch = CHR(chTab)) OR (ch = CHR(chCr)) THEN  maxFieldSize THEN 8BEGIN 8newSize := maxFieldSize; 8fieldOverflow := TRUE; 8END; 4IF newSize > oldSize THEN 8data.InsManyAt(1 + data.size, buffer, 1, newSize - oldSize); 4buffer.DelManyAt(1, i); 4IF (NOT terminatorFound) AND (buffer.Size = 0) THEN 8ReadBuffer; 0UNTIL terminatorFound OR (buffer.Size = 0); 0{$IFC fUniversalTextTrace} 0IF fPrintSecrets THEN 4BEGIN 4WRITELN('Buffer size is ',buffer.Size:1, ' data size is ',data.size:1); 4FOR i := 1 to data.size DO 8WRITE(data.At(i)); 4IF fieldTerminator = CHR(chTab) THEN 8WRITE('') 4ELSE 4IF fieldTerminator = CHR(chCr) THEN 8WRITE('') 4ELSE 8WRITE(''); 4WRITELN; 4WRITELN('FieldOverflow is ', fieldOverflow); 4END; 0{$ENDC} 0END ,ELSE 0result := FALSE; (UNTIL (NOT result) OR (columnNr > 1) OR SELF.dataBeforeTab; (ReadField := result; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TReadUnivText.}ReadLine( maxLineSize: INTEGER; GVAR lineOverflow: BOOLEAN; GVAR lineTerminator: CHAR) `: BOOLEAN; ${----------------------------------------------------------------------------------------------------} {$IFC WithUObject} $VAR data: TString; (buffer: TString; {$ELSEC} $VAR data: TUTString; (buffer: TUTString; {$ENDC} (i: INTEGER; (terminatorFound: BOOLEAN; (oldSize: INTEGER; (newSize: INTEGER; (ch: CHAR; (PROCEDURE ReadBuffer; (BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ,SELF.data := buffer; ,SELF.ReadRun; ,SELF.data := data; (END; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (buffer := SELF.buffer; (data := SELF.data; (IF buffer.Size = 0 THEN { If there is no data then get some } ,ReadBuffer; (lineTerminator := CHR(0); (lineOverflow := FALSE; (data.DelAll; (terminatorFound := FALSE; (IF buffer.Size > 0 THEN { If there is still text to paste } ,BEGIN ,ReadLine := TRUE; ,REPEAT 0i := 0; 0WHILE (i < buffer.size) AND (NOT terminatorFound) DO 4BEGIN 4i := i + 1; 4ch := buffer.At(i); 4IF ch = CHR(chCr) THEN 8BEGIN 8terminatorFound := TRUE; 8lineTerminator := ch; 8END; 4END; 0oldSize := data.Size; 0newSize := oldSize + i; 0IF terminatorFound THEN { Hide the terminating character, if any } 4newSize := newSize - 1; 0IF newSize > maxLineSize THEN 4BEGIN 4newSize := maxLineSize; 4lineOverflow := TRUE; 4END; 0IF newSize > oldSize THEN 4data.InsManyAt(1 + data.size, buffer, 1, newSize - oldSize); 0buffer.DelManyAt(1, i); 0IF (NOT terminatorFound) AND (buffer.Size = 0) THEN 4ReadBuffer; ,UNTIL terminatorFound OR (buffer.Size = 0); ,{$IFC fUniversalTextTrace} ,IF fPrintSecrets THEN 0BEGIN 0WRITELN('Buffer size is ',buffer.Size:1, ' data size is ',data.size:1); 0FOR i := 1 to data.size DO 4WRITE(data.At(i)); 0IF lineTerminator = CHR(chCr) THEN 4WRITE('') 0ELSE 4WRITE(''); 0WRITELN; 0WRITELN('LineOverflow is ', lineOverflow); 0END; ,{$ENDC} ,END (ELSE ,ReadLine := FALSE; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TReadUnivText.}ReadRun; ${----------------------------------------------------------------------------------------------------} $VAR error: INTEGER; (size: LONGINT; $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (BindUTDSeg(error); &{ Size up the tab and data arrays to take the next run } (SELF.data.DelAll; (SELF.data.EditAt(1, SELF.maxDataSize); &{ Set the achad to receive the next run } (WITH secrets.achad DO ,BEGIN ,rgch := POINTER(SELF.data.AddrMember(1)); ,ichFst := 0; ,ichLim := SELF.maxDataSize; ,END; (WITH secrets DO ,REPEAT .{ Get the next run } 0IF lpd.lplim = 0 THEN 4SetLpd(@Lpd, streamArrayIndex, 0, lpd.Tyset, achad) 0ELSE 4Seqlpd(@lpd, achad); ,UNTIL (NOT lpd.rce^.fvan) OR (achad.ichFst = achad.ichLim); ({$IFC fUniversalTextTrace} (IF fPrintSecrets THEN ,PrintSecrets(secrets.achad, secrets.lpd); ({$ENDC} &{ Convert to Run } (SELF.StreamToRun; (WITH secrets.lpd DO ,BEGIN ,IF tyset.fRpe THEN 0size := lpLimPar - lp {LSR: changed lpFstPar to lp} ,ELSE 0size := lpLim - lp; ,IF size > (lpLim-lp) THEN 0size := lpLim - lp; ,lpLim := lp + size; ,END; (IF size < SELF.data.size THEN ,SELF.data.DelManyAt(size + 1, SELF.data.size - size); (UnBindUTDSeg(error); ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTMain} {$ELSEC} {$S UTMain} {$ENDC} ${----------------------------------------------------------------------------------------------------} $FUNCTION {TReadUnivText.}GetParaPicture(heap: THeap) : PicHandle; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (GetParaPicture := NIL; ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END; {$IFC WithUObject} METHODS OF TTKWriteUnivText {$ELSEC} METHODS OF TWriteUnivText {$ENDC} {$IFC WithUObject} {$S TKUTWrite} {$ELSEC} {$S UTWrite} {$ENDC} ${----------------------------------------------------------------------------------------------------} {$IFC WithUObject} (FUNCTION {TWriteUnivText.}CREATE(object: TObject; JitsHeap: THeap; JitsTString: TString; JitsDataSize: INTEGER) _: TTKWriteUnivText; {$ELSEC} (FUNCTION {TWriteUnivText.}CREATE(object: TUTObject; JitsHeap: THeap; JitsTString: TUTString; JitsDataSize: INTEGER) _: TWriteUnivText; {$ENDC} ${----------------------------------------------------------------------------------------------------} $VAR (ptrToolKitUT: TPtrToolKitUT; (error: INTEGER; (index: TB; ({$IFC PasteTrace} (dbgCh: CHAR; ({$ENDC} $BEGIN ({$IFC PasteTrace} (WRITE('Do you want to debug (Y/N): '); (READ(dbgCh); (fPrintSecrets := dbgCh IN ['Y', 'y']; ({$ENDC} {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} (BindUTDseg(error); (IF error <> 0 THEN ,ABCBreak('BindUTDseg Error',error); (index := IcsCreate(tycsFld, SIZEOF(ToolKitUT), POINTER(ORD(itsHeap))); ({$R-} (ptrToolKitUT := POINTER( rghcs^[index]^ ); ({$R+} (WITH secrets DO ,BEGIN ,streamArrayIndex := index; ,lpd.tyset.fRpe := TRUE; ,lpd.tyset.fRce := TRUE; ,END; (WITH ptrToolKitUT^ DO ,BEGIN ,cspd.argproc[IProcSeqLpd] := @SeqLpdUTBB; ,cspd.argproc[IProcFreeIcs] := Pointer(procnil); ,cspd.argproc[IProcPxHcs] := Pointer(procnil); ,cspd.argproc[IProcFindLpFixed] := @FindLpFstPar; ,cspd.argproc[IProcFSelLpBounds] := @TrueStdSelLpBounds; ,END; (secrets.streamArrayIndex := index; (nOfSavedPara := 0; {Nothing in the backLogBuffer} (dataLp := 0; {Starting lpd} (IF object = NIL THEN {$IFC WithUObject} ,object := NewObject(itsHeap, THISCLASS); {$ELSEC} ,object := NewUTObject(itsHeap, THISCLASS); {$ENDC} {$IFC WithUObject} (SELF := TTKWriteUnivText(TTKUnivText.CREATE(object, itsHeap, itsTString, itsDataSize)); {$ELSEC} (SELF := TWriteUnivText(TUnivText.CREATE(object, itsHeap, itsTString, itsDataSize)); {$ENDC} ${ Get a default UT character and paragraph descriptors } (WITH secrets DO ,BEGIN ,lpd.rpe := @lpd.arpe; &{$H-} moveRgch(@lpd.arpe, @arpeStd, arpeStd.cb); {$H+} ,Lpd.rce := @lpd.arce; &{$H-} moveRgch(pointer(ord(lpd.rce)), @arceStd, arceStd.cb); {$H+} ,END; (SELF.StreamToRun; (activeStream := SELF; (SELF.data.DelAll; (StartGetScrap(error); (IF error <> 0 THEN ,ABCBreak('StartGetScrap Error',error); (PutCsScrap(index, error); (IF error <> 0 THEN ,ABCBreak('PutCsScrap Error',error); (freeics(index); (EndGetScrap(error); (IF error <> 0 THEN ,ABCBreak('EndGetScrap Error',error); (UnbindUTDseg(error); (IF error <> 0 THEN ,ABCBreak('UnbindUTDseg Error',error); ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTWrite} {$ELSEC} {$S UTWrite} {$ENDC} ${----------------------------------------------------------------------------------------------------} $PROCEDURE {TWriteUnivText.}FillParagraph; ${----------------------------------------------------------------------------------------------------} $BEGIN {$IFC fTraceUT} LogCall; {$ENDC} ({$IFC fTrce}BP(11);{$ENDC} {$IFC WithUObject} (ABCBreak('Failed to reimplement TTKWriteUnivText.FillParagraph',0); {$ELSEC} (ABCBreak('Failed to reimplement TWriteUnivText.FillParagraph',0); {$ENDC} ({$IFC fTrce}EP;{$ENDC} $END; {$IFC WithUObject} {$S TKUTInit} {$ELSEC} {$S UTInit} {$ENDC} END; 3. "6F^9DED!$ǐ^tKb-lib]? ' ic.lib} TD3. "6F^>g ΠƠ >H$EXEC {Install a Library in Intrinsic.lib} {filename build/install.text} $ ${ %0 -- number of the library to install} ${ %1 -- (optional)pathname for input intrinsic.lib. Defaults to } ${ -#boot-intrinsic.lib} ${ %2 -- (optional) pathname for output intrinsic.lib. Defaults to %1} $ $IF %0='' THEN #$WRITE 'Number Of The Library To Install? ' #$READLN %0 #$IF %1='' THEN &$WRITE 'Pathname For Input Intrinsic.lib [ For -#boot-intrinsic.lib]? ' &$READLN %1 &$IF %2='' THEN )$WRITE 'Pathname For Output Intrinsic.lib [ For -#boot-intrinsic.lib]? ' )$READLN %2 &$ENDIF #$ENDIF $ENDIF $DEFAULT %1 TO '-#boot-intrinsic.lib' $DEFAULT %2 TO %1 R{un}IUmanager %1 %2 I{nstall}%0 QY $ F{ile-MGR}B{ackup}%2,$ Q{uit} $ENDEXEC 3. "6F^5D!$ǐ^I$EXEC {BUILD/MAKE/ATKLIB -- Assemble modules needed by the Toolkit} F{ile-Mgr}D{elete}LIBTK/XFER.OBJ Y{es}Q{uit} $SUBMIT BUILD/ASSEMB(LIBTK/XFER) $ENDEXEC 3. "6F^5D!$ǐ^  f [$EXEC {BUILD/MAKE/CTKLIB -- Compile units needed by the Toolkit} F{ile-Mgr} D{elete}LIBTK/UUNIVTEXT.OBJ Y{es} D{elete}LIBTK/UTEXT.OBJ Y{es} D{elete}LIBTK/UDIALOG.OBJ Y{es} Q{uit} $SUBMIT BUILD/COMP(LIBTK/UUNIVTEXT) $SUBMIT BUILD/COMP(LIBTK/UTEXT) $SUBMIT BUILD/COMP(LIBTK/UDIALOG) $ENDEXEC 3. "6F^9DED!$ǐ^!!kKbISTART.TE6 TD3. "6F^$EXEC {BUILD/MAKE/CTKLIB -- Compile units needed by the Toolkit} F{ile-Mgr}D{elete}LIBTK/UOBJECT.OBJ Y{es} D{elete}LIBTK/UDRAW.OBJ Y{es} D{elete}LIBTK/UABC.OBJ Y{es} Q{uit} $SUBMIT BUILD/COMP(LIBTK/UOBJECT) $SUBMIT BUILD/COMP(LIBTK/UDRAW) $SUBMIT BUILD/COMP(LIBTK/UABC) $ENDEXEC 3. "6F^9DED!$ǐ^tKbVlib]? ' ic.lib} TD3. "6F^$EXEC {BUILD/MAKE/LTKLIB -- Link the Toolkit} F{ile-Mgr}D{elete}-#boot-TK2LIB.OBJ Y{es}Q{uit} L{ink}? +i +m TKUTInit SgTxtIni +m DlgInit SgTxtIni +m DlgAlloc SgTxtIni +m SgTxtHot SgTxtRes +m TK2Start SgParRes +m SgTxtWrm SgParRes +m DlgText SgTxtRes +m SgTxtCld SgTxtTwo +m DlgDbg SgDIAdbg +m DlgHot SgDialog +m DlgRes SgDialog +m DlgCold SgDialog +m DlgWarm SgDialog +m HdgMarg SgDialog +m DlgLayou SgLayout +m TKUTWrit TKUT +m TKUTMain TKUT LIBTK/UUNIVTEXT LIBTK/UTEXT LIBTK/UDIALOG -#boot-TKLIB -#boot-IOSPASLIB -#boot-SYS1LIB {no more input files} {no listing file} -#boot-TK2LIB $SUBMIT BUILD/INSTALL(11) $ENDEXEC 3. "6F^9DED!$ǐ^tKbYlib]? ' ic.lib} TD3. "6F^$EXEC {BUILD/MAKE/LTKLIB -- Link the Toolkit} F{ile-Mgr}D{elete}-#boot-TKLIB.OBJ Y{es}Q{uit} L{ink}? +i +M SgCLAres SgABCdat +M SgCLAcld SgABCdat +M sABCdat SgABCdat {remove} +M sSplit SgABCdat +M sRes SgDRWres +M sClick SgDRWres {SgABCdat} +M sFilter SgDRWres {SgABCdat} +M SgXFER SgABCres +M sHotUtil SgABCres {?} +M sStartup SgABCres +M sResDat SgABCres +M sCommand SgDRWres {SgABCdat} +M sCmd2 SgABCres +M sScroll SgABCres +M sLOX SgCLAini +M sError SgABCdbg +M Override SgCLAini +M sCldInit SgCLAdbg +M sInit1 SgABCini +M sAlert SgABCcld +M sUtil SgCLAdbg +M sCut SgABCdat +M sPaste SgABCdat LIBTK/UOBJECT LIBTK/UDRAW LIBTK/UABC LIBTK/XFER -#BOOT-IOSPASLIB -#BOOT-IOSFPLIB -#BOOT-SYS1LIB -#BOOT-PRLIB {no more input files} {no listing file} -#BOOT-TKLIB $SUBMIT BUILD/INSTALL(10) $ENDEXEC PASSWD INTRINSIC; {Provides calls for Password Protection in the Lisa Toolkit} { Copyright 1983, 1984, Apple Computer Inc. } INTERFACE "USES {$U -#BOOT-SYSCALL} syscall; "procedure MAKE_SECURE ( var ecode : integer; :var path : pathname; :var passwd : e_name ); "procedure KILL_SECURE ( var ecode : integer; :var path : pathname; :var passwd : e_name ); "procedure OPEN_SECURE ( var ecode : integer; :var path : pathname; :var refnum : integer; >manip : mset; :var passwd : e_name ); "procedure RENAME_SECURE ( var ecode : integer; var path : pathname; >var oldPasswd : e_name; >var newPasswd : e_name ); IMPLEMENTATION "procedure MAKE_SECURE ( var ecode : integer; 3. "6F^9DED!$ǐ^##Y;3. "6F^$EXEC {BUILD/MAKE/TKLIB -- build the Toolkit} $SUBMIT BUILD/ASSEMB(LIBPL/CLASLIB) $SUBMIT BUILD/COMP(LIBPL/UCLASCAL) $SUBMIT BUILD/MAKE/ATKLIB $SUBMIT BUILD/MAKE/CTKLIB $SUBMIT BUILD/MAKE/LTKLIB $SUBMIT BUILD/MAKE/CTK2LIB $SUBMIT BUILD/MAKE/LTK2LIB $ENDEXEC PASLIBCAintrinsic; interface "USES ${$U libos/syscall.obj } syscall; "CONST $CclearScreen = 1; {clear the whole screen} $CclearEScreen = 2; {clear to the end of the screen} $CclearELine = 3; {clear to end of line} $CgoHome = 11; {move cursor to home position} $CleftArrow = 12; {move cursor left one character position} $CrightArrow = 13; {move cursor right one character position} $CupArrow = 14; {move cursor up one line position} $CdownArrow = 15; {move cursor down one line position} $function PAbortFlag : boolean; {Apple-period entered or not} $PROCEDURE GetGPrefix (Var prefix : pathname); {get global working directory} $procedure ScreenCtr (contrfun : integer); {standard screen control functions} $procedure GetPrDevice (var PrDevice : e_name); $function PaslibVersion : integer; {return PASLIB version} $PROCEDURE PTranLisaChar (toTranslate : boolean); {to translate Lisa char when print} &{ Optional Call To Initialize the Heap } $procedure PLINITHEAP(var ernum,refnum: integer; size,delta: longint; 8ldsn: integer; swapable: boolean); implementation $$$$$$$$$$ $ $ $ $ $$$$$$$$$$$$$ O 9999  ! NOMPNQORPSQTRUSVT WU XV YW ZX [Y\Z][^\_]`^a_b`cadbecfdgehfigjhkiljmk nl!om"pn#qo$rp%sq&tr'us(vt)wu*xv+yw,zx-{y.|z/}{0~|1}2~3456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopq                                                  O       !" #!$"%#&$'%(&)'*(+),*-+.,/- 0.!1/"20#31$42%53&64'75(86)97*:8+;9,<:-=;.></?=0@>1A?2B@3CA4DB5EC6FD7GE8HF9IG:JH;KINL?OM@PNAQOBRPCSQDTREUSFVTGWUHXVIYWJZXK[YL\ZM][N^\O_]P`^Qa_Rb`ScaTdbUecVfdWgeXhfYigZjh[ki\lj]mk^nl_om`pnaqobrpcsqdtreusfvtgwuhxviywjzxk{yl|zm}{n~|o}p~qrstuvwxyz{      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} ~          !" #!$"%#&$'%(&)'*(+),*-+.,/-0.1/2031425364758697:8;9<:=;><?=@>A?B@CADBECFDGEHFIGJHKILJMK‚NLÂOMĂPNłQOƂRPLJQ T US VT WU XV YW ZX [Y \Z ][ ^\ _] `^ a_ b` ca db ec fd ge hf ig jh ki lj mk nl om pn qo rp sq tr !us "vt #wu $xv %yw &zx '{y (|z )}{ *~| +} ,~ - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~