/*
 * Generic c routine for Box Fitting 
 *
 * int boxFit( int *NW , int *NH, int AW, int AH , int BW, int BH );
 *
 * AW - Actual Width 
 * AH - Actual Height 
 * BW - Box Width 
 * BH - Box Height 
 * NW - New Width 
 * NH - New Height 
 *
 * Fits AW,AH into a box specified by BW,BH and returns the new 
 * width and height as NW,NH. The fitting is done preserving the
 * aspect ratio of AW,AH 
 *
 * 
 * On successfull fitting boxFit() returns 0 on failure -1 
 * 
 * If both BH,BW are <= 0 no fitting is done AW,AH is returned
 * as NW,NH
 *
 * If any of BW,BH  is <= 0  , then fitting is done only taking the 
 * non-zero value. So it does a  height/width-fit instead of box-fit .
 *
 * If both AW, AH is less than the BW,BH then its considered already 
 * fitted and AW,AH is returned as NW,NH
 *
 * If one of AW,AH is less than BW,BH then the fitting is done
 * with the other value of AW,AH which is greater than BW,BH 
 * 
 * If either or both of AW,AH is <= 0 the NW,NH will be returned 
 * as 0,0 and boxFit() will return -1 instead of 0 
 *
 *
 * kishan@hackorama.com  ( www.hackorama.com )  Circa 1999
 *
 */

#include <stdio.h>


int
boxFit( int *nw , int *nh, int aw, int ah , int bw, int bh )
{
	float scale_factor = 1.0;
	int temp_value  = 0;

	/*  check validity of aw,ah */
	if( ah <= 0 || aw <= 0 ){
		*nw = 0;
		*nh = 0;
		return -1;
	}

	/* no valid  box  no fitting will be done */
	if( bw <= 0 && bh <= 0 ){
		*nw = aw;
		*nh = ah;
	}else if ( ah < bh && aw < bw ){/* if box already fits */
		*nw = aw;
		*nh = ah;
	}else if ( bh <= 0 ) { /* if only valid width  */
		if( aw < bw ){ /* already fits */
			*nw = aw;
			*nh = ah;
		}else{
			scale_factor = (float) ( (float)aw / (float)bw );
			*nw = bw ;
			*nh = (int)  ( (float)ah / scale_factor ) ;		
		}
	}else if ( bw <= 0 ) { /* if only valid height */
		if( ah < bh ){ /* already fits */
			*nh = ah;
			*nw = aw;
		}else{
			scale_factor = (float) ( (float)ah / (float)bh );
			*nh = bh ;
			*nw = (int)  ( (float)aw / scale_factor ) ;		
		}
	}else { /* actual box fit */
		if( ah > bh ){ /* if height is to be scaled */
			scale_factor = (float) ( (float)ah / (float)bh );
			temp_value   = (int)   ( (float)aw / scale_factor );
			if( temp_value <= bw ){
				*nw = temp_value;
				*nh = bh;
			}else{
				scale_factor = (float) ( (float)aw / (float)bw );
				*nw = bw;
				*nh = (int)  ( (float)ah / scale_factor ) ;
			}
		}else if( aw > bw ){ /* height need not be scaled only width */
			scale_factor = (float) ( (float)aw / (float)bw );
			*nh = (int)  ( (float)ah / scale_factor ) ;
			*nw = bw;
		}else{
			fprintf( stderr, "\nTHIS SHOULD HAVE BEEN HANDLED ALREADY\n" );
			return -1 ;
		}

		/* make sure the fitting worked */
		if( *nh > bh || *nw > bw ){
			fprintf( stderr, "\nFAILED FITTING, THIS SHOULD NOT HAPPEN\n" );
			return -1 ;
		}
	}	
	
	/* if the scaled values are too small set it to  1 */
	if( *nh == 0 ) *nh = 1;
	if( *nw == 0 ) *nw = 1;
	
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9