File: programming/cocoa/UKDistributedView.zip/UliKit/NSImage NiceScaling.m


/* =============================================================================
    PROJECT:    Filie
    FILE:       NSImage+NiceScaling.h
    
    COPYRIGHT:  (c) 2003 by M. Uli Kusterer, all rights reserved.
    
    AUTHORS:    M. Uli Kusterer - UK
    
    LICENSES:   GNU GPL, Modified BSD
    
    REVISIONS:
        2003-12-19  UK  Created.
   ========================================================================== */
 
// -----------------------------------------------------------------------------
//  Headers:
// -----------------------------------------------------------------------------
 
#import "NSImage+NiceScaling.h"
 
 
@implementation NSImage (NiceScaling)
 
-(NSImage*) scaledImageToFitSize: (NSSize)fitIn
{
	return [self scaledImageToFitSize: fitIn withInterpolation: NSImageInterpolationHigh];
}
 
 
-(NSImage*) scaledImageToFitSize: (NSSize)fitIn withInterpolation: (NSImageInterpolation)inter
{
	return [self scaledImageToFitSize: fitIn withInterpolation: inter andBox: NO];
}
 
-(NSImage*) scaledImageToFitSize: (NSSize)fitIn withInterpolation: (NSImageInterpolation)inter andBox: (BOOL)doBox
{
	NSSize		size = [self scaledSizeToFitSize: fitIn];
	NSImage*	img = [[[NSImage alloc] initWithSize: fitIn] autorelease];
	NSRect		srcBox = { { 0, 0 }, { 0, 0 } },
				dstBox = { { 0, 0 }, { 0, 0 } };
	
	dstBox.size = size;
	srcBox.size = [self size];
	dstBox.origin.x += (fitIn.width -size.width) /2;
	dstBox.origin.y += (fitIn.height -size.height) /2;
	
	NS_DURING
		[img lockFocus];
			if( doBox )
			{
				[[NSColor whiteColor] set];
				[NSBezierPath fillRect: dstBox];
				[[NSColor blackColor] set];
			}
			[[NSGraphicsContext currentContext] setImageInterpolation: inter];
			[self drawInRect: dstBox fromRect: srcBox operation:NSCompositeSourceOver fraction:1.0];
			if( doBox )
				[NSBezierPath strokeRect: dstBox];
		[img unlockFocus];
		
		NS_VALUERETURN( img, NSImage* );
	NS_HANDLER
		NSLog(@"Couldn't scale image %@",localException);
	NS_ENDHANDLER
	
	return nil;
}
 
 
-(NSImage*) scaledImageToCoverSize: (NSSize)fitIn
{
	return [self scaledImageToCoverSize: fitIn withInterpolation: NSImageInterpolationHigh];
}
 
 
-(NSImage*) scaledImageToCoverSize: (NSSize)fitIn withInterpolation: (NSImageInterpolation)inter
{
	return [self scaledImageToCoverSize: fitIn withInterpolation: inter andBox: NO];
}
 
-(NSImage*) scaledImageToCoverSize: (NSSize)fitIn withInterpolation: (NSImageInterpolation)inter andBox: (BOOL)doBox
{
	return [self scaledImageToCoverSize: fitIn withInterpolation: inter andBox: doBox align: NSImageAlignCenter];
}
 
