Image cache tidyup

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5345 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-12-01 13:49:47 +00:00
parent f2bcb34b09
commit 804630d3ae
3 changed files with 277 additions and 306 deletions

View file

@ -739,7 +739,7 @@ static NSColor *shadowCol;
case NSNullCellType: case NSNullCellType:
break; break;
} }
[controlView unlockFocus]; [controlView unlockFocus];
} }
- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView - (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView

View file

@ -94,12 +94,9 @@ static NSString* NSImage_PATH = @"Images";
- (void) dealloc - (void) dealloc
{ {
if (fileName) TEST_RELEASE(fileName);
[fileName release]; TEST_RELEASE(rep);
if (rep) TEST_RELEASE(bg);
[rep release];
if (bg)
[bg release];
NSDeallocateObject(self); NSDeallocateObject(self);
} }
@end @end
@ -134,15 +131,20 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (BOOL) loadFromData: (NSData *)data; - (BOOL) loadFromData: (NSData *)data;
- (BOOL) loadFromFile: (NSString *)fileName; - (BOOL) loadFromFile: (NSString *)fileName;
- (NSImageRep *) lastRepresentation; - (NSImageRep *) lastRepresentation;
- (NSImageRep*) cacheForRep: (NSImageRep*)rep
onDevice: (NSDictionary*)deviceDescription;
- (NSImageRep*) _doImageCache: (NSDictionary*)deviceDescription;
@end @end
@implementation NSImage @implementation NSImage
/* Class variables and functions for class methods */ /* Class variables and functions for class methods */
static NSMutableDictionary* nameDict = nil; static NSMutableDictionary *nameDict = nil;
static NSDictionary* nsmapping = nil; static NSDictionary *nsmapping = nil;
static NSColor *clearColor = nil;
static Class cacheClass = 0;
+ (void)initialize + (void) initialize
{ {
if (self == [NSImage class]) if (self == [NSImage class])
{ {
@ -156,13 +158,14 @@ static NSDictionary* nsmapping = nil;
// initialize the class variables // initialize the class variables
nameDict = [[NSMutableDictionary alloc] initWithCapacity: 10]; nameDict = [[NSMutableDictionary alloc] initWithCapacity: 10];
if (path) if (path)
nsmapping = [[[NSString stringWithContentsOfFile: path] nsmapping = RETAIN([[NSString stringWithContentsOfFile: path]
propertyListFromStringsFileFormat] propertyListFromStringsFileFormat]);
retain]; clearColor = RETAIN([NSColor clearColor]);
cacheClass = [NSCachedImageRep class];
} }
} }
+ imageNamed: (NSString *)aName + (id) imageNamed: (NSString *)aName
{ {
NSString *realName = [nsmapping objectForKey: aName]; NSString *realName = [nsmapping objectForKey: aName];
@ -252,7 +255,7 @@ static NSDictionary* nsmapping = nil;
if (image) if (image)
{ {
[image setName: aName]; [image setName: aName];
[image release]; // Retained in dictionary. RELEASE(image); // Retained in dictionary.
} }
return image; return image;
} }
@ -272,10 +275,10 @@ static NSDictionary* nsmapping = nil;
} }
// Designated initializer for nearly everything. // Designated initializer for nearly everything.
- initWithSize: (NSSize)aSize - (id) initWithSize: (NSSize)aSize
{ {
[super init]; [super init];
_reps = [[NSMutableArray arrayWithCapacity: 2] retain]; _reps = [[NSMutableArray alloc] initWithCapacity: 2];
if (aSize.width && aSize.height) if (aSize.width && aSize.height)
{ {
_size = aSize; _size = aSize;
@ -302,7 +305,7 @@ static NSDictionary* nsmapping = nil;
_flags.dataRetained = NO; _flags.dataRetained = NO;
if (![self useFromFile: fileName]) if (![self useFromFile: fileName])
{ {
[self release]; RELEASE(self);
return nil; return nil;
} }
} }
@ -318,7 +321,7 @@ static NSDictionary* nsmapping = nil;
_flags.dataRetained = YES; _flags.dataRetained = YES;
if (![self useFromFile: fileName]) if (![self useFromFile: fileName])
{ {
[self release]; RELEASE(self);
return nil; return nil;
} }
} }
@ -333,14 +336,14 @@ static NSDictionary* nsmapping = nil;
{ {
if (![self loadFromData: data]) if (![self loadFromData: data])
{ {
[self release]; RELEASE(self);
return nil; return nil;
} }
} }
return self; return self;
} }
- initWithPasteboard: (NSPasteboard *)pasteboard - (id) initWithPasteboard: (NSPasteboard *)pasteboard
{ {
[self notImplemented: _cmd]; [self notImplemented: _cmd];
return nil; return nil;
@ -356,7 +359,8 @@ static NSDictionary* nsmapping = nil;
{ {
if (_size.width == 0) if (_size.width == 0)
{ {
NSImageRep* rep = [self bestRepresentationForDevice: nil]; NSImageRep *rep = [self bestRepresentationForDevice: nil];
_size = [rep size]; _size = [rep size];
} }
return _size; return _size;
@ -365,52 +369,48 @@ static NSDictionary* nsmapping = nil;
- (void) dealloc - (void) dealloc
{ {
[self representations]; [self representations];
[_repList release]; RELEASE(_repList);
[_reps release]; RELEASE(_reps);
/* Make sure we don't remove name from the nameDict if we are just a copy /* Make sure we don't remove name from the nameDict if we are just a copy
of the named image, not the original image */ of the named image, not the original image */
if (name && self == [nameDict objectForKey: name]) if (name && self == [nameDict objectForKey: name])
[nameDict removeObjectForKey: name]; [nameDict removeObjectForKey: name];
[name release]; RELEASE(name);
[super dealloc]; [super dealloc];
} }
- copyWithZone: (NSZone *)zone - (id) copyWithZone: (NSZone *)zone
{ {
NSImage* copy; NSImage *copy;
// FIXME: maybe we should retain if _flags.dataRetained = NO // FIXME: maybe we should retain if _flags.dataRetained = NO
copy = (NSImage*)NSCopyObject (self, 0, zone); copy = (NSImage*)NSCopyObject (self, 0, zone);
[name retain]; RETAIN(name);
copy->_reps = [NSMutableArray new]; copy->_reps = [NSMutableArray new];
copy->_repList = [NSMutableArray new]; copy->_repList = [NSMutableArray new];
[_color retain]; RETAIN(_color);
_lockedView = nil; _lockedView = nil;
[copy addRepresentations: [[[self representations] copyWithZone: zone] [copy addRepresentations: [self representations]];
autorelease]];
return copy; return copy;
} }
- (BOOL)setName: (NSString *)string - (BOOL) setName: (NSString *)string
{ {
if (!nameDict) if (!nameDict)
nameDict = [[NSMutableDictionary dictionaryWithCapacity: 2] retain]; nameDict = [[NSMutableDictionary alloc] initWithCapacity: 2];
if (!string || [nameDict objectForKey: string]) if (!string || [nameDict objectForKey: string])
return NO; return NO;
[string retain]; ASSIGN(name, string);
if (name)
[name release];
name = string;
[nameDict setObject: self forKey: name]; [nameDict setObject: self forKey: name];
return YES; return YES;
} }
- (NSString *)name - (NSString *) name
{ {
return name; return name;
} }
@ -421,7 +421,7 @@ static NSDictionary* nsmapping = nil;
_flags.useEPSOnResolutionMismatch = flag; _flags.useEPSOnResolutionMismatch = flag;
} }
- (BOOL)usesEPSOnResolutionMismatch - (BOOL) usesEPSOnResolutionMismatch
{ {
return _flags.useEPSOnResolutionMismatch; return _flags.useEPSOnResolutionMismatch;
} }
@ -431,7 +431,7 @@ static NSDictionary* nsmapping = nil;
_flags.colorMatchPreferred = flag; _flags.colorMatchPreferred = flag;
} }
- (BOOL)prefersColorMatch - (BOOL) prefersColorMatch
{ {
return _flags.colorMatchPreferred; return _flags.colorMatchPreferred;
} }
@ -441,7 +441,7 @@ static NSDictionary* nsmapping = nil;
_flags.multipleResolutionMatching = flag; _flags.multipleResolutionMatching = flag;
} }
- (BOOL)matchesOnMultipleResolution - (BOOL) matchesOnMultipleResolution
{ {
return _flags.multipleResolutionMatching; return _flags.multipleResolutionMatching;
} }
@ -492,15 +492,18 @@ static NSDictionary* nsmapping = nil;
GSRepData *repd = (GSRepData*)[_reps objectAtIndex: i]; GSRepData *repd = (GSRepData*)[_reps objectAtIndex: i];
if (repd->bg != nil if (repd->bg != nil
|| [repd->rep isKindOfClass: [NSCachedImageRep class]] == NO) || [repd->rep isKindOfClass: cacheClass] == NO)
valid = YES; {
valid = YES;
break;
}
} }
return valid; return valid;
} }
- (void) recache - (void) recache
{ {
int i, count; unsigned i, count;
count = [_reps count]; count = [_reps count];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -510,8 +513,7 @@ static NSDictionary* nsmapping = nil;
repd = (GSRepData*)[_reps objectAtIndex: i]; repd = (GSRepData*)[_reps objectAtIndex: i];
if (repd->bg != nil) if (repd->bg != nil)
{ {
[repd->bg release]; DESTROY(repd->bg);
repd->bg = nil;
} }
} }
} }
@ -528,18 +530,13 @@ static NSDictionary* nsmapping = nil;
- (void) setBackgroundColor: (NSColor *)aColor - (void) setBackgroundColor: (NSColor *)aColor
{ {
if (_color != aColor) ASSIGN(_color, aColor);
{
if (_color)
[_color release];
_color = [aColor retain];
}
} }
- (NSColor *) backgroundColor - (NSColor *) backgroundColor
{ {
if (_color == nil) if (_color == nil)
_color = [[NSColor clearColor] retain]; _color = RETAIN(clearColor);
return _color; return _color;
} }
@ -575,39 +572,24 @@ static NSDictionary* nsmapping = nil;
// a cache and no cache exists, create one and draw the representation in it // a cache and no cache exists, create one and draw the representation in it
// If a cache exists, but is not valid, redraw the cache from the original // If a cache exists, but is not valid, redraw the cache from the original
// image (if there is one). // image (if there is one).
- (NSImageRep *)_doImageCache - (NSImageRep *)_doImageCache: (NSDictionary*)deviceDesc
{ {
NSImageRep *rep = nil; NSImageRep *rep = nil;
GSRepData *repd; GSRepData *repd;
repd = repd_for_rep(_reps, [self bestRepresentationForDevice: nil]); repd = repd_for_rep(_reps, [self bestRepresentationForDevice: deviceDesc]);
rep = repd->rep; rep = repd->rep;
if (doesCaching) if (doesCaching == YES)
{ {
/* /*
* If this is not a cached image rep - create a cache to be used to * If this is not a cached image rep - create a cache to be used to
* render the image rep into, and switch to the cached rep. * render the image rep into, and switch to the cached rep.
*/ */
if ([rep isKindOfClass: [NSCachedImageRep class]] == NO) if ([rep isKindOfClass: cacheClass] == NO)
{ {
NSScreen *cur = [NSScreen mainScreen]; rep = [self cacheForRep: rep onDevice: deviceDesc];
NSCachedImageRep *cachedRep; repd = repd_for_rep(_reps, rep);
NSSize imageSize;
imageSize = [self size];
if (imageSize.width == 0 || imageSize.height == 0)
return nil;
cachedRep = [[NSCachedImageRep alloc] initWithSize: _size
depth: [cur depth]
separate: NO
alpha: NO];
[self addRepresentation: cachedRep];
[cachedRep release]; /* Retained in _reps array. */
repd = repd_for_rep(_reps, cachedRep);
repd->original = rep;
rep = repd->rep;
} }
/* /*
@ -620,21 +602,16 @@ static NSDictionary* nsmapping = nil;
NSRect bounds; NSRect bounds;
[self lockFocusOnRepresentation: rep]; [self lockFocusOnRepresentation: rep];
/*
* If this is not a cache - the lockFocus will have created a
* cache that we can use instead.
*/
if (repd->original == nil)
{
repd = repd_for_rep(_reps, [self lastRepresentation]);
}
bounds = [_lockedView bounds]; bounds = [_lockedView bounds];
[_color set]; if (_color != nil && [_color isEqual: clearColor] == NO)
NSEraseRect(bounds); {
[_color set];
NSEraseRect(bounds);
}
[self drawRepresentation: repd->original [self drawRepresentation: repd->original
inRect: NSMakeRect(0, 0, _size.width, _size.height)]; inRect: NSMakeRect(0, 0, _size.width, _size.height)];
[self unlockFocus]; [self unlockFocus];
repd->bg = [_color copy]; repd->bg = _color ? [_color copy] : [clearColor copy];
} }
} }
@ -662,7 +639,7 @@ static NSDictionary* nsmapping = nil;
// xxx If fromRect specifies something other than full image // xxx If fromRect specifies something other than full image
// then we need to construct a subimage to draw // then we need to construct a subimage to draw
rep = [self _doImageCache]; rep = [self _doImageCache: nil];
[self drawRepresentation: rep inRect: rect]; [self drawRepresentation: rep inRect: rect];
} }
@ -684,7 +661,7 @@ static NSDictionary* nsmapping = nil;
// xxx If fromRect specifies something other than full image // xxx If fromRect specifies something other than full image
// then we need to construct a subimage to draw // then we need to construct a subimage to draw
rep = [self _doImageCache]; rep = [self _doImageCache: nil];
[self drawRepresentation: rep inRect: rect]; [self drawRepresentation: rep inRect: rect];
} }
@ -751,9 +728,9 @@ static NSDictionary* nsmapping = nil;
if ([array indexOfObject: ext] == NSNotFound) if ([array indexOfObject: ext] == NSNotFound)
return NO; return NO;
repd = [GSRepData new]; repd = [GSRepData new];
repd->fileName = [fileName retain]; repd->fileName = RETAIN(fileName);
[_reps addObject: repd]; [_reps addObject: repd];
[repd release]; RELEASE(repd);
_flags.syncLoad = YES; _flags.syncLoad = YES;
return YES; return YES;
} }
@ -777,31 +754,12 @@ static NSDictionary* nsmapping = nil;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
repd = [GSRepData new]; repd = [GSRepData new];
repd->rep = [[imageRepArray objectAtIndex: i] retain]; repd->rep = RETAIN([imageRepArray objectAtIndex: i]);
[_reps addObject: repd]; [_reps addObject: repd];
[repd release]; RELEASE(repd);
} }
} }
- (BOOL) useCacheWithDepth: (int)depth
{
NSSize imageSize;
NSCachedImageRep* rep;
imageSize = [self size];
if (!imageSize.width || !imageSize.height)
return NO;
// FIXME: determine alpha? separate?
rep = [[NSCachedImageRep alloc] initWithSize: _size
depth: depth
separate: NO
alpha: NO];
[self addRepresentation: rep];
return YES;
}
- (void) removeRepresentation: (NSImageRep *)imageRep - (void) removeRepresentation: (NSImageRep *)imageRep
{ {
unsigned i; unsigned i;
@ -824,57 +782,45 @@ static NSDictionary* nsmapping = nil;
- (void) lockFocus - (void) lockFocus
{ {
NSScreen *cur = [NSScreen mainScreen];
NSImageRep *rep; NSImageRep *rep;
if (!(rep = [self bestRepresentationForDevice: nil])) if (!(rep = [self bestRepresentationForDevice: nil]))
{ {
[self useCacheWithDepth: [cur depth]]; if ([rep isKindOfClass: cacheClass] == NO)
rep = [self lastRepresentation]; {
rep = [self cacheForRep: rep onDevice: nil];
}
} }
[self lockFocusOnRepresentation: rep]; [self lockFocusOnRepresentation: rep];
} }
- (void) lockFocusOnRepresentation: (NSImageRep *)imageRep - (void) lockFocusOnRepresentation: (NSImageRep *)imageRep
{ {
NSScreen *cur = [NSScreen mainScreen]; if (imageRep == nil)
NSWindow *window;
if (!imageRep)
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
format: @"Cannot lock focus on nil rep"]; format: @"Cannot lock focus on nil rep"];
if (doesCaching) if (doesCaching == YES)
{ {
if (![imageRep isKindOfClass: [NSCachedImageRep class]]) NSWindow *window;
{
GSRepData *cached;
int depth;
if (_flags.unboundedCacheDepth) if ([imageRep isKindOfClass: cacheClass] == NO)
depth = [cur depth]; // FIXME: get depth correctly {
else imageRep = [self cacheForRep: imageRep onDevice: nil];
depth = [cur depth]; }
if (![self useCacheWithDepth: depth]) window = [(NSCachedImageRep *)imageRep window];
{ _lockedView = [window contentView];
[NSException raise: NSImageCacheException [_lockedView lockFocus];
format: @"Unable to create cache"];
}
cached = repd_for_rep(_reps, [self lastRepresentation]);
cached->original = imageRep;
imageRep = cached->rep;
}
window = [(NSCachedImageRep *)imageRep window];
_lockedView = [window contentView];
[_lockedView lockFocus];
} }
} }
- (void) unlockFocus - (void) unlockFocus
{ {
if (_lockedView) if (_lockedView != nil)
[_lockedView unlockFocus]; {
_lockedView = nil; [_lockedView unlockFocus];
_lockedView = nil;
}
} }
- (NSImageRep *) lastRepresentation - (NSImageRep *) lastRepresentation
@ -902,8 +848,7 @@ static NSDictionary* nsmapping = nil;
/* /*
* What's the best representation? FIXME * What's the best representation? FIXME
* At the moment we take the last bitmap we find, or the first * At the moment we take the last bitmap we find.
* rep of any type if we don't find a bitmap.
*/ */
[_reps getObjects: reps]; [_reps getObjects: reps];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -914,73 +859,99 @@ static NSDictionary* nsmapping = nil;
{ {
rep = repd->rep; rep = repd->rep;
} }
else if (rep == nil)
{
rep = repd->rep;
}
}
/*
* If we got a representation - see if we already have it cached.
*/
if (doesCaching)
{
if (rep != nil)
{
GSRepData *invalidCache = nil;
GSRepData *validCache = nil;
/*
* Search the cached image reps for any whose original is our
* 'best' image rep. See if we can notice any invalidated
* cache as we go - if we don't find a valid cache, we want to
* re-use an invalidated one rather than createing a new one.
*/
for (i = 0; i < count; i++)
{
GSRepData *repd = reps[i];
if (repd->original == rep)
{
if (repd->bg == nil)
{
invalidCache = repd;
}
else if ([repd->bg isEqual: _color] == YES)
{
validCache = repd;
break;
}
}
}
if (validCache)
{
/*
* If the image rep has transparencey and we are drawing
* without a background (background is clear) then the
* cache can't really be valid 'cos we might be drawing
* transparency on top of anything. So we invalidate
* the cache by removing the background color information.
*/
if ([rep hasAlpha]
&& [validCache->bg isEqual: [NSColor clearColor]])
{
[validCache->bg release];
validCache->bg = nil;
}
rep = validCache->rep;
}
else if (invalidCache)
{
rep = invalidCache->rep;
}
}
} }
} }
return rep; return rep;
} }
- (NSImageRep*) cacheForRep: (NSImageRep*)rep
onDevice: (NSDictionary*)deviceDescription
{
if (doesCaching == YES)
{
NSImageRep *cacheRep = nil;
unsigned count = [_reps count];
if (count > 0)
{
GSRepData *invalidCache = nil;
GSRepData *validCache = nil;
GSRepData *reps[count];
unsigned i;
[_reps getObjects: reps];
/*
* Search the cached image reps for any whose original is our
* 'best' image rep. See if we can notice any invalidated
* cache as we go - if we don't find a valid cache, we want to
* re-use an invalidated one rather than createing a new one.
*/
for (i = 0; i < count; i++)
{
GSRepData *repd = reps[i];
if (repd->original == rep)
{
if (repd->bg == nil)
{
invalidCache = repd;
}
else if ([repd->bg isEqual: _color] == YES)
{
validCache = repd;
break;
}
}
}
if (validCache != nil)
{
/*
* If the image rep has transparencey and we are drawing
* without a background (background is clear) then the
* cache can't really be valid 'cos we might be drawing
* transparency on top of anything. So we invalidate
* the cache by removing the background color information.
*/
if ([rep hasAlpha] && [validCache->bg isEqual: clearColor])
{
DESTROY(validCache->bg);
}
cacheRep = validCache->rep;
}
else if (invalidCache != nil)
{
cacheRep = invalidCache->rep;
}
}
if (cacheRep == nil)
{
NSScreen *cur = [NSScreen mainScreen];
NSSize imageSize;
GSRepData *repd;
imageSize = [self size];
if (imageSize.width == 0 || imageSize.height == 0)
return nil;
cacheRep = [[cacheClass alloc] initWithSize: _size
depth: [cur depth]
separate: NO
alpha: NO];
[self addRepresentation: cacheRep];
RELEASE(cacheRep); /* Retained in _reps array. */
repd = repd_for_rep(_reps, cacheRep);
repd->original = rep;
}
return cacheRep;
}
else
{
return rep;
}
}
- (NSArray *) representations - (NSArray *) representations
{ {
unsigned i, count; unsigned i, count;

View file

@ -120,29 +120,29 @@
[self setControlView: controlView]; [self setControlView: controlView];
// do nothing if cell's frame rect is zero // do nothing if cell's frame rect is zero
if( NSIsEmptyRect(cellFrame) ) if (NSIsEmptyRect(cellFrame))
return; return;
[controlView lockFocus]; [controlView lockFocus];
// draw the border if needed // draw the border if needed
switch( [self imageFrameStyle] ) switch ([self imageFrameStyle])
{ {
case NSImageFrameNone: case NSImageFrameNone:
// nada // nada
break; break;
case NSImageFramePhoto: case NSImageFramePhoto:
// what does this one look like? TODO (in sync with the rest of the code) // FIXME
break; break;
case NSImageFrameGrayBezel: case NSImageFrameGrayBezel:
NSDrawGrayBezel(cellFrame, NSZeroRect); NSDrawGrayBezel(cellFrame, NSZeroRect);
break; break;
case NSImageFrameGroove: case NSImageFrameGroove:
NSDrawGroove(cellFrame, NSZeroRect); NSDrawGroove(cellFrame, NSZeroRect);
break; break;
case NSImageFrameButton: case NSImageFrameButton:
NSDrawButton(cellFrame, NSZeroRect); NSDrawButton(cellFrame, NSZeroRect);
break; break;
} }
[self drawInteriorWithFrame: cellFrame inView: controlView]; [self drawInteriorWithFrame: cellFrame inView: controlView];
[controlView unlockFocus]; [controlView unlockFocus];
@ -165,7 +165,7 @@ static inline float xRightInRect(NSSize innerSize, NSRect outerRect)
static inline float yTopInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) static inline float yTopInRect(NSSize innerSize, NSRect outerRect, BOOL flipped)
{ {
if( flipped ) if (flipped)
return NSMinY(outerRect); return NSMinY(outerRect);
else else
return MAX(NSMaxY(outerRect) - innerSize.height, 0.0); return MAX(NSMaxY(outerRect) - innerSize.height, 0.0);
@ -178,7 +178,7 @@ static inline float yCenterInRect(NSSize innerSize, NSRect outerRect, BOOL flipp
static inline float yBottomInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) static inline float yBottomInRect(NSSize innerSize, NSRect outerRect, BOOL flipped)
{ {
if( flipped ) if (flipped)
return MAX(NSMaxY(outerRect) - innerSize.height, 0.0); return MAX(NSMaxY(outerRect) - innerSize.height, 0.0);
else else
return NSMinY(outerRect); return NSMinY(outerRect);
@ -207,85 +207,85 @@ static inline NSSize scaleProportionally(NSSize imageSize, NSRect canvasRect)
NSDebugLLog(@"NSImageCell", @"NSImageCell drawInteriorWithFrame called"); NSDebugLLog(@"NSImageCell", @"NSImageCell drawInteriorWithFrame called");
image = [self image]; image = [self image];
if( !image ) if (!image)
return; return;
// leave room for the frame // leave room for the frame
cellFrame = [self drawingRectForBounds: cellFrame]; cellFrame = [self drawingRectForBounds: cellFrame];
[controlView lockFocus]; [controlView lockFocus];
switch( [self imageScaling] ) switch ([self imageScaling])
{
case NSScaleProportionally:
{ {
NSDebugLLog(@"NSImageCell", @"NSScaleProportionally"); case NSScaleProportionally:
[image setScalesWhenResized:YES]; {
[image setSize: scaleProportionally(_original_image_size, cellFrame)]; NSDebugLLog(@"NSImageCell", @"NSScaleProportionally");
break; [image setScalesWhenResized:YES];
[image setSize: scaleProportionally(_original_image_size, cellFrame)];
break;
}
case NSScaleToFit:
{
NSDebugLLog(@"NSImageCell", @"NSScaleToFit");
[image setScalesWhenResized:YES];
[image setSize: cellFrame.size];
break;
}
case NSScaleNone:
{
NSDebugLLog(@"NSImageCell", @"NSScaleNone");
[image setScalesWhenResized:NO];
// don't let the image size overrun the space available
if (_original_image_size.width > cellFrame.size.width
|| _original_image_size.height > cellFrame.size.height)
[image setSize: cellFrame.size];
else
[image setSize: _original_image_size];
break;
}
} }
case NSScaleToFit:
{
NSDebugLLog(@"NSImageCell", @"NSScaleToFit");
[image setScalesWhenResized:YES];
[image setSize: cellFrame.size];
break;
}
case NSScaleNone:
{
NSDebugLLog(@"NSImageCell", @"NSScaleNone");
[image setScalesWhenResized:NO];
// don't let the image size overrun the space available
if( _original_image_size.width > cellFrame.size.width ||
_original_image_size.height > cellFrame.size.height )
[image setSize: cellFrame.size];
else
[image setSize: _original_image_size];
break;
}
}
switch( [self imageAlignment] ) switch ([self imageAlignment])
{ {
case NSImageAlignLeft: case NSImageAlignLeft:
position.x = xLeftInRect([image size], cellFrame); position.x = xLeftInRect([image size], cellFrame);
position.y = yCenterInRect([image size], cellFrame, is_flipped); position.y = yCenterInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignRight: case NSImageAlignRight:
position.x = xRightInRect([image size], cellFrame); position.x = xRightInRect([image size], cellFrame);
position.y = yCenterInRect([image size], cellFrame, is_flipped); position.y = yCenterInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignCenter: case NSImageAlignCenter:
position.x = xCenterInRect([image size], cellFrame); position.x = xCenterInRect([image size], cellFrame);
position.y = yCenterInRect([image size], cellFrame, is_flipped); position.y = yCenterInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignTop: case NSImageAlignTop:
position.x = xCenterInRect([image size], cellFrame); position.x = xCenterInRect([image size], cellFrame);
position.y = yTopInRect([image size], cellFrame, is_flipped); position.y = yTopInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignBottom: case NSImageAlignBottom:
position.x = xCenterInRect([image size], cellFrame); position.x = xCenterInRect([image size], cellFrame);
position.y = yBottomInRect([image size], cellFrame, is_flipped); position.y = yBottomInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignTopLeft: case NSImageAlignTopLeft:
position.x = xLeftInRect([image size], cellFrame); position.x = xLeftInRect([image size], cellFrame);
position.y = yTopInRect([image size], cellFrame, is_flipped); position.y = yTopInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignTopRight: case NSImageAlignTopRight:
position.x = xRightInRect([image size], cellFrame); position.x = xRightInRect([image size], cellFrame);
position.y = yTopInRect([image size], cellFrame, is_flipped); position.y = yTopInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignBottomLeft: case NSImageAlignBottomLeft:
position.x = xLeftInRect([image size], cellFrame); position.x = xLeftInRect([image size], cellFrame);
position.y = yBottomInRect([image size], cellFrame, is_flipped); position.y = yBottomInRect([image size], cellFrame, is_flipped);
break; break;
case NSImageAlignBottomRight: case NSImageAlignBottomRight:
position.x = xRightInRect([image size], cellFrame); position.x = xRightInRect([image size], cellFrame);
position.y = yBottomInRect([image size], cellFrame, is_flipped); position.y = yBottomInRect([image size], cellFrame, is_flipped);
break; break;
} }
// account for flipped views // account for flipped views
if( is_flipped ) if (is_flipped)
position.y += [image size].height; position.y += [image size].height;
// draw! // draw!
@ -300,18 +300,18 @@ static inline NSSize scaleProportionally(NSSize imageSize, NSRect canvasRect)
// Get border size // Get border size
switch (_frameStyle) switch (_frameStyle)
{ {
case NSImageFrameNone: case NSImageFrameNone:
borderSize = [NSCell sizeForBorderType: NSNoBorder]; borderSize = [NSCell sizeForBorderType: NSNoBorder];
break; break;
case NSImageFramePhoto: case NSImageFramePhoto:
// what does this one look like? TODO (in sync with the rest of the code) // FIXME
borderSize = [NSCell sizeForBorderType: NSNoBorder]; borderSize = [NSCell sizeForBorderType: NSNoBorder];
break; break;
case NSImageFrameGrayBezel: case NSImageFrameGrayBezel:
case NSImageFrameGroove: case NSImageFrameGroove:
case NSImageFrameButton: case NSImageFrameButton:
borderSize = [NSCell sizeForBorderType: NSBezelBorder]; borderSize = [NSCell sizeForBorderType: NSBezelBorder];
break; break;
} }
// Get Content Size // Get Content Size