mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 18:30:47 +00:00
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:
parent
f2bcb34b09
commit
804630d3ae
3 changed files with 277 additions and 306 deletions
|
@ -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
|
||||||
|
|
379
Source/NSImage.m
379
Source/NSImage.m
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue