***************************************************************************************************** ; WP Line Manipulation Routines ; ; This file contains the routines used by WP to manipulate the line handles data structure for ; paragraphs. The paragraph and line handle data strucutures are described below: ; ; The paragraph data structure is an array from 1..W_LastP of paragraph info blocks: ; ; W_pBlockHand gequ 0 : handle to the block that the par is in ; W_pOffset gequ 4 : offset into this block that starts the par ; W_pAttr gequ 6 : attribute word for the par ; W_pRulerHand gequ 8 : handle to the ruler that governs this par ; W_pPixels gequ 12 : number of pixels tall this par is ; W_pLineHand gequ 14 : handle to the line struct for this par (Purgeable) ; W_pLastLine gequ 18 : number of last line in the par+1, cr is 0 ; W_pBytes gequ 20 : equate for size of paragraph block. ; ; The linehandle will always have a header as follows ; ; W_MaxLine gequ 0 ; W_LineHeader gequ 4 ; ; The LineHandle in the paragraph record is an array from 0..W_lastline-1. Each record looks like: ; ; W_lOffset gequ 0 ; W_lFont gequ 2 ; W_lSize gequ 4 ; W_lStyle gequ 5 ; W_lColor gequ 6 ; W_lAscent gequ 8 ; W_lDescent gequ 10 ; W_lHeight gequ 12 ; W_lLeading gequ 14 ; lREcSize gequ 16 ; ***************************************************************************************************** load 'macros.dump' include 'driver.equ' include 'wp.equ' IMPORT D_BeachBall IMPORT D_Deref IMPORT D_GetStats IMPORT D_GetWdth IMPORT D_GrowLHandle IMPORT D_MainZPage IMPORT D_NeedHandle IMPORT D_MustHandle IMPORT D_MustGrowL IMPORT D_NoAlert IMPORT D_SelectFont IMPORT D_UnLock IMPORT W_DateStr IMPORT W_DeepShit IMPORT W_EndColor IMPORT W_EndFont IMPORT W_EndPtr IMPORT W_EndStyle IMPORT W_GetAddr IMPORT W_GetLeft IMPORT W_GetParRec IMPORT W_Hand IMPORT W_Indent IMPORT W_JustBits IMPORT W_JustExtra IMPORT W_JustPtr IMPORT W_JustSpaces IMPORT W_LastP IMPORT W_LeftMargin IMPORT W_MaxAscent IMPORT W_MaxDescent IMPORT W_MaxLeading IMPORT W_NumTabs IMPORT W_PageStr IMPORT W_ReadRuler IMPORT W_RightMargin IMPORT W_RulBits IMPORT W_STColor IMPORT W_STFont IMPORT W_STLIne IMPORT W_STPtr IMPORT W_STStyle IMPORT W_Tabs IMPORT W_TimeStr ENTRY W_CalcLineHeight ENTRY W_CutLine ENTRY W_GetLineRec ENTRY W_UseTab ***************************************************************************************************** ; W_MakeLines ( Paragraph:word ) ; ; This routine is called to generate all the textual information for the given paragraph. This ; routine will return an error if the line handle could not be allocated ( either because there is ; is not enough memory or because more than 4k lines exit in the paragraph ). W_MakeLines PROC EXPORT ;Using wpglobals input par:w local ptr:l,LineHand:l,LinePtr:l,MaxLine:w local ParRec:l,LineRec:l,LineBeg:l,pixels:w error err begin ; Get pointer to paragraph record and check if page break paragraph. If so no lines to make so just ; exit. stz err rcall W_GetParRec,in=(par:a),out=(ParRec:ax) cmpw [ParRec]:#W_pAttr,#W_PgBrk jeq exit ; Get ruler information for the paragraph. movelong [ParRec]:#W_pRulerHand,ax jsl W_ReadRuler ; Get line handle for paragraph. If no line handle exists then set paragraph line count to be ; initially 1. movelong [ParRec]:#W_pLineHand,LineHand cpzl LineHand bne chknil moveword #1,[ParRec]:#W_pLastLine bra getlinehand ; If line handle has been purged then dispose of old handle and fall through to create new one. chknil cpzl [LineHand] jne NotPurge tool _DisposeHandle,in=([ParRec]:#W_pLineHand:l) ; Ask for line handle large enough to hold all the lines in the paragraph. If we can't get it ; we're in trouble so use must handle. Note: Will fail if we have more than 4k lines in the ; paragraph. Line handle will be allocated as most purgeable status. getlinehand cmpw [ParRec]:#W_pLastLine,#$0FFF bge abort moveword #1,>D_NoAlert moveword [ParRec]:#W_pLastLine,a inc a asl a asl a asl a asl a clc adc #W_LineHeader ldx #0 call D_MustHandle,in=(ax:l,#$300:w),out=(LineHand:l),err=err moveword #0,>D_NoAlert bcc gotline ; Really bad error has occurred. Just return with error -1 (handled) and hope we recover. abort moveword #-1,err sta W_DeepShit tool _SysBeep movelong #0,[ParRec]:#W_pLineHand IF (Developing) THEN setborder #3 ENDIF brl unlocktext ; Successfully got the line handle (whew!) so put it in the paragraph. Put line count into start ; of line handle. gotline movelong LineHand,[ParRec]:#W_pLineHand movelong [LineHand],LinePtr moveword [ParRec]:#W_pLastLine,[LinePtr] ; Line handle exists. Loop through all lines getting line information as we go along. Lock down ; the line handle and the paragraph text block. Get the max line count. Get pointer to start of ; text block where paragraph font information is. NotPurge rcall D_Deref,in=(LineHand:ax),out=(LinePtr:ax) rcall D_Deref,in=([ParRec]:ax) moveword [LinePtr],MaxLine rcall W_GetAddr,in=(par:a,#0:x),out=(ptr:ax) ; Set up CutLine global variables. addlong #W_TextHeader,ptr,W_STPtr stz W_STLIne moveword [ptr],W_STFont moveword [ptr]:#2,W_STStyle moveword [ptr]:#4,a and #$ff sta W_STColor stz pixels ; Call cutline to determine the end values for the line we specified above. The global variables for ; the end font/style/color/ptr and max ascent/descent/leading will be set. Get pointer to the lines ; record. LineLoop jsl W_CutLine ; jsl D_BeachBall rcall W_GetLineRec,in=(LinePtr:ax,W_STLine:y),out=(LineRec:ax) ; Fill in line record information for current line. subword W_STPtr,ptr,[LineRec]:#W_lOffset moveword W_STFont,[LineRec]:#W_lFont moveword W_STStyle,[LineRec]:#W_lStyle moveword W_STColor,[LineRec]:#W_lColor moveword W_MaxAscent,[LineRec]:#W_lAscent moveword W_MaxDescent,[LineRec]:#W_lDescent clc adc W_MaxAscent moveword a,[LineRec]:#W_lHeight moveword W_MaxLeading,[LineRec]:#W_lLeading ; Adjust current pixel position by the height of the line (takes into account line spacing). movelong LineRec,ax jsl W_CalcLineHeight addword a,pixels,pixels ; Setup values for start of next line to be same as end of last line. moveword W_EndFont,W_STFont moveword W_EndStyle,W_STStyle moveword W_EndColor,W_STColor movelong W_EndPtr,LineBeg movelong W_EndPtr,W_STPtr ; If carriage return then we are done getting lines for the paragraph so branch. lda [LineBeg] and #$ff cmp #cr beq DoneLoop ; Bump the line count. If we have not exceed the line count for the paragraph go back and process the ; next line. inc W_STLIne cmpw W_STLIne,MaxLine jcc LineLoop ; Paragraph has grown. We need to enlarge the line handle to hold new line record information. Try to ; grow line handle by enough room for 10 more lines (160 bytes). If we can't get it we are in real ; trouble. If we will exceed the 4k lines limit then abort. addword #10,MaxLine,MaxLine cmp #$0FFF bge goabort inc a asl a asl a asl a asl a clc adc #W_LineHeader ldx #0 ; Try to grow the line handle. If we succeed then save new line count in line handle and go back for ; next line. Else abort. call D_MustGrowL,in=(ax:l,LineHand:l),out=(LinePtr:l),err=err bcs goabort moveword MaxLine,[LinePtr] brl LineLoop goabort brl abort ; Have successfully grown and filled line handle for the paragraph except for last line. Set offset ; for start of last line. Update the line count and pixel size for the paragraph. DoneLoop movelong LinePtr,ax ldy W_STLIne iny jsl W_GetLineRec movelong ax,LineRec subword LineBeg,ptr,[LineRec] lda W_STLIne inc a moveword a,[ParRec]:#W_pLastLine moveword pixels,[ParRec]:#W_pPixels ; Unlock the line and paragraph handles. rcall D_Unlock,in=(LineHand:ax) unlocktext rcall D_Unlock,in=([ParRec]:ax) exit return ENDP ***************************************************************************************************** ; W_ValidLines ( Paragraph:word ) ; ; This routine is called to generate all the textual information for the given paragraph. If the ; paragraph is not a page break and its line handle has been purged then it will call MakeLines to ; do the actual work of rebuilding the line information for this paragraph. W_ValidLines PROC EXPORT ;Using wpglobals input par:w local LineHand:l,parptr:l error err begin ; Get pointer to paragraph and see if its a page break. If so then its valid so exit. stz err rcall W_GetParRec,in=(par:a),out=(parptr:ax) cmpw [parptr]:#W_pAttr,#W_PgBrk beq exit ; Get line handle for paragraph. If no line handle exists or the handle has been purged then make ; new line information. movelong [parptr]:#W_pLineHand,LineHand cpzl LineHand beq notvalid cpzl [LineHand] bne exit ; Line information is no longer valid call make lines to update it. notvalid call W_MakeLines,in=(par:w),err=err exit return ENDP ***************************************************************************************************** ; W_CutLine ( ) ; ; This routine is called to cut the line described in the following global variables: ; ; W_STFont word ; starting font ; W_STStyle byte ; starting style ; W_STSize byte ; starting font size ; W_STColor word ; starting text color ; W_STPtr long ; pointer to start of line text ; W_STLine word ; starting line ; ; The following globals will have been set on return from this routine: ; ; W_EndFont word ; ending font ; W_EndStyle byte ; ending style ; W_EndSize byte ; ending font size ; W_EndColor word ; ending text color ; W_EndPtr long ; pointer to end of line text ; ; W_MaxAscent word ; max ascent found in line ; W_MaxDescent word ; max descent found in line ; W_MaxLeading word ; max leading found in line ; ; W_JustPtr long ; pointer used for justification ; W_JustBits word ; ; W_JustSpaces word ; number of spaces to use for justify ; W_JustExtra long ; extra pixels to justify W_CutLine PROC EXPORT ;Using wpglobals local CurH:w,ChrPtr:l,LastH:w,lflag:w,lflag2:w,WasLastSp:w local tFont:w,tstyle:w,tcolor:w,StringPtr:l local tAscent:w,tDescent:w,tLeading:w begin ; Setup default values for tFont/tStyle/tColor & EndFont/EndStyle/EndColor. Then select the font. stz WasLastSp lda W_STFont sta tFont sta W_EndFont ldx W_STStyle stx tstyle stx W_EndStyle ldy W_STColor sty tcolor sty W_EndColor jsl D_SelectFont ; Get stats for current font. jsl D_GetStats sta W_MaxAscent stx W_MaxDescent sty W_MaxLeading ; Clear temp values for ascent, descent, and leading. stz tAscent stz tdescent stz tleading ; Set flags so first character will determine height. moveword #1,lflag stz W_JustSpaces stz lflag2 ; Setup initial values of various pointers to be same as start of text. movelong W_StPtr,ax movelong ax,ChrPtr movelong ax,W_JustPtr movelong ax,W_EndPtr ; Get current horizontal position for the line and set last position to it as well. lda W_STLIne jsl W_GetLeft sta CurH sta LastH ; All flags and variables now initialized. Loop through characters in line adjusting pointers and ; global variables as we cut the line. If character is not one of the supported characters then ; branch else if special character jump to handler. ChrLoop lda [ChrPtr] and #$ff cmp #SP beq isspace bcs RegChr cmp #CR+1 bcc isspecial brl BadChar isspace brl HitSP isspecial asl a tax jmp (ChrTable,x) ; Bad character detected in WP; used to die now will treat character as a normal character. Set gray ; border if developing to say we caught an old error and survived! Character will be changed to a ; DEL char. BadChar IF (Developing) THEN setborder #3 ENDIF lda #$FF sta [ChrPtr] ; Regular character entered call check stuff to adjust values for ascent/descent/leading as needed. ; Make sure to preserve character in A-reg. Get width of character and adjust the current horizontal ; position. RegChr pha jsr CheckStuff pla jsl D_GetWdth clc adc CurH sta CurH ; Check if current horizontal has exceeded the right margin. If not bump the character pointer and ; go back for next character. chkright cmpw CurH,W_RightMargin bcs pastmarg incl ChrPtr bra ChrLoop ; We have gone past the right margin. Check to see if the current character is a space; branch if ; not. Else check if last character was a space ( ie two spaces in a row ); if not just set last ; space to where last horizontal was and branch back to the character loop. pastmarg lda [ChrPtr] and #$ff cmp #sp bne NoEndSpace lda WasLastSp bne WrapExSpace moveword LastH,WasLastSp brl ChrLoop ; Comes here if two spaces were kept past the margin. Dont count space length before doing a regular ; word wrap. ( Extra space was wrapped ). WrapExSpace moveword WasLastSp,LastH bra RegWordWrap ; If start pointer is no longer same as end pointer then treat as regular word wrap. NoEndSpace cmpw W_STPtr,W_EndPtr bne RegWordWrap ; If no spaces on the line then use character that exceeded the right margin. addlong #1,ChrPtr,W_EndPtr movelong W_EndPtr,W_JustPtr moveword CurH,LastH moveword tAscent,W_MaxAscent moveword tDescent,W_MaxDescent moveword tLeading,W_MaxLeading moveword tfont,W_EndFont moveword tstyle,W_EndStyle moveword tcolor,W_EndColor ; This is the regular word wrap exit. Just bits will get the number of pixels difference between ; the last seen horizontal position and the right margin. Check if we are in full justification ; mode. If so calculate the extra space that will be needed per blank to justify the line. RegWordWrap subword W_RightMargin,LastH,W_JustBits lda W_RulBits and #W_r_full beq killjust ; Check if single word on line ( just spaces <= 1 ). If so then zero extra justification space. stzl W_JustExtra cmpw W_JustSpaces,#2 blt exit ; At least two spaces exist on line so get justification amount needed for drawing line. spacelong pushword W_JustBits lda W_JustSpaces dec a pha _FixRatio pullLong W_JustExtra bra exit ; Move end pointer to just ptr for no justification. killjust movelong W_EndPtr,W_JustPtr exit return ;...................................................................................................; ; Check if ascent/descent/leading need to be changed. Iflag will be set when a change has been ; detected to font/style/size. Get the ascent/descent/size for the current font and adjust the ; running values if they are too small. CheckStuff ldy lflag beq NoHtChan stz lflag lda tfont ldx tstyle ldy tcolor jsl D_SelectFont jsl D_GetStats cmp tAscent bcc NotMaxA sta tAscent NotMaxA cpx tDescent bcc NotMaxD stx tDescent NotMaxD cpy tLeading bcc NoHtChan sty tLeading NoHtChan rts ;...................................................................................................; ; get new font and set both changed flags. bump character pointer by 3. fChange moveword [ChrPtr]:#1,tFont lda #3 bra bumpflags ;...................................................................................................; ; get new style and set both changed flags. bump character pointer by 2. StyleChange ldy #1 lda [ChrPtr],y shortm sta tStyle longm bra bump2 ;...................................................................................................; ; get new size and set both changed flags. bump character pointer by 2. SizeChange ldy #1 lda [ChrPtr],y shortm sta tStyle+1 longm bump2 lda #2 bra bumpflags ;...................................................................................................; ; get new color and set something changed flag. bump character pointer by 2. ColorChange ldy #1 lda [ChrPtr],y and #$ff sta tColor lda #2 bra bumpflag2 ;...................................................................................................; ; set change flags and bump character pointer by value in A-reg. bumpflags inc lflag bumpflag2 inc lflag2 addwl a,ChrPtr brl ChrLoop ;...................................................................................................; ; Tab character encountered. Bump current horizontal if not past right margin. Adjust justification ; values and cut line output variables. HitTab jsr CheckStuff addlong #1,ChrPtr,W_EndPtr movelong W_EndPtr,W_JustPtr ; Get position of next tab. If zero is returned then tab would go past the right margin and we should ; treat the tab as carriage return for a soft line wrap, otherwise adjust current horizontal position. call W_UseTab,in=(tfont:w,tstyle:w,tcolor:w,CurH:w,ChrPtr:l),out=(a:w) jeq HitCr sta CurH ; Tab found so clear number of justification spaces, and changed flag. stz W_JustSpaces stz lflag2 ; Update the cut line out values. The current horizontal position is the last break position since ; we can break on tabs or spaces. If we were to break the max values for ascent/descent/leading ; would be the current running values and the font/style/color at the end of the line would be the ; current values. moveword CurH,LastH moveword tAscent,W_MaxAscent moveword tDescent,W_MaxDescent moveword tLeading,W_MaxLeading moveword tfont,W_EndFont moveword tstyle,W_EndStyle moveword tcolor,W_EndColor brl chkright ;...................................................................................................; ; Page/Date/Time width character encountered. Set pointer to string then do width. PageWidth movelong #W_PageStr,StringPtr bra DoWidth DateWidth movelong #W_DateStr,StringPtr bra DoWidth TimeWidth movelong #W_TimeStr,StringPtr DoWidth jsr CheckStuff tool _StringWidth,in=(StringPtr:l),out=(a:w) addword a,CurH,CurH brl chkright ;...................................................................................................; ; Carriage return encountered. Set end pointer and justification pointer to location of carriage ; return. HitCr movelong ChrPtr,ax movelong ax,W_JustPtr movelong ax,W_EndPtr ; Update ascent/descent/leading values if they have changed. Update ending font/style/color. Put ; difference between right margin and current horizontal position into just bits then exit. Note: ; last line of paragraphs is not justified ( this is what we want ). lda tascent ora tDescent ora tLeading beq MaxsOk moveword tAscent,W_MaxAscent moveword tDescent,W_MaxDescent moveword tLeading,W_MaxLeading MaxsOk moveword tfont,W_EndFont moveword tstyle,W_EndStyle moveword tcolor,W_EndColor subword W_RightMargin,CurH,W_JustBits brl exit ;...................................................................................................; ; Space detected. Increment the number of spaces count for justification. Point the end pointer just ; paste the space character. Set the last seen horizontal break location to the current horizontal ; position where the space was found. HitSp inc W_JustSpaces addlong #1,ChrPtr,W_EndPtr moveword CurH,LastH ; If Iflag2 has not been set then no changes have occurred yet so skip setting new values, else clear ; the flag and set the latest return values. lda lflag2 beq SkipStuff stz lflag2 moveword tAscent,W_MaxAscent moveword tDescent,W_MaxDescent moveword tLeading,W_MaxLeading moveword tfont,W_EndFont moveword tstyle,W_EndStyle moveword tcolor,W_EndColor ; Handle space as regular character at this point. SkipStuff lda #sp brl RegChr ;...................................................................................................; ; Routines to handle the character found. Note uses BadChar if character is undefined and HitSp if ; character is a space. ChrTable DC.W BadChar,fChange ;0,1 DC.W styleChange,SizeChange ;2,3 DC.W ColorChange,PageWidth ;4,5 DC.W DateWidth,TimeWidth ;6,7 DC.W BadChar,HitTab ;8,9 DC.W BadChar,BadChar ;a,b DC.W BadChar,HitCR ;c,d ENDP ***************************************************************************************************** ; W_GetLRecPtr ( par:word, line:word ): LineRecPtr:ax ; ; This routine will return a pointer to the record for the given line of the given paragraph. If ; unable to validate lines for the paragraph then return error #-1. W_GetLRecPtr PROC EXPORT input par:w,line:w local ParRec:l,Hand:l output LineRec:l error err begin stzl LineRec call W_ValidLines,in=(par:w),err=err bcs exit rcall W_GetParRec,in=(par:a),out=(parrec:ax) movelong [ParRec]:#W_pLineHand,Hand ldy #2 lda [Hand],y tax lda [Hand] ldy line jsl W_GetLineRec movelong ax,LineRec exit return ENDP ***************************************************************************************************** ; W_GetLineRec ( LinePtr:ax, Line:y ): LineRecPtr:ax ; ; This routine will return a pointer in A,X to the record for the given line. LinePtr points to ; the start of the line handle to be used. W_GetLineRec PROC EXPORT pha tya asl a asl a asl a asl a adc #W_LineHeader clc adc 1,s bcc exit inx exit ply rtl ENDP ***************************************************************************************************** ; W_UseTab ( CurFont:word, CurStyle:word, CurColor:word, CurH:word, CurPtr:long ):NextH:word ; ; This routine will return horizontal position where placing text should continue given the ; current font/style/color horizontal position and a pointer to the text. If the tab places us past ; the right margin then return 0 for the next horizontal pixel position. CurH is where text up to ; CurPtr ends horizontally. CurPtr should point past the tab. ; ; CAUTION: This routine can change the current font ; NOTE: This routine assumes that the text block for the paragraph has been locked down. W_UseTab PROC EXPORT ;Using wpglobals input CurFont:w,CurStyle:w,CurColor:w,CurH:w,CurPtr:l local xTab:w,CurTab:l,TextWidth:w,Room:w,StringPtr:l local FontChange:w,Indent:w output NextH:w begin ; Clear return value and font change flag. stz NextH stz fontChange jsr selectfont ; Check if center or right justification if so branch and treat tab as just another space. lda W_RulBits and #W_r_full+W_r_left jeq MakeItSpace ; Get the number of tabs in ruler. If none then return with zero for horizontal, else get max tab ; offset. lda W_NumTabs jeq MakeCurH asl a asl a sta xTab ; Find tab in table if not found then return with past right margin (0) value for NextH. ldx #0 LookTab cmpw CurH,W_Tabs:x bcc GetIndent inx inx inx inx cpx xTab bcc LookTab brl exit ; Determine whether to use indent margin or left margin as a possible tab stop. GetIndent moveword W_Indent,Indent cmp W_LeftMargin bge FoundTab moveword W_LeftMargin,Indent ; Found tab. If current horizontal position is less than indent margin and indent margin is less than ; the tab we found then use indent margin instead of tab, else use tab position for CurTab. FoundTab cmpw CurH,Indent bge NoUseIndent cmpw Indent,W_Tabs:x bge NoUseIndent moveword Indent,CurTab stz CurTab+2 bra GotCurTab NoUseIndent movelong W_Tabs:x,CurTab ; Check if found tab position will extend past the current right margin if so just return with 0 for ; NextH. GotCurTab cmpw CurTab,W_RightMargin jge exit ; Set NextH to found tab position. If tab is a left tab then we are done. If tab is decimal or right ; tab we still have some work to do. moveword CurTab,NextH lda CurTab+2 jeq exit ; Point to next character. Determine how much room exists between the tab and the current horizontal ; position. Clear text width so far accumulated. incl CurPtr subword CurTab,CurH,Room stz TextWidth ; Main character loop. Check if decimal found (for decimal tabs). If not then branch to handle char. ; If period found and decimal tab then adjust for the tab and exit, else treat the period as a ; regular character. ChrLoop lda [CurPtr] and #$ff cmp #'.' bne noPer ldy CurTab+2 bpl RegChr brl AdjustTab ; Check if character is valid, special character, or bad character and branch to the correct ; handler. NoPer cmp #sp bcs RegChr cmp #cr+1 bcs badchar UseTable asl a tax jmp (ChrTable,x) ; Bad character detected in WP; used to die now will treat character as a normal character. Set gray ; border if developing to say we caught an old error and survived! Character will be changed to a ; DEL char. BadChar IF (Developing) THEN setborder #3 ENDIF lda #$FF sta [CurPtr] ; Regular character encountered. If font changes have been detected then select font before getting ; width of character. Get width of character and add it to the running text width. If width exceeds ; the room available then simply return with the tab position as found, else point to next character ; and go back for more. RegChr pha lda FontChange beq NoSelf jsr selectfont NoSelf pla jsl D_GetWdth clc adc TextWidth sta TextWidth GotTW cmp Room bge MakeCurH incl CurPtr brl ChrLoop ; Tab character encountered. Make sure current font selected. If we ran out of room before the tap ; then return with NextH set to zero. Else return with NextH = CurH + (Room-TextWidth). AdjustTab jsr selectfont lda Room sec sbc TextWidth bmi exit clc adc CurH sta NextH bra exit ; Treat the tab as a space character. Get the width of a space character and set NextH accordingly, ; unless it will exceed the right margin in which case we should return zero. MakeItSpace lda #sp jsl D_GetWdth addword a,CurH,a cmp W_RightMargin bcs MakeCurH sta NextH bra exit ; Set return value to current horizontal value and return to caller. MakeCurH moveword CurH,NextH exit jsr selectfont return ;...................................................................................................; ; get new font and bump character pointer by 3. FChange ldy #1 lda [CurPtr],y sta CurFont lda #3 bra bumpptr ;...................................................................................................; ; get new size and bump character pointer by 2. SizeChange ldy #1 lda [CurPtr],y shortm sta CurStyle+1 longm bra bumpby2 ;...................................................................................................; ; get new style and bump character pointer by 2. StyleChange ldy #1 lda [CurPtr],y shortm sta CurStyle longm bra bumpby2 ;...................................................................................................; ; get new color and bump character pointer by 2. ColorChange ldy #1 lda [CurPtr],y and #$ff sta CurColor bumpby2 lda #2 ;...................................................................................................; bumpptr addwl a,CurPtr moveword #1,FontChange brl ChrLoop ;...................................................................................................; ; Page/Date/Time width character encountered. Set pointer to string then do width. PageWidth movelong #W_PageStr,StringPtr bra DoWidth DateWidth movelong #W_DateStr,StringPtr bra DoWidth TimeWidth movelong #W_TimeStr,StringPtr DoWidth tool _StringWidth,in=(StringPtr:l),out=(a:w) addword a,TextWidth,TextWidth brl GotTW ;...................................................................................................; ; Select the current font, style, and color. selectfont rcall D_SelectFont,in=(CurFont:a,CurStyle:x,CurColor:y) rts ;...................................................................................................; ChrTable DC.W BadChar,FChange ;0,1 DC.W StyleChange,SizeChange ;2,3 DC.W ColorChange,PageWidth ;4,5 DC.W DateWidth,TimeWidth ;6,7 DC.W BadChar,AdjustTab ;8,9 DC.W BadChar,BadChar ;a,b DC.W BadChar,AdJustTab ;c,d ;...................................................................................................; ENDP ***************************************************************************************************** ; W_CalcLineHeight ( LineRecPtr:ax ): Height:a, Descent:x ; ; This routine will return the height and descent for the given line. The routine will take into ; account the current line spacing. W_CalcLineHeight PROC EXPORT ;Using wpglobals ;Using D_GlobalData ptr equ 0 W_Leading equ 4 W_HeightNL equ 6 height equ 8 descent equ 10 tay phd lda >D_MainZPage tcd sty ptr stx ptr+2 moveword [ptr]:#W_lHeight,W_HeightNL addword [ptr]:#W_lLeading,W_HeightNL,height moveword [ptr]:#W_lDescent,descent lda W_RulBits and #W_r_single bne exit lda W_HeightNL lsr a addword a,height,height lda W_RulBits and #W_r_double bne exit lda W_HeightNL lsr a addword a,height,height exit lda height ldx descent pld rtl ENDP ***************************************************************************************************** ; W_FindFont ( par:word, line:word, offset:word ): font:long, color:word ; ; This routine will return font and color for the given paragraph line and the given offset. ; ; NOTE: This routine will return an error if GetLRecPtr can not get a pointer to the line record. W_FindFont PROC EXPORT ;Using wpglobals input Par:w,line:w,offset:w local LineRec:l,StartPtr:l,MaxLook:w,ParRec:l output font:l,color:w error err begin ; Get pointer to paragraph record. stz err rcall W_GetParRec,in=(par:a),out=(parrec:ax) ; If paragraph is a page break then look at next paragraph line 0 to get the font and color. cmpw [ParRec]:#W_pAttr,#W_PgBrk bne NotPB inc par stz line moveword #W_TextHeader,offset ; Get pointer to line record for the given paragraph line. From the line record extract the default ; font, style, and color to use for the line. NotPB call W_GetLRecPtr,in=(par:w,line:w),out=(LineRec:l),err=err jcs exit moveword [LineRec]:#W_lFont,font moveword [LineRec]:#W_lStyle,font+2 ;STYLE moveword [LineRec]:#W_lColor,color ; Get pointer to start of line text. moveword [LineRec]:#W_lOffset,x stx MaxLook lda par jsl W_GetAddr movelong ax,StartPtr ; Determine maximum number of character we wish to look at by subtracting the given offset into the ; line from the starting offset of the line in the text block. subword offset,MaxLook,MaxLook ; Until we get to the point in the line that we want accumulate font/style/color changes. ldy #0 ChrLoop cpy MaxLook jcs exit lda [StartPtr],y and #$ff iny cmp #sp bcs ChrLoop cmp #cr+1 bcs BadChar asl a tax jmp (ChrTable,x) ; Bad character detected in WP; used to die now will treat character as a normal character. Set gray ; border if developing to say we caught an old error and survived! Character will be changed to a ; DEL char. BadChar IF (Developing) THEN setborder #3 ENDIF dey lda #$FF sta [StartPtr],y iny bra Chrloop ; Font change encountered. Save new running font and point Y-reg past font info. FChange lda [StartPtr],y sta Font iny iny brl ChrLoop ; Size change encountered. Save new running size and point Y-reg past size info. SizeChange lda [StartPtr],y shortm sta Font+3 longm iny brl ChrLoop ; Style change encountered. Save new running style and point Y-reg past style info. StyleChange lda [StartPtr],y shortm sta Font+2 longm iny brl ChrLoop ; Color change encountered. Save new running color and point Y-reg past color info. ColorChange lda [StartPtr],y and #$ff sta color iny brl ChrLoop exit return ;...................................................................................................; ChrTable DC.W BadChar,FChange ;0,1 DC.W StyleChange,SizeChange ;2,3 DC.W ColorChange,ChrLoop ;4,5 DC.W ChrLoop,ChrLoop ;6,7 DC.W BadChar,ChrLoop ;8,9 DC.W BadChar,BadChar ;a,b DC.W BadChar,ChrLoop ;c,d ;...................................................................................................; ENDP ***************************************************************************************************** ; W_ReadFont ( font:long, color:word, StartPtr:long, EndPtr:long ): font:long, color:word ; ; This routine will return font and color for the text between the two given pointers. W_ReadFont PROC EXPORT input InFont:l,InCol:w,StartPtr:l,Ptr2:l local MaxLook:w output font:l,color:w begin ; Initialize starting font and color from inputs and determine maximum number of characters to be ; examined. movelong InFont,font moveword InCol,color subword Ptr2,StartPtr,MaxLook ; Until we get to the point in the line that we want accumulate font/style/color changes. ldy #0 ChrLoop cpy MaxLook jcs exit lda [StartPtr],y and #$ff iny cmp #sp bcs ChrLoop cmp #cr+1 bcs BadChar asl a tax jmp (ChrTable,x) ; Bad character detected in WP; used to die now will treat character as a normal character. Set gray ; border if developing to say we caught an old error and survived! Character will be changed to a ; DEL char. BadChar IF (Developing) THEN setborder #3 ENDIF dey lda #$FF sta [StartPtr],y iny bra Chrloop ; Font change encountered. Save new running font and point Y-reg past font info. FChange lda [StartPtr],y sta Font iny iny brl ChrLoop ; Size change encountered. Save new running size and point Y-reg past size info. SizeChange lda [StartPtr],y shortm sta Font+3 longm iny brl ChrLoop ; Style change encountered. Save new running style and point Y-reg past style info. StyleChange lda [StartPtr],y shortm sta Font+2 longm iny brl ChrLoop ; Color change encountered. Save new running color and point Y-reg past color info. ColorChange lda [StartPtr],y and #$ff sta color iny brl ChrLoop exit return ;...................................................................................................; ChrTable DC.W BadChar,FChange ;0,1 DC.W StyleChange,SizeChange ;2,3 DC.W ColorChange,ChrLoop ;4,5 DC.W ChrLoop,ChrLoop ;6,7 DC.W BadChar,ChrLoop ;8,9 DC.W BadChar,BadChar ;a,b DC.W BadChar,ChrLoop ;c,d ;...................................................................................................; ENDP ***************************************************************************************************** ; W_UpdateLines ( par:word, line:word, amount:word ) ; ; This routine will add the given amount to the offset into the text block of every line after the ; given line. ( useful for inserting text on the line and keeping all the other lines correct ). ; ; Note: Can return an error if valid lines fails. W_UpdateLines PROC EXPORT input par:w,line:w,amount:w local ParRec:l,LineRec:l,LineHand:l,lines:w error err begin ; Make sure line handle contains valid lines for the given paragraph. If error then abort and hope ; for the best. call W_ValidLines,in=(par:w),err=err jcs exit ; Get pointer to paragraph record. Get number of lines in the paragraph. Get pointer to the given ; line's record. rcall W_GetParRec,in=(par:a),out=(ParRec:ax) moveword [ParRec]:#W_pLastLine,lines movelong [ParRec]:#W_pLineHand,LineHand movelong [LineHand],LineRec rcall W_GetLineRec,in=(LineRec:ax,line:y),out=(LineRec:ax) ; Add amount to each line's offset after the given line. ldy #W_lOffset Loop inc line tya clc adc #W_lBytes tay addword Amount,[LineRec]:y,[LineRec]:y cmpw line,lines bcc Loop exit return ENDP ***************************************************************************************************** ; W_CutLine2 ( par:word, line:word ) ; ; This routine will setup the entry values to CutLine for the given line and paragraph and then ; will call CutLine to determine where the given paragraph line should be cut and what its end line ; attributes are. (see CutLine for more details) ; ; NOTE: This routine can return an error if the line handle does not exist for the paragraph. W_CutLine2 PROC EXPORT ;Using wpglobals input par:w,line:w local ptr:l,LineHand:l,LineRecPtr:l error err begin ; Get pointer to current paragraph record and put its ruler info in the ruler globals. moveword #1,err rcall W_GetParRec,in=(par:a),out=(ptr:ax) rcall W_ReadRuler,in=([ptr]:#W_pRulerHand:ax) ; Make sure line handle exists else return with error set. movelong [ptr]:#W_pLineHand,LineHand cpzl LineHand jeq exit ldy #2 lda [LineHand] ora [LineHand],y jeq exit stz err ; Set starting font/style/color and starting ptr/line values for cutline to use. If line handle does ; not exist or has been purged then return with error set. rcall W_GetLineRec,in=([LineHand]:ax,line:y),out=(LineRecPtr:ax) moveword [LineRecPtr]:#W_lFont,W_STFont moveword [LineRecPtr]:#W_lStyle,W_STStyle moveword [LineRecPtr]:#W_lColor,W_STColor moveword [LineRecPtr]:#W_lOffset,a tax lda par jsl W_GetAddr movelong ax,W_STPtr moveword line,W_STLIne ; Set just ptr and end ptr to start of next line. moveword [LineRecPtr]:#W_lOffset+W_lBytes,a tax lda par jsl W_GetAddr movelong ax,W_JustPtr movelong ax,W_EndPtr ; Cut line to do the actual work of determining where this paragraph line should be cut. jsl W_CutLine exit return ENDP ***************************************************************************************************** ; W_GetLineAddr ( par:word, line:word ) ptr:long ; ; This routine will return a pointer to the start of the given paragraph line's text. ; ; Note: This routine can return an error if ValidLines fails. W_GetLineAddr PROC EXPORT input par:w,line:w local ptr:l,LineHand:l,LinePtr:l output LineAddr:l error err begin ; Make sure paragraph lines are valid. If can't make lines valid we're in trouble error on up. call W_ValidLines,in=(par:w),err=err jcs exit ; Get pointer to start of line's text. rcall W_GetParRec,in=(par:a),out=(ptr:ax) movelong [ptr]:#W_pLineHand,LineHand movelong [LineHand],LinePtr rcall W_GetLineRec,in=(LinePtr:ax,Line:y),out=(ptr:ax) moveword [ptr]:#W_lOffset,x lda par jsl W_GetAddr movelong ax,LineAddr exit return ENDP ***************************************************************************************************** ; W_GetEndLine ( par:word, line:word ): offset:word ; W_GetLineOffset ( par:word, line:word ): offset:word ; W_GetBegLine ( par:word, line:word ): offset:word ; ; The following shared code is used by the above three routines to return the requested offset ; into the given paragraph line's text. ; ; Note: These routine can return errors if the paragraph line handle could not be validated. W_GetEndLine PROC EXPORT EXPORT W_GetLineOffset EXPORT W_GetBegLine ; Get end by bumping line count first to next line. lda 4,s inc a sta 4,s W_GetLineOffset W_GetBegLine input par:w,line:w local ptr:l,LineHand:l,LinePtr:l output offset:w error err begin ; Make sure that valid line handle exists for this paragraph. If we can't make a valid line handle ; then we are in serious trouble pass the error on up. call W_ValidLines,in=(par:w),err=err bcs exit ; Get offset for the given line from its line record information. rcall W_GetParRec,in=(par:a),out=(ptr:ax) movelong [ptr]:#W_pLineHand,LineHand movelong [LineHand],LinePtr rcall W_GetLineRec,in=(LinePtr:ax,Line:y),out=(ptr:ax) moveword [ptr]:#W_lOffset,offset exit return ENDP ***************************************************************************************************** ; W_NextLine ( par:word, line:word ) par:word, line:word ; ; This routine will return the paragraph and line for the line following the given paragraph line. ; An error will be returned if this is already the last line of the last paragraph. W_NextLine PROC EXPORT ;Using wpglobals input par:w,line:w output OPar:w,OLine:w local ParRec:l error err begin ; Bump line count. If it the given paragraph has enough lines we're done. stz err moveword par,OPar moveword line,OLine inc OLine rcall W_GetParRec,in=(par:a),out=(ParRec:ax) cmpw Oline,[ParRec]:#W_pLastLine bcc exit ; Else bump the paragraph count. If we were already on the last paragraph then return error set. inc OPar stz OLine cmpw W_LastP,OPar bcs exit inc err exit return ENDP END