
	load 'macros.dump'
	include 'driver.equ'
	include 'pl.equ'

;-----------------------------------------------
;
;   Imported addresses
;
;-----------------------------------------------

	IMPORT	D_BitMapChanged
	IMPORT	D_BitMapPtr
	IMPORT	D_ClearBitMap
	IMPORT	D_Deref
	IMPORT	D_DrawText
	IMPORT	D_GetStats
	IMPORT	D_KillFont
	IMPORT	P_ContentRect
	IMPORT	P_CurrentWin
	IMPORT	P_DrawFigure
	IMPORT	P_H
	IMPORT	P_Page
	IMPORT	P_PageMode
	IMPORT	P_V
	IMPORT	D_RectZap
	IMPORT	D_SelectFont
	IMPORT	D_Set4Pat
	IMPORT	T_CountSpaces
	IMPORT	T_CurColor
	IMPORT	T_CurFont
	IMPORT	T_CurParHdl
	IMPORT	T_CurRulBits
	IMPORT	T_CurSize
	IMPORT	T_CurStyle
	IMPORT	T_GetParPtr
	IMPORT	T_GetSpacing
	IMPORT	T_GetStart
	IMPORT	T_LockLines
	IMPORT	T_LockRuler
	IMPORT	T_MulLine
	IMPORT	T_ScalePort
	IMPORT	T_TrackFont
	IMPORT	T_UnlockRuler
	IMPORT	T_UseTab
	IMPORT	P_PageRect
	IMPORT	P_FullPageRect

;-----------------------------------------------
;
;   Forward addresses and entries
;
;-----------------------------------------------

	ENTRY	T_DrawLine
	ENTRY	T_DrawLines
	ENTRY	T_DrawOSLine



;-------------------------------------------------------------------------------
;
; T_Update (ObjHdl:l; Printing:w)
;


