COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

	Copyright (c) GeoWorks 1989 -- All Rights Reserved

PROJECT:	PC GEOS
MODULE:		
FILE:		text.def

AUTHOR:		John Wedgwood, Nov  3, 1989

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	11/ 3/89	Initial revision


DESCRIPTION:
	Includes stuff that is needed for text object calculations that are
	shared between the kernel and application/ui.
		
	$Id: text.def,v 1.1 97/04/04 14:22:40 newdeal Exp $

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

SetDef	__TEXT

include fontID.def
include graphics.def
include char.def

StartKernel

global GrTextObjCalc:far
global GrTextPosition:far
global GrSetTextDrawOffset:far

;
; Structure to pass to GrTextObjCalc.
;
TOCFlags	record
    TOCF_NO_WORD_WRAP:1		; PASS: Set - word-wrap should be done
    TOCF_AUTO_HYPHENATE:1	; PASS: Set - attempt auto hyphenation

    TOCF_FOUND_ANCHOR:1		; RET:  Set - an anchor character was found
    TOCF_IS_HARD_HYPHEN:1	; RET:  Set - break is a hard or opt hyphen
    TOCF_FOUND_BREAK:1		; RET:  Set - an auto-hyphen position was found
    TOCF_LINE_TERMINATED:1	; RET:  Set - last field on line
    TOCF_ONE_TAB_TOO_LARGE:1	; RET:  Set - tab couldn't be handled
    TOCF_OPT_HYPHEN_TOO_WIDE:1	; RET:  Set - optional hyphen too wide to fit
TOCFlags	end

;
; Other flags.
;
TOCOtherFlags	record
    TOCOF_IS_FIRST_FIELD:1	; PASS: Set - This is the first field on the line
    TOCOF_PREV_CHAR_KERNED:1	; HACK added by jim 4/27/92 so kernel will make
    TOCOF_LAST_BREAK_KERNED:1	; HACK added by jim 4/27/92 so kernel will make
    TOCOF_WRAP_AFTER_OVERFLOW:1	; PASS: Set - wrap after text overflows width
    TOCOF_WAIT_FOR_WORD:1	; INT: used internally, do not set
    TOCOF_FOUND_WORD:1		; INT: used internally, do not set
    TOCOF_FIRST_CHAR_OVERFLOW:1	; INT: used internally, do not set
    :1
TOCOtherFlags	end

;
; An array of line structures is kept (one for every line of text).
; For updates we need to know if a line has changed (so we can redraw it).
; For calculations we need to know if a line is the start of a paragraph (so
; we can apply the paragraph margin).
;
LineFlags	record
    LF_STARTS_PARAGRAPH:1	; Set if line starts a paragraph
    LF_ENDS_PARAGRAPH:1		; Set if line ends a paragraph
    
    LF_ENDS_IN_CR:1		; Set if field ends in CR.
    LF_ENDS_IN_COLUMN_BREAK:1	; Set if line ends in a column break
    LF_ENDS_IN_SECTION_BREAK:1	; Set if line ends in a section break
    LF_ENDS_IN_NULL:1		; Set if line ends in NULL, last one in document
    
    LF_NEEDS_DRAW:1		; Set if line needs redrawing
    LF_NEEDS_CALC:1		; Set if line needs calculating
    
    LF_ENDS_IN_AUTO_HYPHEN:1	; Set if line ends in a generated hyphen
    LF_ENDS_IN_OPTIONAL_HYPHEN:1 ; Set if line ends in an optional hyphen
    
    ;
    ; Sometimes characters in a line will extend outside the top and bottom
    ; bounds of the line. We mark these lines with these bits. 
    ;
    LF_INTERACTS_ABOVE:1	; Set if line interacts with line above it
    LF_INTERACTS_BELOW:1	; Set if line interacts with line below it

    ;
    ; When doing an optimized redraw of a line we draw the last field in the
    ; line if the field got longer. If the field got shorter we just clear
    ; from beyond the right edge of the field. There are a few situations
    ; where we can't really do this:
    ;	- Current last character on line extended to the right of its font
    ;	  box. (Italic characters are a good example of this).
    ;	- The last character on the line was negatively kerned before we
    ;	  made the modification and is that is no longer the case (this
    ;	  character was removed).
    ; We flag these two cases separately.
    ;
    LF_LAST_CHAR_EXTENDS_RIGHT:1 ; Set if the last character on the line extends
				;  to the right of its font box.
    
    LF_LAST_CHAR_KERNED:1	; Set if the last character on the line is 
				; kerned. The only time we use this is to copy
				; it into the next field...
    
    ;
    ; Set by the application if the line contains styles which are not supported
    ; directly by the kernel. This allows applications to optimize line redraw
    ; by skipping over code which may attempt to draw attributes which don't
    ; exist for the line.
    ;
    LF_CONTAINS_EXTENDED_STYLE:1 ; Set if the line contains a non-kernel
				;  supported style.
    
    :1
