home *** CD-ROM | disk | FTP | other *** search
- * ============================================================================ *
- * 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);
- }
-