/*----------------------------------------------------------------------------------------------

Hit ctrl-enter to execute.

Description:

	This script will scale all of the annotations on an image by a requested factor.
	It will keep the center of all of the annotations put together constant.

	Copyright 1995, Gatan Inc.
	Written by Chris Meyer
	Annotated by Paul Thomas March 2001

-----------------------------------------------------------------------------------------------*/


/* 	This method cycles through the annotations in the input image and returns the annotation bounds 
	extrema values in the passed parameters (hence the use of '&', allowing the passed parameters 
	to be modified).*/

void CalculateAnnotationExtent( Image image, number &xTop, number &xLeft, number &xBottom, number &xRight )
{	
	// Get the size of the input image 
	number width, height
	Get2dSize( image, width, height )						

	// Count the number of annotations present
	number annotCount = CountAnnotations( image )				
	
	// Begin with the most extreme values for each bounding side variable
	xTop = height												
	xLeft = width
	xBottom = 0
	xRight = 0


	// Loop through each annotation in the image
	number index
	for ( index=0; index<annotCount; index++ )					
	{	
		// Get the annotation ID number for the n'th (or index'th) annotation 	
		number annotID = GetNthAnnotationID( image, index )		
	
		number top, left, bottom, right							
	
		// Get the bounding co-ordinates of the n'th annotation
		GetAnnotationRect( image, annotID, top, left, bottom, right )		
		
		// Now check to see if the top value for the annoation is top-most in comparison with xtop, etc.
		// If so, copy the new values
		if ( top < xTop ) xTop = top							
		if ( left < xLeft ) xLeft = left						
		if ( bottom > xBottom ) xBottom = bottom
		if ( right > xRight ) xRight = right
	}
}


/*	This method recales all the annotations in the given image around the given origin by the given
	percentage.  It is called with the image of interest, the specified origin and the scaling factor. 
	It returns nothing. */

void RescaleAnnotations( Image image, number originX, number originY, number scale )
{
	// Get the height and width of the input image
	number width, height
	Get2dSize( image, width, height )						

	// Count the number of annotations
	number annotCount = image.CountAnnotations(  )			 

	// Loop through the annotations
	number index
	for ( index=0; index<annotCount; index++ )				
	{	
		// Get the annotaion ID for the n'th annotation in the loop index
		number annotID = image.GetNthAnnotationID( index )	
	
		// Get the bounding co-ordinates of the n'th annotation 
		number top, left, bottom, right
		GetAnnotationRect( image, annotID, top, left, bottom, right )		
		
		// Scale the bounding co-ordinates and offset by the appropriate amount wrt the origin
		top = originY - ( originY - top ) * scale			
		bottom = ( bottom - originY ) * scale + originY
		left = originX - ( originX - left ) * scale
		right = ( right - originX ) * scale + originX
		
		// Set the new annotation bounding co-ordinate values
		SetAnnotationRect( image, annotID, top, left, bottom, right )		
	}
}


/* This part of the script executes the example, calling on the two above methods where required */

// Get the front image
Image image := GetFrontImage()								
	
// Call the CalculateAnnotationExtent function to establish the extreme annotation bounds
number top, left, bottom, right
CalculateAnnotationExtent( image, top, left, bottom, right )		

// Request the scaling constant, and clip to ensure it is a sensible value
number rescale
if (!GetNumber("Enter annotation rescaling constant (0.1 - 5.0)", 1.0, rescale))
	exit(0)
Clip(rescale, 0.1, 5.)	
								 
// Post the bounding co-ordinates extent to the results window
Result( "Extent: " + top + "," + left + "," + bottom + ", " + right + "\n" )		

// Call the RescaleAnnotation method, using the centre co-ordinates of the annotation bounding rectangle as the origin 
RescaleAnnotations( image, ( right + left ) / 2, ( top + bottom ) / 2, rescale )		