LineFlags	end

;----------------------------------------------------------
;
; A line is made up of a sequence of 'fields'. A field is a range of text
; bounded on either side by a margin, or a tab character.
;
;	Structure of a tab
;

TabLeader	etype byte
TL_NONE		enum TabLeader
TL_DOT		enum TabLeader
TL_LINE		enum TabLeader
TL_BULLET	enum TabLeader

TabType etype byte
TT_LEFT		enum TabType
TT_CENTER	enum TabType
TT_RIGHT	enum TabType
TT_ANCHORED	enum TabType

TabAttributes	record
    :3
    TA_LEADER		TabLeader:3
    TA_TYPE		TabType:2
TabAttributes	end

;
;	Structure of a tab
;
Tab	struct
    T_position		word		; Position of tab (pixels * 8)
    T_attr		TabAttributes	; Tab attributes.
    T_grayScreen	SysDrawMask	; Gray screen for tab lines
    T_lineWidth		byte		; Width of line before (after) tab
					; 0 = none, units are pixels * 8
    T_lineSpacing	byte		; Space between tab and line
					; 0 = none, units are pixels * 8
    T_anchor		word		; Anchor character.
Tab	ends

;----------------------------------------------------------

TabReferenceType	etype	byte
TRT_RULER	enum	TabReferenceType	; Reference is into the ruler.
TRT_OTHER	enum	TabReferenceType	;

TabReference	record
    TR_TYPE	TabReferenceType:1	; Type of reference.
    TR_REF_NUMBER:7			; Reference number
TabReference	end

;
; Reference number that means no tab, use left edge of line.
; MUST BE 0x7f (-1 in 7 binary digits).
;
RULER_TAB_TO_LINE_LEFT		=	0x7f

;
; Reference number that means use the left margin value.
;
RULER_TAB_TO_LEFT_MARGIN	=	0x7e

;
; Reference number that means use the para margin value.
;
RULER_TAB_TO_PARA_MARGIN	=	0x7d

;
; Reference number that means tab has an intrinsic width and is not associated
; with any tabstop.
;
OTHER_INTRINSIC_TAB		=	0x7f

;
; Reference number that means that the tab is zero width. This is a special
; case that is reserved for really horrible situations.
;
OTHER_ZERO_WIDTH_TAB		=	0x7e

;
; A line is made up of a list of fields...
;
FieldInfo	struct
    FI_nChars		word		; Number of characters in the field
    FI_position		word		; X position of field on line
    FI_width		word		; Width of the field

    FI_tab		TabReference	; Reference to a tab in the ruler
FieldInfo	ends

;
; A line...
;
LineInfo	struct
    LI_flags		LineFlags	; Misc flags
    LI_hgt		WBFixed		; Height of line
    LI_blo		WBFixed		; Baseline offset
    LI_adjustment	word		; Adjustment for justification
    LI_count		WordAndAHalf	; Number of characters in the line
					; This is the total of the field counts
    LI_spacePad		WBFixed		; Amount to pad last field to get
					;    full justification
    LI_lineEnd		word		; The rounded end-of-line position
					;    which indicates the end of the
					;    last non-white-space character
    LI_firstField	FieldInfo	; Contains the always present 1st field
LineInfo	ends
	;
	; There are more fields after this...
	;