T_Update	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		INPUT ObjHdl:l,Printing:w

		LOCAL ObjPtr:l,ParagHdl:l,ParagPtr:l
		LOCAL ParagNo:w,StartLine:w,VertPos:w,Q_Rect:r
		LOCAL ParagCount:w,MaxHeight:w


		BEGIN

		pushlong T_CurParHdl

		rcall D_Deref,in=(ObjHdl:ax),out=(ObjPtr:ax)
		movelong [ObjPtr]:#P_ParagHdl,ParagHdl
		movelong ParagHdl,T_CurParHdl
		rcall T_GetParPtr,in=(#0:a),out=(ParagPtr:ax)
		moveword [ParagPtr],ParagCount


		moverect [ObjPtr]:#P_ObjRect,Q_Rect
		subword Q_Rect+4,Q_Rect,MaxHeight


		lda Printing
		bne Skip

		tool _SetPensize,in=(#2:w,#1:w)
		call D_Set4Pat,in=(#3:w)
		call P_DrawFigure,in=(#P_RECTANGLE:w,Q_Rect:l,Q_Rect+4:l)
		tool _PenNormal
Skip


		moveword [ObjPtr]:#P_StartParag,ParagNo
		moveword [ObjPtr]:#P_StartLine,StartLine
		stz VertPos

		lda ParagNo
		cmp #$FFFF
		beq Done


ParLoop
		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)

		in ObjPtr:l,ParagNo:w,StartLine:w,[ParagPtr]:#T_LineCount:w
		in VertPos:w,#0:w
		out VertPos:w
		xcall T_DrawLines

		cmp MaxHeight
		bge Done

		inc ParagNo
		cmpw ParagNo,ParagCount
		bge Done

		stz StartLine
		bra ParLoop


Done
		pulllong T_CurParHdl
		tool _HUnlock,in=(ObjHdl:l)

		RETURN
		ENDP




;-------------------------------------------------------------------------------
;
; T_DrawParag (ParagNo:w,StartLine:w,MaxLine:w,VertPos:w)
;
; Draw the specified lines in the specified paragraph.  Cross object bounds
; if neccessary.
;
; Current Bugs
;			 1. May not handle MaxLine correctly if it is not the last Q_Line
;				and the paragraph crosses objects.

T_DrawParag	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_TextEqu
			;Using T_Data

		INPUT ParagNo:w,StartLine:w,MaxLine:w,VertPos:w
		LOCAL ObjHdl:l,ObjPtr:l,ParagPtr:l

		BEGIN

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_ObjHdl,ObjHdl
		movelong [ObjHdl],ObjPtr

ObjLoop
		cmpw ParagNo,[ObjPtr]:#P_EndParag
		blt CkDraw
		cmpw StartLine,[ObjPtr]:#P_EndLine
		bge NextObject


CkDraw
		cmpw [ObjPtr]:#P_PageNo,P_Page
		bne NextObject

		tool _HLock,in=(ObjHdl:l)

		in  ObjPtr:l,ParagNo:w,StartLine:w,MaxLine:w,VertPos:w,#1:w
		out a:w
		xcall T_DrawLines

		tool _HUnlock,in=(ObjHdl:l)


NextObject
		movelong [ObjPtr]:#P_NThread,ObjHdl
		cpzl ObjHdl
		beq Exit

		movelong [ObjHdl],ObjPtr
		cmpw [ObjPtr]:#P_StartParag,ParagNo
		bne Exit

		moveword [ObjPtr]:#P_StartLine,StartLine
		stz VertPos
		brl ObjLoop


Exit
		RETURN
		ENDP




;-------------------------------------------------------------------------------
;
; _DrawLines (ObjPtr:l,ParagNo:w,StartLine:w,EndLine:w,StartVert:w
;			 OffScreen:w): EndVert:w
;
; Draws the part of the paragraph specified by StartLine and EndLine.
; EndLine is really one larger than the last Q_Line drawn.
; It doesn't draw across object boundaries.

T_DrawLines	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		INPUT  ObjPtr:l,ParagNo:w,StartLine:w,MaxLine:w
		INPUT  StartVert:w,OffScreen:w
		OUTPUT EndVert:w

		LOCAL ParagPtr:l,LinesHdl:l,LinesPtr:l,TextHdl:l,TextPtr:l
		LOCAL ParHeight:w,MaxWidth:w,CurLine:w
		LOCAL LeftPix:w,TopPix:w,MaxVert:w
		LOCAL BaseLine:w,Ascent:w,Descent:w,Flags:w

		BEGIN


		subword [ObjPtr]:#P_TRect+6,[ObjPtr]:#P_TRect+2,MaxWidth
		subword [ObjPtr]:#P_TRect+4,[ObjPtr]:#P_TRect,MaxVert

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_TextBlock,TextHdl
		moveword [ParagPtr]:#T_ParHeight,ParHeight

		rcall D_Deref,in=(TextHdl:ax),out=(TextPtr:ax)
		moveword [ParagPtr]:#T_ParOffset,a
		addwl a,TextPtr

		rcall T_LockRuler,in=(ParagPtr:ax)

		rcall T_LockLines,in=(ParagNo:a),out=(LinesHdl:ax)
		movelong [LinesHdl],LinesPtr

		lda StartLine
		sta CurLine
		jsl T_MulLine
		addwl a,LinesPtr


		call T_TrackFont,in=(TextPtr:l,[LinesPtr]:w)

		subword P_ContentRect+2,P_H,a
		addword a,[ObjPtr]:#P_TRect+2,LeftPix
		subword P_ContentRect,P_V,a
		addword a,[ObjPtr]:#P_TRect,TopPix



LineLoop
		stz Flags
		lda CurLine
		bne NotFirst
		lda Flags
		ora #T_FirstLine
		sta Flags
NotFirst

		inc CurLine
		cmpw CurLine,MaxLine
		blt DoLine
		jne Done

		lda Flags
		ora #T_LastLine
		sta Flags


DoLine
		moveword [LinesPtr]:#T_Ascent,a
		and #$ff
		sta Ascent
		moveword [LinesPtr]:#T_Descent,a
		and #$ff
		sta Descent

		rcall T_GetSpacing,in=(T_CurRulBits:a,Ascent:x,Descent:y)
		addword a,Ascent,a
		addword a,StartVert,StartVert
		sta BaseLine

		pushword LeftPix
		addword StartVert,TopPix,s
		_MoveTo

		addword StartVert,Descent,StartVert
		cmp MaxVert
		bge Done

		lda P_PageMode
		bne DrawOff
		lda OffScreen
		beq DrawOn

DrawOff
		in TextPtr:l,LinesPtr:l,Flags:w
		in [ObjPtr]:#P_TRect+4:l,[ObjPtr]:#P_TRect:l,BaseLine:w
		xcall T_DrawOSLine
		bra DrewIt

DrawOn
		in TextPtr:l,LinesPtr:l,MaxWidth:w,Flags:w
		xcall T_DrawLine

DrewIt	addwl #T_LineInfoSize,LinesPtr
		brl LineLoop



Done	moveword StartVert,EndVert
		call T_UnlockRuler
		tool _HUnlock,in=(LinesHdl:l)
		tool _HUnlock,in=(TextHdl:l)

		RETURN
		ENDP





;------------------------------------------------------------------------------;
;
; T_DrawLine (TextPtr:l,LinePtr:l,MaxWidth:w,Flags:w)
;

T_DrawLine	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu


		INPUT TextPtr:l,LinePtr:l,MaxWidth:w,Flags:w

		LOCAL Offset:w,Length:w,LineWidth:w,theChar:w
		LOCAL MaxOffset:w,StartSeg:w,EndSeg:w,LeftOffset:w
		LOCAL Spaces:w,TabStop:w,FontChanged:w
		LOCAL BaseChange:w,BaseOffset:w
		LOCAL MaxAscent:w,MaxDescent:w,Descent:w
		LOCAL NoIndent:w,Pt:l,LeftMarg:w,CurH:w,NewH:w
		LOCAL TempPtr:l,SpaceWidth:w

		BEGIN

		moveword [LinePtr]:#T_Offset,Offset
		moveword [LinePtr]:#T_Length,Length
		moveword [LinePtr]:#T_LineWidth,LineWidth
		addword Length,Offset,MaxOffset

		lda Flags
		and #T_FIRSTLINE
		eor #T_FIRSTLINE
		sta NoIndent

		in LineWidth:w,MaxWidth:w,NoIndent:w
		out LeftOffset:w
		xcall T_GetStart


		lda T_CurRulBits
		and #T_Full
		beq DrawIt
		lda Flags
		and #T_LastLine
		bne DrawIt

		in TextPtr:l,Offset:w,MaxOffset:w
		out TabStop:w,Spaces:w
		xcall T_CountSpaces

		lda TabStop
		bne TabOnLine
		lda Spaces				; Don't divide by 0
		beq TabOnLine
		spacelong
		subword MaxWidth,LineWidth,s
		pushword Spaces
		_FixRatio
		_SetSpaceExtra
TabOnLine

DrawIt
		rcall D_SelectFont,in=(T_CurFont:a,T_CurStyle:x,T_CurColor:y)
		stz FontChanged
		moveword Offset,StartSeg
		tool _GetPen,in=(!Pt:l)
		moveword Pt+2,LeftMarg
		tool _Move,in=(LeftOffset:w,#0:w)


CharLoop	cmpw Offset,MaxOffset
		jge EndLine

		moveword [TextPtr]:Offset,a
		inc Offset
		and #$ff
		sta theChar
		cmp #T_ColorChange+1
		blt SpecialChar

		cmp #TAB
		beq DoTab


; real characters

		lda FontChanged
		beq CharLoop

		rcall D_SelectFont,in=(T_CurFont:a,T_CurStyle:x,T_CurColor:y)
		stz FontChanged

		subword Offset,#1,StartSeg
		bra CharLoop



DoTab
		lda FontChanged
		bne IsDrawn
		subword Offset,#1,EndSeg
		jsr DrawSegment
IsDrawn

		tool _GetPen,in=(!Pt:l)
		subword Pt+2,LeftMarg,CurH

		in TextPtr:l,Offset:w,CurH:w,MaxWidth:w
		in T_CurFont:l,T_CurColor:w
		out a:w
		xcall T_UseTab
		bmi EndLine
		sta NewH

		subword NewH,CurH,s
		pushword #0
		_Move

		moveword Offset,StartSeg
		brl CharLoop




SpecialChar
		pha
		lda FontChanged
		bne DoJump

		subword Offset,#1,EndSeg
		jsr DrawSegment
		inc FontChanged

DoJump	pla
		asl a
		tax
		jmp (JumpTable,x)


FontChange	moveword [TextPtr]:Offset,T_CurFont
		inc Offset
		bra ChangeExit

StyleChange	movebyte [TextPtr]:Offset,T_CurStyle
		bra ChangeExit

SizeChange	movebyte [TextPtr]:Offset,T_CurSize
		bra ChangeExit

ColorChange	moveword [TextPtr]:Offset,a
		and #$ff
		sta T_CurColor

ChangeExit	inc Offset
		brl CharLoop



EndLine
		lda FontChanged
		bne IsDrawn2
		moveword Offset,EndSeg
		jsr DrawSegment
IsDrawn2

		lda T_CurRulBits
		and #T_FULL
		beq Exit
		tool _SetSpaceExtra,in=(#0:l)

Exit	RETURN


DrawSegment
		stz BaseChange

		lda T_CurStyle
;		and #SuperScript-SubScript
	  	and #SuperScript+SubScript
		beq Draw
;		eor #SuperScript-SubScript
		eor #SuperScript+SubScript
		beq Draw

		inc BaseChange
		stz BaseOffset
		lda T_CurStyle
		and #$ffff-SuperScript-SubScript
		tax
		rcall D_SelectFont,in=(T_CurFont:a,x:x,T_CurColor:y)

		lda T_CurStyle
		and #SuperScript
		beq DoSub

		moveword [LinePtr]:#T_Ascent,a
		and #$ff
		sta MaxAscent

		jsl D_GetStats
		subword a,MaxAscent,BaseOffset
		tool _Move,in=(#0:w,BaseOffset:w)
		bra Draw

DoSub
		moveword [LinePtr]:#T_Descent,a
		and #$ff
		sta MaxDescent

		jsl D_GetStats
		stx Descent
		subword MaxDescent,Descent,BaseOffset
		tool _Move,in=(#0:w,BaseOffset:w)


Draw
		SpaceWord
		pushword #SPACE
		_CharWidth
		pullword SpaceWidth
		
		lda StartSeg
		addlong a,TextPtr,TempPtr
		pushlong TempPtr
		subword EndSeg,StartSeg,y

		lda LeftOffSet
		clc
		adc LineWidth
		adc SpaceWidth
		cmp MaxWidth
		blt NoSpaceAtEnd
Dloop
		dey
		bmi OutOfBounds
		lda [TempPtr],y
		and #$FF
		cmp #SPACE                     ;is it a space?
		beq NoSpaceAtEnd
		
OutOfBounds		
		iny
NoSpaceAtEnd
		phy									;# of chars to draw
		call D_DrawText

		lda BaseChange
		beq No
		pushword #0
		subword #0,BaseOffset,s
		_Move
No

		rts


JumpTable	DC.W	CharLoop	; 0
	DC.W	FontChange	; 1
	DC.W	StyleChange	; 2
	DC.W	SizeChange	; 3
	DC.W	ColorChange	; 4

		ENDP





;------------------------------------------------------------------------------;
;
; T_DrawOSLine (TextPtr:l,LinePtr:l,Flags:w,TextRect:r,BaseLine:w)
;

T_DrawOSLine	PROC		EXPORT
			;Using P_Data
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

		INPUT TextPtr:l,LinePtr:l,Flags:w,TextRect:r,BaseLine:w
		LOCAL Ascent:w,Descent:w,MaxWidth:w,Port:l
		LOCAL ClipRect:r,ScaleRect:r,MoreLoc:r,LocInfo:r
		LOCAL VertPos:w,HorizPos:w

		BEGIN

		moveword #1,>D_BitMapChanged

		moveword [LinePtr]:#T_Ascent,a
		and #$ff
		sta Ascent
		moveword [LinePtr]:#T_Descent,a
		and #$ff
		sta Descent

		rcall T_GetSpacing,in=(T_CurRulBits:a,Ascent:x,Descent:y)
		addword a,Ascent,Ascent

		subword TextRect+6,TextRect+2,MaxWidth
		movelong P_CurrentWin,Port


		lda P_PageMode
		jne ScaleLine


; Adjust top,left and right of rectangle to local coordinates

		subword P_ContentRect,P_V,a
		addword a,TextRect,TextRect
		subword P_ContentRect+2,P_H,a
		addword a,TextRect+2,TextRect+2
		addword a,MaxWidth,TextRect+6


; Narrow in on the Q_Line of Q_Text

		addword TextRect,BaseLine,VertPos
		subword a,Ascent,TextRect
		addword VertPos,Descent,TextRect+4



; Adjust rectangle to global coordinates

		moveword TextRect+2,HorizPos
		tool _LocalToGlobal,in=(!TextRect:l)
		tool _LocalToGlobal,in=(!TextRect+4:l)
		call D_ClearBitMap,in=(!TextRect:l)

		tool _MoveTo,in=(HorizPos:w,VertPos:w)
		pushlong [Port]:#2			   ;D_Save BitMap Ptr
		movelong >D_BitMapPtr,[Port]:#2

		in TextPtr:l,LinePtr:l,MaxWidth:w,Flags:w
		xcall T_DrawLine

		pulllong [Port]:#2			   ;Restore BitMap Ptr


; Intersect the zap rectangle with the content Q_Rect in global coords.

		moverect P_ContentRect,ClipRect
		tool _LocalToGlobal,in=(!ClipRect:l)
		tool _LocalToGlobal,in=(!ClipRect+4:l)

		tool _SectRect,in=(!TextRect:l,!ClipRect:l,!TextRect:l),out=(a:w)
		beq NoZap

		call D_RectZap,in=(!TextRect:l)
NoZap	brl Exit


ScaleLine


; Narrow in on the Q_Line of Q_Text

		addword TextRect,BaseLine,VertPos
		subword a,Ascent,TextRect
		addword VertPos,Descent,TextRect+4

; Scale rectangle

		moverect TextRect,ScaleRect
		tool _MapRect,in=(!ScaleRect:l,#P_PageRect:l,#P_FullPageRect:l)

		subword TextRect+4,TextRect,TextRect+4
		subword TextRect+6,TextRect+2,TextRect+6
		stz TextRect
		stz TextRect+2

		call D_ClearBitMap,in=(#ScreenRect:l)

		tool _SetPort,in=(T_ScalePort:l)
		jsl D_KillFont
		tool _MoveTo,in=(#0:w,Ascent:w)

		in TextPtr:l,LinePtr:l,MaxWidth:w,Flags:w
		xcall T_DrawLine

		tool _SetPort,in=(Port:l)

		pushlong T_ScalePort			 ;Src LocInfo
		pushlong Port					;Dest LocInfo
		pushlong !TextRect			   ;Src Q_Rect
		pushlong !ScaleRect			  ;Dest Q_Rect
		pushword #NotBIC				 ;Mode
		pushlong #0
		_CopyPixels


Exit	RETURN

ScreenRect	DC.W	0,0,199,640

		ENDP





;------------------------------------------------------------------------------
;
; T_DrawOneLine (ParagNo:w,LineNo:w,ObjHdl:l,VertPos:w)
;

T_DrawOneLine	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_TextEqu
			;Using T_Data

		INPUT ParagNo:w,LineNo:w,ObjHdl:l,VertPos:w

		LOCAL ParagPtr:l,TextHdl:l,TextPtr:l
		LOCAL ObjPtr:l,LinesHdl:l,LinePtr:l
		LOCAL Flags:w,Ascent:w,Descent:w


		BEGIN

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		rcall T_LockRuler,in=(ax:ax)

		movelong [ParagPtr]:#T_TextBlock,TextHdl
		tool _HLock,in=(TextHdl:l)
		movelong [TextHdl],TextPtr
		moveword [ParagPtr]:#T_ParOffset,a
		addwl a,TextPtr

		rcall T_LockLines,in=(ParagNo:a),out=(LinesHdl:ax)
		movelong [LinesHdl],LinePtr
		rcall T_MulLine,in=(LineNo:a),out=(a:a)
		addwl a,LinePtr

		stz Flags
		moveword [ParagPtr]:#T_LineCount,a
		dec a
		cmp LineNo
		bne NotLast
		moveword #T_LastLine,Flags
NotLast	lda LineNo
		bne NotFirst
		lda Flags
		ora #T_FirstLine
		sta Flags
NotFirst

		moveword [LinePtr]:#T_Ascent,a
		and #$ff
		sta Ascent
		moveword [LinePtr]:#T_Descent,a
		and #$ff
		sta Descent

		rcall T_GetSpacing,in=(T_CurRulBits:a,Ascent:x,Descent:y)
		addword a,Ascent,a
		addword a,VertPos,VertPos

		call T_TrackFont,in=(TextPtr:l,[LinePtr]:w)

		movelong [ObjHdl],ObjPtr

		in TextPtr:l,LinePtr:l,Flags:w
		in [ObjPtr]:#P_TRect+4:l,[ObjPtr]:#P_TRect:l,VertPos:w
		xcall T_DrawOSLine

		call T_UnlockRuler
		tool _HUnlock,in=(TextHdl:l)
		tool _HUnlock,in=(LinesHdl:l)

		RETURN
		ENDP
		END

