Don't invalidate valid cached representations. The new cache would have

exactly the same contents.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@27295 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2008-12-15 17:14:30 +00:00
parent 3764826e20
commit 86e5b297ae
2 changed files with 335 additions and 348 deletions

View file

@ -1,3 +1,13 @@
2008-12-15 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSImage.m: White space changes and general clean up.
* Source/NSImage.m (-removeRepresentation:): Remove also cached
representations for the current one.
* Source/NSImage.m (-_cacheForRep:): Don't invalidate a valid
cached representation.
* Source/NSImage.m: Move some code from _doImageCache: to
lockFocusOnRepresentation:
2008-12-14 Wolfgang Lux <wolfgang.lux@gmail.com> 2008-12-14 Wolfgang Lux <wolfgang.lux@gmail.com>
* Source/NSDocument.m (-addWindowController:,-removeWindowController:): * Source/NSDocument.m (-addWindowController:,-removeWindowController:):

View file

@ -315,7 +315,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (id) initWithSize: (NSSize)aSize - (id) initWithSize: (NSSize)aSize
{ {
[super init]; if (!(self = [super init]))
return nil;
//_flags.archiveByName = NO; //_flags.archiveByName = NO;
//_flags.scalable = NO; //_flags.scalable = NO;
@ -341,7 +342,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (id) initByReferencingFile: (NSString *)fileName - (id) initByReferencingFile: (NSString *)fileName
{ {
self = [self init]; if (!(self = [self init]))
return nil;
if (![self _useFromFile: fileName]) if (![self _useFromFile: fileName])
{ {
@ -355,7 +357,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (id) initWithContentsOfFile: (NSString *)fileName - (id) initWithContentsOfFile: (NSString *)fileName
{ {
if ( ! ( self = [self init] ) ) if (!(self = [self init]))
return nil; return nil;
_flags.dataRetained = YES; _flags.dataRetained = YES;
@ -370,7 +372,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (id) initWithData: (NSData *)data - (id) initWithData: (NSData *)data
{ {
if (! ( self = [self init] ) ) if (!(self = [self init]))
return nil; return nil;
_flags.dataRetained = YES; _flags.dataRetained = YES;
@ -383,7 +385,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
return self; return self;
} }
- (id)initWithBitmapHandle:(void *)bitmap - (id) initWithBitmapHandle: (void *)bitmap
{ {
NSImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapHandle: bitmap]; NSImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapHandle: bitmap];
@ -392,7 +394,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(self); RELEASE(self);
return nil; return nil;
} }
self = [self init]; if (!(self = [self init]))
return nil;
[self addRepresentation: rep]; [self addRepresentation: rep];
RELEASE(rep); RELEASE(rep);
return self; return self;
@ -408,7 +412,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(self); RELEASE(self);
return nil; return nil;
} }
self = [self init]; if (!(self = [self init]))
return nil;
[self addRepresentation: rep]; [self addRepresentation: rep];
RELEASE(rep); RELEASE(rep);
return self; return self;
@ -423,7 +429,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(self); RELEASE(self);
return nil; return nil;
} }
self = [self init]; if (!(self = [self init]))
return nil;
_flags.dataRetained = YES; _flags.dataRetained = YES;
[self addRepresentations: array]; [self addRepresentations: array];
return self; return self;
@ -433,7 +441,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
{ {
NSArray *reps; NSArray *reps;
if ( ! ( self = [self init] ) ) if (!(self = [self init]))
return nil; return nil;
reps = [NSImageRep imageRepsWithPasteboard: pasteboard]; reps = [NSImageRep imageRepsWithPasteboard: pasteboard];
@ -647,6 +655,15 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
BOOL valid = NO; BOOL valid = NO;
unsigned i, count; unsigned i, count;
if (_flags.syncLoad)
{
/* Make sure any images that were added with _useFromFile: are loaded
in and added to the representation list. */
if (![self _loadFromFile: _fileName])
return NO;
_flags.syncLoad = NO;
}
/* Go through all our representations and determine if at least one /* Go through all our representations and determine if at least one
is a valid cache */ is a valid cache */
// FIXME: Not sure if this is correct // FIXME: Not sure if this is correct
@ -744,7 +761,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
if (cache != nil) if (cache != nil)
{ {
NSRect rect; NSRect rect;
float y = aPoint.y;
rect = [cache rect]; rect = [cache rect];
NSDebugLLog(@"NSImage", @"composite rect %@ in %@", NSDebugLLog(@"NSImage", @"composite rect %@ in %@",
@ -756,7 +772,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
rect = NSIntersectionRect(aRect, rect); rect = NSIntersectionRect(aRect, rect);
PScomposite(NSMinX(rect), NSMinY(rect), NSWidth(rect), NSHeight(rect), PScomposite(NSMinX(rect), NSMinY(rect), NSWidth(rect), NSHeight(rect),
[[cache window] gState], aPoint.x, y, op); [[cache window] gState], aPoint.x, aPoint.y, op);
} }
else else
{ {
@ -788,12 +804,12 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
operation: (NSCompositingOperation)op operation: (NSCompositingOperation)op
fraction: (float)delta fraction: (float)delta
{ {
NSRect rect;
NSSize size = [self size]; NSSize size = [self size];
rect = NSMakeRect(0, 0, size.width, size.height); [self compositeToPoint: aPoint
[self compositeToPoint: aPoint fromRect: rect fromRect: NSMakeRect(0, 0, size.width, size.height)
operation: op fraction: delta]; operation: op
fraction: delta];
} }
- (void) compositeToPoint: (NSPoint)aPoint - (void) compositeToPoint: (NSPoint)aPoint
@ -861,11 +877,11 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat - (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat
{ {
NSRect rect;
NSSize size = [self size]; NSSize size = [self size];
rect = NSMakeRect(0, 0, size.width, size.height); [self dissolveToPoint: aPoint
[self dissolveToPoint: aPoint fromRect: rect fraction: aFloat]; fromRect: NSMakeRect(0, 0, size.width, size.height)
fraction: aFloat];
} }
- (void) dissolveToPoint: (NSPoint)aPoint - (void) dissolveToPoint: (NSPoint)aPoint
@ -893,7 +909,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
if (cache != nil) if (cache != nil)
{ {
NSRect rect; NSRect rect;
float y = aPoint.y;
rect = [cache rect]; rect = [cache rect];
// Move the drawing rectangle to the origin of the image rep // Move the drawing rectangle to the origin of the image rep
@ -902,7 +917,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
aRect.origin.y += rect.origin.y; aRect.origin.y += rect.origin.y;
rect = NSIntersectionRect(aRect, rect); rect = NSIntersectionRect(aRect, rect);
PSdissolve(NSMinX(rect), NSMinY(rect), NSWidth(rect), NSHeight(rect), PSdissolve(NSMinX(rect), NSMinY(rect), NSWidth(rect), NSHeight(rect),
[[cache window] gState], aPoint.x, y, aFloat); [[cache window] gState], aPoint.x, aPoint.y, aFloat);
} }
else else
{ {
@ -938,13 +953,16 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
PSgsave(); PSgsave();
if (_color != nil) if (_color != nil && [_color alphaComponent] != 0.0)
{ {
NSRect fillrect = aRect; NSRect fillrect = aRect;
[_color set];
if ([[NSView focusView] isFlipped]) if ([[NSView focusView] isFlipped])
fillrect.origin.y -= _size.height; fillrect.origin.y -= _size.height;
[_color set];
NSRectFill(fillrect); NSRectFill(fillrect);
if ([GSCurrentContext() isDrawingToScreen] == NO) if ([GSCurrentContext() isDrawingToScreen] == NO)
{ {
/* Reset alpha for image drawing. */ /* Reset alpha for image drawing. */
@ -1200,7 +1218,10 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
} }
else if (repd->original == imageRep) else if (repd->original == imageRep)
{ {
repd->original = nil; // Remove cached representations for this representation
// instead of turning them into real ones
//repd->original = nil;
[_reps removeObjectAtIndex: i];
} }
} }
} }
@ -1212,8 +1233,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (void) lockFocusOnRepresentation: (NSImageRep *)imageRep - (void) lockFocusOnRepresentation: (NSImageRep *)imageRep
{ {
// FIXME: This should rather use
// [NSGraphicsContext graphicsContextWithBitmapImageRep:]
if (_cacheMode != NSImageCacheNever) if (_cacheMode != NSImageCacheNever)
{ {
NSWindow *window; NSWindow *window;
@ -1231,14 +1250,10 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
[NSException raise: NSImageCacheException [NSException raise: NSImageCacheException
format: @"Cannot lock focus on nil rep"]; format: @"Cannot lock focus on nil rep"];
[_lockedView lockFocus]; [_lockedView lockFocus];
/* Validate cached image */
if (repd->bg == nil) if (repd->bg == nil)
{ {
repd->bg = [_color copy]; // Clear the background of the cached image, as it is not valid
[_color set]; if ([_color alphaComponent] < 1.0)
if ([_color alphaComponent] < 1)
{ {
/* With a Quartz-like alpha model, alpha can't be cleared /* With a Quartz-like alpha model, alpha can't be cleared
with a rectfill, so we need to clear the alpha channel with a rectfill, so we need to clear the alpha channel
@ -1250,8 +1265,26 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
PScompositerect(0, 0, _size.width, _size.height, PScompositerect(0, 0, _size.width, _size.height,
NSCompositeClear); NSCompositeClear);
} }
repd->bg = [_color copy];
if (_color != nil && [_color alphaComponent] != 0.0)
{
// Won't be needed when drawRepresentation: gets called,
// but we never know.
[_color set];
NSRectFill(NSMakeRect(0, 0, _size.width, _size.height)); NSRectFill(NSMakeRect(0, 0, _size.width, _size.height));
} }
if ([repd->bg alphaComponent] == 1.0)
{
[imageRep setOpaque: YES];
}
else
{
[imageRep setOpaque: [repd->original isOpaque]];
}
}
} }
} }
@ -1594,6 +1627,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
} }
} }
} }
- (id) initWithCoder: (NSCoder*)coder - (id) initWithCoder: (NSCoder*)coder
{ {
BOOL flag; BOOL flag;
@ -1793,7 +1827,7 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
- (BOOL) _loadFromFile: (NSString *)fileName - (BOOL) _loadFromFile: (NSString *)fileName
{ {
NSArray* array; NSArray *array;
array = [NSImageRep imageRepsWithContentsOfFile: fileName]; array = [NSImageRep imageRepsWithContentsOfFile: fileName];
if (array) if (array)
@ -1851,24 +1885,6 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
inRect: NSMakeRect(0, 0, _size.width, _size.height)]; inRect: NSMakeRect(0, 0, _size.width, _size.height)];
[self unlockFocus]; [self unlockFocus];
if (_color != nil && [_color alphaComponent] != 0.0)
{
repd->bg = [_color copy];
}
else
{
repd->bg = [clearColor copy];
}
if ([repd->bg alphaComponent] == 1.0)
{
[rep setOpaque: YES];
}
else
{
[rep setOpaque: [repd->original isOpaque]];
}
NSDebugLLog(@"NSImage", @"Rendered rep %p on background %@", NSDebugLLog(@"NSImage", @"Rendered rep %p on background %@",
rep, repd->bg); rep, repd->bg);
} }
@ -1889,14 +1905,12 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
* for this image rep. If none is found create a cache to be used to * for this image rep. If none is found 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.
*/ */
NSImageRep *cacheRep = nil;
unsigned count = [_reps count]; unsigned count = [_reps count];
if (count > 0) if (count > 0)
{ {
GSRepData *invalidCache = nil; GSRepData *invalidCache = nil;
GSRepData *partialCache = nil; GSRepData *partialCache = nil;
GSRepData *validCache = nil;
GSRepData *reps[count]; GSRepData *reps[count];
unsigned partialCount = 0; unsigned partialCount = 0;
unsigned i; unsigned i;
@ -1916,7 +1930,7 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
{ {
GSRepData *repd = reps[i]; GSRepData *repd = reps[i];
if (repd->original == rep && repd->rep != rep) if (repd->original == rep && repd->rep != nil)
{ {
if (repd->bg == nil) if (repd->bg == nil)
{ {
@ -1928,8 +1942,7 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
{ {
NSDebugLLog(@"NSImage", @"Exact %@ ... %@ %d", NSDebugLLog(@"NSImage", @"Exact %@ ... %@ %d",
repd->bg, _color, repd->rep); repd->bg, _color, repd->rep);
validCache = repd; return repd;
break;
} }
else else
{ {
@ -1941,25 +1954,14 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
} }
} }
if (validCache != nil) if (invalidCache != nil)
{
if (NSImageForceCaching == NO && opaque == NO)
{ {
/* /*
* If the image rep is not opaque and we are drawing * If there is an unused cache - use it rather than
* without an opaque background then the cache can't * re-using this one, since we might get a request
* really be valid 'cos we might be drawing transparency * to draw with this color again.
* on top of anything. So we invalidate the cache by
* removing the background color information.
*/ */
if ([validCache->bg alphaComponent] != 1.0) return invalidCache;
{
DESTROY(validCache->bg);
}
}
cacheRep = validCache->rep;
if (cacheRep != nil)
return validCache;
} }
else if (partialCache != nil && partialCount > 2) else if (partialCache != nil && partialCount > 2)
{ {
@ -1969,48 +1971,28 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
* creating a new cache. * creating a new cache.
*/ */
if (NSImageForceCaching == NO && opaque == NO) if (NSImageForceCaching == NO && opaque == NO)
{
if (invalidCache != nil)
{
/*
* If there is an unused cache - use it rather than
* re-using this one, since we might get a request
* to draw with this color again.
*/
partialCache = invalidCache;
}
else
{ {
DESTROY(partialCache->bg); DESTROY(partialCache->bg);
} }
}
cacheRep = partialCache->rep;
if (cacheRep != nil)
return partialCache; return partialCache;
} }
else if (invalidCache != nil)
{
cacheRep = invalidCache->rep;
if (cacheRep != nil)
return invalidCache;
}
} }
if (cacheRep == nil) // We end here, when no representation are there or no match is found.
{ {
NSSize imageSize; NSImageRep *cacheRep = nil;
GSRepData *repd; GSRepData *repd;
NSSize imageSize = [self size];
imageSize = [self size];
if (imageSize.width == 0 || imageSize.height == 0) if (imageSize.width == 0 || imageSize.height == 0)
return nil; return nil;
// Create a new cached image rep without any contents. // Create a new cached image rep without any contents.
cacheRep = [[cachedClass alloc] cacheRep = [[cachedClass alloc]
initWithSize: _size initWithSize: imageSize
depth: [[NSScreen mainScreen] depth] depth: [[NSScreen mainScreen] depth]
separate: NO separate: _flags.cacheSeparately
alpha: NO]; alpha: [rep hasAlpha]];
repd = [GSRepData new]; repd = [GSRepData new];
repd->rep = cacheRep; repd->rep = cacheRep;
repd->original = rep; repd->original = rep;
@ -2019,11 +2001,6 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
return repd; return repd;
} }
else
{
// I don't think we ever reach this line.
return repd_for_rep(_reps, cacheRep);
}
} }
} }