;
; Substructure for a style run. This is included at the beginning of
; TOC_vars and GTP_vars, so they can use common calculation routines.
; DO NOT REARRANGE THEM, UNDER PAIN OF DEATH!
;   TMS_styleCallBack - must be at start
;
TMSFlags record
    TMSF_IS_BREAK_CHARACTER:1	;TRUE: Last char was a break character.
    TMSF_IS_OPTIONAL_HYPHEN:1	;TRUE: Break is an optional hyphen.
    TMSF_PAD_SPACES:1		;TRUE: AddWidth should pad spaces.
    TMSF_UPDATE_SIZE_ONLY:1	;TRUE: AddWidth only updates size.

    TMSF_OPT_HYPHENS:1		;TRUE: deal with optional hyphens.
    TMSF_NEGATIVE_KERNING:1	;TRUE: last char on line was negatively kerned.
    TMSF_EXTENDS_ABOVE:1	;TRUE: last char on line has tall accent.
    TMSF_EXTENDS_BELOW:1	;TRUE: last char on line has large descender.

    TMSF_STYLE_CHANGED:1	;TRUE: style changed, update line height.
    TMSF_NOWRAP:1               ;TRUE: style run isn't allowed to break.
    :6				;Yes, I want an entire word...
TMSFlags end

TextMetricStyles struct
    TMS_styleCallBack	fptr.far	;style callback routine
	;		(can be vfptr for XIP'ed geodes)
	;
	;	PASS:		ss:bx	= TOC_vars
	;			di	= Offset into the field
	;			ds	= Segment address of old text pointer
	;	RETURN:		TMS_textAttr set
	;			ds:si	= Pointer to the text
	;			cx	= Number of characters in this style
	;	DESTROYED:	nothing
	;
    TMS_graphicCallBack	fptr.far	;graphic callback routine
	;		(can be vfptr for XIP'ed geodes)
	;
	;	PASS:		ss:bx	= LICL_vars
	;			di	= Offset into the field
	;			ds	= Segment address of text pointer
	;	RETURN:		cx	= Height of the graphic of graphic
	;					at current position
	;			dx	= Width of the graphic
	;	DESTROYED:	nothing
	;
    TMS_fieldStart	dword		;offset to the start of the field
    TMS_sizeSoFar	WBFixed		;accumulated size
    TMS_lastCharWidth	WBFixed		;width of last char
    TMS_textAttr	TextAttr	;text attributess
    TMS_fontHandle	hptr.FontBuf	;current font handle
    TMS_trackKernValue	BBFixed		;scaled track kerning
    TMS_flags		TMSFlags	;special flags
    TMS_gstateHandle	hptr.GState	;handle to gstate in use
    TMS_gstateSegment	word		;GState segment address
    TMS_styleHeight	WBFixed		;Used only by GrTextObjCalc()
    TMS_styleBaseline	WBFixed		;   but they need to be here.
if DBCS_PCGEOS
    TMS_kernChar	Chars		;character for kerning
    TMS_textMiscMode	TextMiscModeFlags	;character or space padding?
endif
TextMetricStyles ends

;-----------------------------------------------------------------------------
;			    GrTextObjCalc
;-----------------------------------------------------------------------------

;
; TOC_int -
;	This structure contains the fields which are internal to GrTextObjCalc.
; All fields are initialized and used inside GrTextObjCalc.
;
; WARNING:
;   Do not move TOCI_style, or put TOC_ext before TOC_int. GrTextObjCalc and
;   GrTextPosition use common calculation routines that expect the
;   TextMetricStyles structure to be the first thing in the stack frame.
;
TOC_int	struct
    TOCI_style		TextMetricStyles
    TOCI_currentHgt	WBFixed		; Height of the field
    TOCI_currentBlo	WBFixed		; Baseline of the field

    TOCI_lastWordStart	word		; Position in text of last word start.
    TOCI_lastWordPos	WBFixed		; Position of last word start.
    TOCI_lastWordEndPos	word		; Position of last word end.

    TOCI_lastHyphen	word		; Position of last usable hyphen.
    TOCI_lastHyphenPos	WBFixed		; Position of last soft/hard hyphen.

    TOCI_tallCharHeightPos word		; Position of tall character with an
					;   important height value.
    TOCI_tallCharHeight	WBFixed		; Height of tall char.

    TOCI_tallCharBaselinePos word	; Position of tall character with an
					;   important baseline value.
    TOCI_tallCharBaseline WBFixed	; Baseline of tall char.

    TOCI_suggestedHyphen word		; Position of suggested hyphen in text
    TOCI_suggestedHyphenPos WBFixed	; Position of suggested hyphen on line

    TOCI_lastMetricFlags       TMSFlags ; Flags for last character
    align	word
TOC_int	ends

;
; TOC_ext -
;	This structure contains some fields which are passed to GrTextObjCalc
; by the application along with some fields which are returned.
;
TOC_ext	struct
    ;
    ; areaToFill - PASSED
    ;	This is the width of the area we are trying to fit the field to.
    ;
    TOCE_areaToFill	sword
    
    ;
    ; hyphenCallback - PASSED
    ;	A routine to call to do automatic hyphenation. Here's how that routine
    ; should be defined:
    ;	Pass:	ss:bp	= pointer to TOC_vars structure on stack.
    ;		di	= Offset to the place where we would split the word
    ;		TOCI_lastWordStart -
    ;			Offset in the text where the word to break starts
    ;		TOCI_lastWordPos -
    ;			Position (distance from left edge of the field) where
    ;			the word to break starts
    ;
    ;	Return:	TOCI_suggestedHyphen -
    ;			The offset to break the word at. Zero to break at the
    ;			start of the word.
    ;		TOCI_suggestedHyphenPos -
    ;			The position (distance from left edge of the field)
    ;			where the hyphen starts.
    ;		TOCE_hyphenWidth -
    ;			Width of the hyphen that was placed at the end of
    ;			the line.
    ;
    ;	Destroyed: nothing
    ;
    TOCE_hyphenCallback	dword		; can be vfptr for XIP'ed geodes
    
    ;
    ; tabCallback - PASSED
    ;	A routine to call when a TAB character is encountered.
    ;		PASS:		ds:si	= pointer to text
    ;				ss:bp	= TOC_vars
    ;				ss:bx	= LICL_vars
    ;		RETURN:		carry set if there is no tabstop within the
    ;					margins.
    ;				TOCE_areaToFill set correctly.
    ;		DESTROYED:	nothing
    ;
    TOCE_tabCallback	dword		; can be vfptr for XIP'ed geodes
    
    ;
    ; heightCallback - PASSED
    ;	A routine to call when the line-height changes.
    ;	Passed:
    ;		ss:bp	= TOC_vars
    ;		ax.bl	= Line height for new characters (WBFixed)
    ;	Return:
    ;		nothing
    ;	Destroyed:
    ;		nothing
    ;
    TOCE_heightCallback	dword		; can be vfptr for XIP'ed geodes
    
    ;
    ; passBack - PASSED
    ;	This is intended to allow applications to pass a word of data in this
    ; stack frame to their callbacks.
    ;
    TOCE_passBack	word
    
    ;
    ; anchorChar - PASSED
    ;	The anchor character to look for if the current field is associated
    ; with an anchored tab-stop.
    ;
    TOCE_anchorChar	word

    ;
    ; flags - PASSED / RETURNED
    ;	These flags are both passed and returned. See the documentation for
    ; TOCFlags for more information.
    ;
    TOCE_flags		TOCFlags	; Misc passed and returned flags
    
    ;
    ; lineHeight - PASSED / RETURNED
    ;	The "current" value of the line height should be passed in. If a line
    ; would grow taller as a result of adding the new field to it then this
    ; value is changed to reflect the new height. 
    ;
    TOCE_lineHeight	WBFixed

    ;
    ; lineBLO - PASSED / RETURNED
    ;	The "current" value of the lines baseline-offset. A line height is
    ; determined by its ascent and descent. To compute these values we need
    ; the baseline around.
    ;
    TOCE_lineBLO	WBFixed
    
    ;
    ; lineFlags - PASSED / RETURNED
    ;	The flags for the current line based on the previous calculations
    ; and the current calculations.
    ;
    TOCE_lineFlags	LineFlags
    
    ;
    ; optFlags - RETURNED
    ;	Flags which exist so that the caller can decide whether an optimized
    ; redraw is possible after a text change.
    ;
    TOCE_otherFlags	TOCOtherFlags
    
    ;
    ; nSpaces - RETURNED
    ;	Number of spaces in the line which can be padded for full justification.
    ;
    TOCE_nSpaces	sword

    ;
    ; nExtraSpaces - RETURNED
    ;	The number of spaces after the word-break. These spaces are on the
    ; line but shouldn't be considered for full justification.
    ;
    TOCE_nExtraSpaces	sword

    ;
    ; widthToAnchor - RETURNED
    ;	The amount of the field which falls before the anchor character.
    ;
    TOCE_widthToAnchor	sword

    ;
    ; nChars - RETURNED
    ;	The number of characters in the field which fit in the area.
    ;
    TOCE_nChars		sword

    ;
    ; break - RETURNED
    ;	The position of the break in the text.
    ;
    TOCE_break		sword
    
    ;
    ; hyphenWidth - RETURNED
    ;	The width of the generated hyphen at the end of the line.
    ;
    TOCE_hyphenWidth	WBFixed
    
    ;
    ; fieldWidth - RETURNED
    ;	The width of the field up to the word-break.
    ;
    TOCE_fieldWidth	WBFixed
    
    ;
    ; justWidth - RETURNED
    ;	The amount of the field which should be considered for justification.
    ; Doesn't include the spaces at the end of the line.
    ;
    TOCE_justWidth	sword

    ;
    ; wrapAfterOverflowWidth
    ;   Maximum width when using TOCOF_WRAP_AFTER_OVERFLOW.
    ;
    TOCE_wrapAfterOverflowWidth	word
TOC_ext	ends

;
; This is the structure that is passed to GrTextObjCalc.
;
TOC_vars	struct
    TOCV_int	TOC_int			; Internal variables
    TOCV_ext	TOC_ext			; Passed/Returned parameters
	align	word
TOC_vars	ends

;-----------------------------------------------------------------------------
;			    GrTextPosition
;-----------------------------------------------------------------------------

;
; Structure passed to GrTextPosition.
;   Do not move GTPL_style, as GrTextPosition and GrTextObjCalc use
;   common calculation routines which expect TextMetricStyles to be
;   at the start of the stack frame.
;
GTP_vars	struct
    GTPL_style		TextMetricStyles
    GTPL_object		dword		; Object segment address.

    GTPL_startPosition	word		; Passed position into string
    GTPL_charCount	word		; Start offset in string
	align	word
GTP_vars	ends

;-----------------------------------------------------------------------------
;			   GrDrawTextField
;-----------------------------------------------------------------------------

HyphenFlags	record
	HF_AUTO_HYPHEN:1		; set when auto-hyphen exists at EOL
HyphenFlags	end

;
; This part of the structure is saved as part of a graphics string
;
GDF_saved	struct
    GDFS_nChars		word		; Number of characters to draw
    GDFS_drawPos	PointWBFixed	; X/Y position to draw at
    GDFS_baseline	WBFixed		; Baseline for text
    GDFS_limit		word		; Limit for underline or strike-through
    GDFS_flags		HyphenFlags
	align	word
GDF_saved	ends

;
; This is the structure passed to GrDrawTextField
;
GDF_vars	struct
    GDFV_saved		GDF_saved	; Stuff to save for graphics-strings
    GDFV_styleCallback	fptr.far	; Callback routine for style changes
	;				; (must be vfptr for XIP'ed geodes)
	;
	;	PASS:		ss:bp	= GDF_vars
	;			bx:di	= TextAttr buffer to fill in
	;			si	= Offset into the field
	;			cx	= 0 if this is the first call
	;	RETURN:		Buffer pointed at by bx:di filled in
	;			cx	= Number of characters in this run
	;			ds:si	= Pointer to the text at offset si
	;					in the field
	;	DESTROYED:	nothing
	;
    GDFV_textOffset	dword		; Offset to text to draw
    GDFV_other		dword		; Application specific data
    GDFV_textPointer	dword		; Current text pointer (set by callback)
	align	word
GDF_vars	ends

EndKernel