-(NSImage*) scaledImageToCoverSize: (NSSize)fitIn withInterpolation: (NSImageInterpolation)inter
						andBox: (BOOL)doBox align: (NSImageAlignment)align
{
	NSSize		size = [self scaledSizeToCoverSize: fitIn];
	NSImage*	img = [[[NSImage alloc] initWithSize: fitIn] autorelease];
	NSRect		srcBox = { { 0, 0 }, { 0, 0 } },
				dstBox = { { 0, 0 }, { 0, 0 } },
				clipBox = { { 0, 0 }, { 0, 0 } };
	
	dstBox.size = size;
	srcBox.size = [self size];
	clipBox.size = fitIn;
	
	// Center it:
	switch( align )
	{
		case NSImageAlignCenter:		// Center h and v.
			dstBox.origin.x -= (dstBox.size.width - clipBox.size.width) /2;
			dstBox.origin.y -= (dstBox.size.height - clipBox.size.height) /2;
			break;
		
		case NSImageAlignTop:			// Center h, v at top.
			dstBox.origin.x -= (dstBox.size.width - clipBox.size.width) /2;
			dstBox.origin.y -= dstBox.size.height - clipBox.size.height;
			break;
		
		case NSImageAlignTopLeft:		// h at left, v at top.
			dstBox.origin.y -= dstBox.size.height - clipBox.size.height;
			break;
		
		case NSImageAlignLeft:			// h at left, center v.
			dstBox.origin.y -= (dstBox.size.height - clipBox.size.height) /2;
			break;
		
		case NSImageAlignBottomLeft:	// h at left, v at bottom
		default:
			break;
		
		case NSImageAlignBottom:		// center h, v at bottom.
			dstBox.origin.x -= (dstBox.size.width - clipBox.size.width) /2;
			break;
		
		case NSImageAlignBottomRight:   // h at right, v at bottom.
			dstBox.origin.x -= dstBox.size.width - clipBox.size.width;
			break;
		
		case NSImageAlignRight:			// h at right, center v.
			dstBox.origin.x -= dstBox.size.width - clipBox.size.width;
			dstBox.origin.y -= (dstBox.size.height - clipBox.size.height) /2;
			break;
		
		case NSImageAlignTopRight:		// h at right, v at top.
			dstBox.origin.y -= dstBox.size.height - clipBox.size.height;
			dstBox.origin.x -= dstBox.size.width - clipBox.size.width;
			break;
		
	}
	
	NS_DURING
		[img lockFocus];
			[NSBezierPath clipRect: clipBox];
			[[NSGraphicsContext currentContext] setImageInterpolation: inter];
			[self drawInRect: dstBox fromRect: srcBox operation:NSCompositeSourceOver fraction:1.0];
			if( doBox )
			{
				[[NSColor blackColor] set];
				[NSBezierPath strokeRect: clipBox];
			}
		[img unlockFocus];
		
		NS_VALUERETURN( img, NSImage* );
	NS_HANDLER
		NSLog(@"Couldn't scale image %@",localException);
	NS_ENDHANDLER
	
	return nil;
}
 
 
-(NSSize)   scaledSizeToFitSize: (NSSize)size
{
	return [[self class] scaledSize: [self size] toFitSize: size];
}
 
 
+(NSSize)   scaledSize: (NSSize)imgSize toFitSize: (NSSize)size
{ 
	NSSize  finalSize = imgSize;
	float   ratio = imgSize.height / imgSize.width;
 
	//if( imgSize.width > size.width || imgSize.height > size.height )
	{
		finalSize.width = size.width;
        if( imgSize.height == imgSize.width )
            finalSize.height = finalSize.width;
        else
            finalSize.height = size.height * ratio;
		
		if( finalSize.height > size.height )
		{
			ratio = imgSize.width / imgSize.height;
			finalSize.height = size.height;
            if( imgSize.height == imgSize.width )
                finalSize.width = finalSize.height;
            else
                finalSize.width = size.width * ratio;
		}
	}
	
	return( finalSize ); 
}
 
 
-(NSSize)   scaledSizeToCoverSize: (NSSize)size 
{
	return [[self class] scaledSize: [self size] toCoverSize: size];
}
 
 
+(NSSize)   scaledSize: (NSSize)imgSize toCoverSize: (NSSize)size
{ 
	NSSize  finalSize = imgSize;
	float   ratio = imgSize.height / imgSize.width;
	
	/*if( imgSize.width == size.width
		&& imgSize.height == size.height )
		return imgSize;*/
	
	finalSize.width = size.width;
	finalSize.height = finalSize.width * ratio;
	
	if( finalSize.height < size.height )
	{
		ratio = imgSize.width / imgSize.height;
		finalSize.height = size.height;
		finalSize.width = finalSize.height * ratio;
	}
	
	return( finalSize ); 
} 
 
 
@end

This code uses the PclZip Zip File reading code, which is subject to the GNU LGPL. It also uses the GeSHi syntax highlighter, subject to the GPL. Ask if you want this for your own web site, it's free.