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>
* Source/NSDocument.m (-addWindowController:,-removeWindowController:):

View file

@ -315,7 +315,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (id) initWithSize: (NSSize)aSize
{
[super init];
if (!(self = [super init]))
return nil;
//_flags.archiveByName = NO;
//_flags.scalable = NO;
@ -341,7 +342,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (id) initByReferencingFile: (NSString *)fileName
{
self = [self init];
if (!(self = [self init]))
return nil;
if (![self _useFromFile: fileName])
{
@ -392,7 +394,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(self);
return nil;
}
self = [self init];
if (!(self = [self init]))
return nil;
[self addRepresentation: rep];
RELEASE(rep);
return self;
@ -408,7 +412,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(self);
return nil;
}
self = [self init];
if (!(self = [self init]))
return nil;
[self addRepresentation: rep];
RELEASE(rep);
return self;
@ -423,7 +429,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(self);
return nil;
}
self = [self init];
if (!(self = [self init]))
return nil;
_flags.dataRetained = YES;
[self addRepresentations: array];
return self;
@ -647,6 +655,15 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
BOOL valid = NO;
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
is a valid cache */
// FIXME: Not sure if this is correct
@ -744,7 +761,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
if (cache != nil)
{
NSRect rect;
float y = aPoint.y;
rect = [cache rect];
NSDebugLLog(@"NSImage", @"composite rect %@ in %@",
@ -756,7 +772,7 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
rect = NSIntersectionRect(aRect, 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
{
@ -788,12 +804,12 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
operation: (NSCompositingOperation)op
fraction: (float)delta
{
NSRect rect;
NSSize size = [self size];
rect = NSMakeRect(0, 0, size.width, size.height);
[self compositeToPoint: aPoint fromRect: rect
operation: op fraction: delta];
[self compositeToPoint: aPoint
fromRect: NSMakeRect(0, 0, size.width, size.height)
operation: op
fraction: delta];
}
- (void) compositeToPoint: (NSPoint)aPoint
@ -861,11 +877,11 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat
{
NSRect rect;
NSSize size = [self size];
rect = NSMakeRect(0, 0, size.width, size.height);
[self dissolveToPoint: aPoint fromRect: rect fraction: aFloat];
[self dissolveToPoint: aPoint
fromRect: NSMakeRect(0, 0, size.width, size.height)
fraction: aFloat];
}
- (void) dissolveToPoint: (NSPoint)aPoint
@ -893,7 +909,6 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
if (cache != nil)
{
NSRect rect;
float y = aPoint.y;
rect = [cache rect];
// 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;
rect = NSIntersectionRect(aRect, 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
{
@ -938,13 +953,16 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
PSgsave();
if (_color != nil)
if (_color != nil && [_color alphaComponent] != 0.0)
{
NSRect fillrect = aRect;
[_color set];
if ([[NSView focusView] isFlipped])
fillrect.origin.y -= _size.height;
[_color set];
NSRectFill(fillrect);
if ([GSCurrentContext() isDrawingToScreen] == NO)
{
/* Reset alpha for image drawing. */
@ -1200,7 +1218,10 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
}
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
{
// FIXME: This should rather use
// [NSGraphicsContext graphicsContextWithBitmapImageRep:]
if (_cacheMode != NSImageCacheNever)
{
NSWindow *window;
@ -1231,14 +1250,10 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
[NSException raise: NSImageCacheException
format: @"Cannot lock focus on nil rep"];
[_lockedView lockFocus];
/* Validate cached image */
if (repd->bg == nil)
{
repd->bg = [_color copy];
[_color set];
if ([_color alphaComponent] < 1)
// Clear the background of the cached image, as it is not valid
if ([_color alphaComponent] < 1.0)
{
/* With a Quartz-like alpha model, alpha can't be cleared
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,
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));
}
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
{
BOOL flag;
@ -1851,24 +1885,6 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
inRect: NSMakeRect(0, 0, _size.width, _size.height)];
[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 %@",
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
* render the image rep into, and switch to the cached rep.
*/
NSImageRep *cacheRep = nil;
unsigned count = [_reps count];
if (count > 0)
{
GSRepData *invalidCache = nil;
GSRepData *partialCache = nil;
GSRepData *validCache = nil;
GSRepData *reps[count];
unsigned partialCount = 0;
unsigned i;
@ -1916,7 +1930,7 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
{
GSRepData *repd = reps[i];
if (repd->original == rep && repd->rep != rep)
if (repd->original == rep && repd->rep != nil)
{
if (repd->bg == nil)
{
@ -1928,8 +1942,7 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
{
NSDebugLLog(@"NSImage", @"Exact %@ ... %@ %d",
repd->bg, _color, repd->rep);
validCache = repd;
break;
return repd;
}
else
{
@ -1941,25 +1954,14 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
}
}
if (validCache != nil)
{
if (NSImageForceCaching == NO && opaque == NO)
if (invalidCache != nil)
{
/*
* If the image rep is not opaque and we are drawing
* without an opaque background 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 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.
*/
if ([validCache->bg alphaComponent] != 1.0)
{
DESTROY(validCache->bg);
}
}
cacheRep = validCache->rep;
if (cacheRep != nil)
return validCache;
return invalidCache;
}
else if (partialCache != nil && partialCount > 2)
{
@ -1969,48 +1971,28 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
* creating a new cache.
*/
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);
}
}
cacheRep = partialCache->rep;
if (cacheRep != nil)
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;
NSSize imageSize = [self size];
imageSize = [self size];
if (imageSize.width == 0 || imageSize.height == 0)
return nil;
// Create a new cached image rep without any contents.
cacheRep = [[cachedClass alloc]
initWithSize: _size
initWithSize: imageSize
depth: [[NSScreen mainScreen] depth]
separate: NO
alpha: NO];
separate: _flags.cacheSeparately
alpha: [rep hasAlpha]];
repd = [GSRepData new];
repd->rep = cacheRep;
repd->original = rep;
@ -2019,11 +2001,6 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
return repd;
}
else
{
// I don't think we ever reach this line.
return repd_for_rep(_reps, cacheRep);
}
}
}