* ============================================================================ *
*	RectFit.asm: constrain a rectangle to fit inside another one.
*
*			void RectFit(struct IBox *outer, struct IBox *inner,struct IBox *result);
*					   	 a0  				 a1 				a2
*
*	This function moves causes the size and position of the rectangle "inner"
*	to be constrained to fit into the rectangle "outer" and the resulting rectangle
*	is placed in "result" (which can be the same pointer as "inner")
*	Note that the Left and Top coords of the "outer" box are ignored, i.e. it
*	is assumed that both "inner" and "result" are relative to the origin of
*	"outer". (This would be the case when using RectFit to determine the size
*	of screens and windows).
* ============================================================================ *

			include		"exec/types.i"
			include		"intuition/intuition.i"
			include		"macros.i"

			SECTION		rectfit.asm,CODE

			xdef		_RectFit

_RectFit:					; (outer:a0, inner:a1, result:a2)

; constrain the width to be non-negative and not creater than outer width

			move.w		ibox_Width(a1),d0		; width of inner box
			bpl.s		1$						; if negative
			moveq		#0,d0					; then make it 0
1$			move.w		ibox_Width(a0),d1		; width of outer box
			cmp.w		d0,d1					; if (inner < outer)
			bhs.s		2$						; then it's ok
			move.w		d1,d0					; else clamp
2$			move.w		d0,ibox_Width(a2)		; save as result

; constrain the left edge of the box to be less than (outer-right - inner-width);
; The commented-out lines are if we ever want to change to absolute positioning.

			sub.w		d0,d1					; amount of width free
			move.w		ibox_Left(a1),d0		; d0 <-- inner left
;			sub.w		ibox_Left(a0),d0		; relative to outer box
			bpl.s		3$						; if positive, ok
			moveq		#0,d0					; otherwise, make it 0
3$			cmp.w		d0,d1					; don't go too far right
			bhs.s		4$						; otherwise
			move.w		d1,d0					; clip it
4$
;			add.w		ibox_Left(a0),d0		; relative to left edge
			move.w		d0,ibox_Left(a2)
			
; constrain the height to be non-negative and not creater than outer height

			move.w		ibox_Height(a1),d0		; height of inner box
			bpl.s		11$						; if negative
			moveq		#0,d0					; then make it 0
11$			move.w		ibox_Height(a0),d1		; height of outer box
			cmp.w		d0,d1					; if (inner < outer)
			bhs.s		12$						; then it's ok
			move.w		d1,d0					; else clamp
12$			move.w		d0,ibox_Height(a2)		; save as result

; constrain the top edge of the box to be less than (outer-bottom - inner-height);
; The commented-out lines are if we ever want to change to absolute positioning.

			sub.w		d0,d1					; amount of height free
			move.w		ibox_Top(a1),d0			; d0 <-- inner top
;			sub.w		ibox_Top(a0),d0			; relative to outer box
			bpl.s		13$						; if positive, ok
			moveq		#0,d0					; otherwise, make it 0
13$			cmp.w		d0,d1					; don't go too far down
			bhs.s		14$						; otherwise
			move.w		d1,d0					; clip it
14$
;			add.w		ibox_Top(a0),d0			; relative to bottom edge
			move.w		d0,ibox_Top(a2)
			move.l		a2,d0					; return address of box
			
			rts

			end
; original C source
void RectFit(struct IBox *outer, struct IBox *inner,struct IBox *result)
{
	result->Width		= clamp(0,inner->Width,outer->Width);
	result->Height		= clamp(0,inner->Height,outer->Height);
	result->Left		= clamp(0,inner->Left,outer->Width - result->Width);
	result->Top			= clamp(0,inner->Top,outer->Height - result->Height);
}
