Reviewed by Dave.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Oct 2004 00:20:59 +0000 (00:20 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Oct 2004 00:20:59 +0000 (00:20 +0000)
        - fixed <rdar://problem/3470715> Pattern cache can get huge with use of css background-image in Safari

        * WebCoreSupport.subproj/WebImageRenderer.h: Change WebImageRenderer to be a subclass of NSObject
        rather than NSImage and contain a pointer to a WebInternalImage.
        * WebCoreSupport.subproj/WebImageRenderer.m:
        (-[WebInternalImage releasePatternColor]): Added. Releases patternColor.
        (-[WebImageRenderer initWithMIMEType:]): Added. Makes WebInternalImage and then self.
        (-[WebImageRenderer initWithData:MIMEType:]): Ditto.
        (-[WebImageRenderer initWithContentsOfFile:]): Ditto.
        (-[WebImageRenderer dealloc]): Added. Calls releasePatternColor and then releases WebInternalImage.
        (-[WebImageRenderer image]): Added. Returns pointer to image.
        (-[WebImageRenderer MIMEType]): Added. Calls through to image.
        (-[WebImageRenderer TIFFRepresentation]): Ditto.
        (-[WebImageRenderer frameCount]): Ditto.
        (-[WebImageRenderer setOriginalData:]): Added. Sets image data pointer.
        (+[WebImageRenderer stopAnimationsInView:]): Added. Calls through to image.
        (-[WebImageRenderer incrementalLoadWithBytes:length:complete:]): Ditto.
        (-[WebImageRenderer size]): Ditto.
        (-[WebImageRenderer resize:]): Ditto.
        (-[WebImageRenderer drawImageInRect:fromRect:]): Ditto.
        (-[WebImageRenderer drawImageInRect:fromRect:compositeOperator:context:]): Ditto.
        (-[WebImageRenderer stopAnimation]): Ditto.
        (-[WebImageRenderer tileInRect:fromPoint:context:]): Ditto.
        (-[WebImageRenderer isNull]): Ditto.
        (-[WebImageRenderer retainOrCopyIfNeeded]): Ditto.
        (-[WebImageRenderer increaseUseCount]): Ditto.
        (-[WebImageRenderer decreaseUseCount]): Ditto.
        (-[WebImageRenderer flushRasterCache]): Ditto.
        (-[WebImageRenderer imageRef]): Ditto.
        (-[WebImageRenderer copyWithZone:]): Ditto.

        * Misc.subproj/WebNSViewExtras.m: (-[NSView _web_dragImage:rect:event:pasteboard:source:offset:]):
        Update for slight changes to WebImageRenderer API.
        * WebCoreSupport.subproj/WebImageRendererFactory.m:
        (-[WebImageRendererFactory imageRendererWithMIMEType:]): Ditto.
        (-[WebImageRendererFactory imageRendererWithData:MIMEType:]): Ditto.
        (-[WebImageRendererFactory imageRendererWithSize:]): Ditto.
        (-[WebImageRendererFactory imageRendererWithName:]): Ditto.
        * WebView.subproj/WebImageView.m: (-[WebImageView image]): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7871 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/Misc.subproj/WebNSViewExtras.m
WebKit/WebCoreSupport.subproj/WebImageRenderer.h
WebKit/WebCoreSupport.subproj/WebImageRenderer.m
WebKit/WebCoreSupport.subproj/WebImageRendererFactory.m
WebKit/WebView.subproj/WebImageView.m

index 73a911a..ff640e5 100644 (file)
@@ -1,3 +1,47 @@
+2004-10-20  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dave.
+
+        - fixed <rdar://problem/3470715> Pattern cache can get huge with use of css background-image in Safari
+
+        * WebCoreSupport.subproj/WebImageRenderer.h: Change WebImageRenderer to be a subclass of NSObject
+        rather than NSImage and contain a pointer to a WebInternalImage.
+        * WebCoreSupport.subproj/WebImageRenderer.m:
+        (-[WebInternalImage releasePatternColor]): Added. Releases patternColor.
+        (-[WebImageRenderer initWithMIMEType:]): Added. Makes WebInternalImage and then self.
+        (-[WebImageRenderer initWithData:MIMEType:]): Ditto.
+        (-[WebImageRenderer initWithContentsOfFile:]): Ditto.
+        (-[WebImageRenderer dealloc]): Added. Calls releasePatternColor and then releases WebInternalImage.
+        (-[WebImageRenderer image]): Added. Returns pointer to image.
+        (-[WebImageRenderer MIMEType]): Added. Calls through to image.
+        (-[WebImageRenderer TIFFRepresentation]): Ditto.
+        (-[WebImageRenderer frameCount]): Ditto.
+        (-[WebImageRenderer setOriginalData:]): Added. Sets image data pointer.
+        (+[WebImageRenderer stopAnimationsInView:]): Added. Calls through to image.
+        (-[WebImageRenderer incrementalLoadWithBytes:length:complete:]): Ditto.
+        (-[WebImageRenderer size]): Ditto.
+        (-[WebImageRenderer resize:]): Ditto.
+        (-[WebImageRenderer drawImageInRect:fromRect:]): Ditto.
+        (-[WebImageRenderer drawImageInRect:fromRect:compositeOperator:context:]): Ditto.
+        (-[WebImageRenderer stopAnimation]): Ditto.
+        (-[WebImageRenderer tileInRect:fromPoint:context:]): Ditto.
+        (-[WebImageRenderer isNull]): Ditto.
+        (-[WebImageRenderer retainOrCopyIfNeeded]): Ditto.
+        (-[WebImageRenderer increaseUseCount]): Ditto.
+        (-[WebImageRenderer decreaseUseCount]): Ditto.
+        (-[WebImageRenderer flushRasterCache]): Ditto.
+        (-[WebImageRenderer imageRef]): Ditto.
+        (-[WebImageRenderer copyWithZone:]): Ditto.
+
+        * Misc.subproj/WebNSViewExtras.m: (-[NSView _web_dragImage:rect:event:pasteboard:source:offset:]):
+        Update for slight changes to WebImageRenderer API.
+        * WebCoreSupport.subproj/WebImageRendererFactory.m:
+        (-[WebImageRendererFactory imageRendererWithMIMEType:]): Ditto.
+        (-[WebImageRendererFactory imageRendererWithData:MIMEType:]): Ditto.
+        (-[WebImageRendererFactory imageRendererWithSize:]): Ditto.
+        (-[WebImageRendererFactory imageRendererWithName:]): Ditto.
+        * WebView.subproj/WebImageView.m: (-[WebImageView image]): Ditto.
+
 2004-10-20  Chris Blumenberg  <cblu@apple.com>
        
        Fixed: <rdar://problem/3846943> REGRESSION: JNLP files are rendered instead of downloaded
index 09934a7..2ffa31d 100644 (file)
     NSPoint origin;
     NSImage *image;
     
-#ifdef USE_CGIMAGEREF
     image = [wir image];
-#else
-    image = wir;
-#endif
     if ([image size].height * [image size].width <= WebMaxOriginalImageArea) {
         NSSize originalSize = rect.size;
         origin = rect.origin;
index ecaa6b1..82b32ce 100644 (file)
 
 #else   // Panther version of WebImageRenderer ------------------------------------
 
+@class WebInternalImage;
 
-@interface WebImageRenderer : NSImage <WebCoreImageRenderer>
+@interface WebImageRenderer : NSObject <WebCoreImageRenderer>
 {
-    NSTimer *frameTimer;
-    NSView *frameView;
-    NSRect imageRect;
-    NSRect targetRect;
-
-    int loadStatus;
-
-    NSColor *patternColor;
-    int patternColorLoadStatus;
-
-    int repetitionsComplete;
-    BOOL animationFinished;
-    
-    NSPoint tilePoint;
-    BOOL animatedTile;
-
-    int compositeOperator;
-    id redirectContext;
-    CGContextRef context;
-    BOOL needFlushRasterCache;
-    BOOL rasterFlushing;
-    NSImageCacheMode rasterFlushingOldMode;
-    
-    NSString *MIMEType;
-    BOOL isNull;
-    int useCount;
-
-    CGImageRef cachedImageRef;
-    
-    id _PDFDoc;
-        
-@public    
-    NSData *originalData;
+    WebInternalImage *image;
 }
 
 - (id)initWithMIMEType:(NSString *)MIME;
 - (id)initWithData:(NSData *)data MIMEType:(NSString *)MIME;
-+ (void)stopAnimationsInView:(NSView *)aView;
-- (int)frameCount;
+- (id)initWithContentsOfFile:(NSString *)filename;
 
+- (NSImage *)image;
 - (NSString *)MIMEType;
+- (NSData *)TIFFRepresentation;
+- (int)frameCount;
+
+- (void)setOriginalData:(NSData *)data;
+
++ (void)stopAnimationsInView:(NSView *)aView;
 
 @end
 
@@ -93,5 +68,3 @@
 CGColorSpaceRef WebCGColorSpaceCreateRGB(void);
 CGColorSpaceRef WebCGColorSpaceCreateGray(void);
 CGColorSpaceRef WebCGColorSpaceCreateCMYK(void);
-
-
index 01bbaea..03ab663 100644 (file)
 
 #else
 
+@interface WebInternalImage : NSImage <NSCopying>
+{
+    NSTimer *frameTimer;
+    NSView *frameView;
+    NSRect imageRect;
+    NSRect targetRect;
+
+    int loadStatus;
+
+    NSColor *patternColor;
+    int patternColorLoadStatus;
+
+    int repetitionsComplete;
+    BOOL animationFinished;
+    
+    NSPoint tilePoint;
+    BOOL animatedTile;
+
+    int compositeOperator;
+    id redirectContext;
+    CGContextRef context;
+    BOOL needFlushRasterCache;
+    BOOL rasterFlushing;
+    NSImageCacheMode rasterFlushingOldMode;
+    
+    NSString *MIMEType;
+    BOOL isNull;
+    int useCount;
+
+    CGImageRef cachedImageRef;
+    
+    id _PDFDoc;
+        
+@public    
+    NSData *originalData;
+}
+
+- (id)initWithMIMEType:(NSString *)MIME;
+- (id)initWithData:(NSData *)data MIMEType:(NSString *)MIME;
+
+- (void)releasePatternColor;
+
+- (NSString *)MIMEType;
+- (int)frameCount;
+
+- (BOOL)incrementalLoadWithBytes:(const void *)bytes length:(unsigned)length complete:(BOOL)isComplete;
+- (void)resize:(NSSize)s;
+- (void)drawImageInRect:(NSRect)ir fromRect:(NSRect)fr;
+- (void)drawImageInRect:(NSRect)ir fromRect:(NSRect)fr compositeOperator:(NSCompositingOperation)compsiteOperator context:(CGContextRef)context;
+- (void)stopAnimation;
+- (void)tileInRect:(NSRect)rect fromPoint:(NSPoint)point context:(CGContextRef)aContext;
+- (BOOL)isNull;
+- (void)increaseUseCount;
+- (void)decreaseUseCount;
+- (WebInternalImage *)retainOrCopyIfNeeded;
+- (void)flushRasterCache;
+- (CGImageRef)imageRef;
+
++ (void)stopAnimationsInView:(NSView *)aView;
+
+- (void)startAnimationIfNecessary;
+- (NSGraphicsContext *)_beginRedirectContext:(CGContextRef)aContext;
+- (void)_endRedirectContext:(NSGraphicsContext *)aContext;
+- (void)_needsRasterFlush;
+- (BOOL)_PDFDrawFromRect:(NSRect)srcRect toRect:(NSRect)dstRect operation:(NSCompositingOperation)op alpha:(float)alpha flipped:(BOOL)flipped;
+
+@end
+
 extern NSString *NSImageLoopCount;
 
 /*
@@ -366,24 +434,14 @@ static CGImageRef _createImageRef(NSBitmapImageRep *rep);
 
 #define MINIMUM_DURATION (1.0/30.0)
 
-// Forward declarations
-@interface WebImageRenderer (WebInternal)
-- (void)startAnimationIfNecessary;
-- (NSGraphicsContext *)_beginRedirectContext:(CGContextRef)aContext;
-- (void)_endRedirectContext:(NSGraphicsContext *)aContext;
-- (void)_needsRasterFlush;
-- (BOOL)_PDFDrawFromRect:(NSRect)srcRect toRect:(NSRect)dstRect operation:(NSCompositingOperation)op alpha:(float)alpha flipped:(BOOL)flipped;
-@end
-
-
-@implementation WebImageRenderer
+@implementation WebInternalImage
 
 static NSMutableSet *activeImageRenderers;
 
 + (void)stopAnimationsInView:(NSView *)aView
 {
     NSEnumerator *objectEnumerator = [activeImageRenderers objectEnumerator];
-    WebImageRenderer *renderer;
+    WebInternalImage *renderer;
     NSMutableSet *renderersToStop = [[NSMutableSet alloc] init];
 
     while ((renderer = [objectEnumerator nextObject])) {
@@ -420,7 +478,7 @@ static NSMutableSet *activeImageRenderers;
 
 - (id)initWithData:(NSData *)data MIMEType:(NSString *)MIME
 {
-    WebImageRenderer *result = nil;
+    WebInternalImage *result = nil;
 
     NS_DURING
     
@@ -449,7 +507,7 @@ static NSMutableSet *activeImageRenderers;
 {
     NSBundle *bundle = [NSBundle bundleForClass:[self class]];
     NSString *imagePath = [bundle pathForResource:filename ofType:@"tiff"];
-    WebImageRenderer *result = nil;
+    WebInternalImage *result = nil;
 
     NS_DURING
 
@@ -482,9 +540,9 @@ static NSMutableSet *activeImageRenderers;
     useCount--;
 }
 
-- (id <WebCoreImageRenderer>)retainOrCopyIfNeeded
+- (WebInternalImage *)retainOrCopyIfNeeded
 {
-    WebImageRenderer *copy;
+    WebInternalImage *copy;
 
     // If an animated image appears multiple times in a given page, we
     // must create multiple WebCoreImageRenderers so that each copy
@@ -505,7 +563,7 @@ static NSMutableSet *activeImageRenderers;
 - copyWithZone:(NSZone *)zone
 {
     // FIXME: If we copy while doing an incremental load, it won't work.
-    WebImageRenderer *copy;
+    WebInternalImage *copy;
 
     copy = [super copyWithZone:zone];
     copy->MIMEType = [MIMEType copy];
@@ -1068,13 +1126,6 @@ static NSMutableSet *activeImageRenderers;
     [self setSize:s];
 }
 
-// required by protocol -- apparently inherited methods don't count
-
-- (NSSize)size
-{
-    return [super size];
-}
-
 - (NSString *)MIMEType
 {
     return MIMEType;
@@ -1104,8 +1155,172 @@ static NSMutableSet *activeImageRenderers;
     return ref;
 }
 
+- (void)releasePatternColor
+{
+    [patternColor release];
+    patternColor = nil;
+}
+
 @end
 
+@implementation WebImageRenderer
+
+- (id)initWithMIMEType:(NSString *)MIME
+{
+    WebInternalImage *i = [[WebInternalImage alloc] initWithMIMEType:MIME];
+    if (i == nil) {
+        [self dealloc];
+        return nil;
+    }
+    [self init];
+    image = i;
+    return self;
+}
+
+- (id)initWithData:(NSData *)data MIMEType:(NSString *)MIME
+{
+    WebInternalImage *i = [[WebInternalImage alloc] initWithData:data MIMEType:MIME];
+    if (i == nil) {
+        [self dealloc];
+        return nil;
+    }
+    [self init];
+    image = i;
+    return self;
+}
+
+- (id)initWithContentsOfFile:(NSString *)filename
+{
+    WebInternalImage *i = [[WebInternalImage alloc] initWithContentsOfFile:filename];
+    if (i == nil) {
+        [self dealloc];
+        return nil;
+    }
+    [self init];
+    image = i;
+    return self;
+}
+
+- (void)dealloc
+{
+    [image releasePatternColor];
+    [image release];
+    [super dealloc];
+}
+
+- (NSImage *)image
+{
+    return image;
+}
+
+- (NSString *)MIMEType
+{
+    return [image MIMEType];
+}
+
+- (NSData *)TIFFRepresentation
+{
+    return [image TIFFRepresentation];
+}
+
+- (int)frameCount
+{
+    return [image frameCount];
+}
+
+- (void)setOriginalData:(NSData *)data
+{
+    NSData *oldData = image->originalData;
+    image->originalData = [data retain];
+    [oldData release];
+}
+
++ (void)stopAnimationsInView:(NSView *)aView
+{
+    [WebInternalImage stopAnimationsInView:aView];
+}
+
+- (BOOL)incrementalLoadWithBytes:(const void *)bytes length:(unsigned)length complete:(BOOL)isComplete
+{
+    return [image incrementalLoadWithBytes:bytes length:length complete:isComplete];
+}
+
+- (NSSize)size
+{
+    return [image size];
+}
+
+- (void)resize:(NSSize)s
+{
+    [image resize:s];
+}
+
+- (void)drawImageInRect:(NSRect)ir fromRect:(NSRect)fr
+{
+    [image drawImageInRect:ir fromRect:fr];
+}
+
+- (void)drawImageInRect:(NSRect)ir fromRect:(NSRect)fr compositeOperator:(NSCompositingOperation)compsiteOperator context:(CGContextRef)context
+{
+    [image drawImageInRect:ir fromRect:fr compositeOperator:compsiteOperator context:context];
+}
+
+- (void)stopAnimation
+{
+    [image stopAnimation];
+}
+
+- (void)tileInRect:(NSRect)r fromPoint:(NSPoint)p context:(CGContextRef)context
+{
+    [image tileInRect:r fromPoint:p context:context];
+}
+
+- (BOOL)isNull
+{
+    return image == nil || [image isNull];
+}
+
+- (id <WebCoreImageRenderer>)retainOrCopyIfNeeded
+{
+    WebInternalImage *newImage = [image retainOrCopyIfNeeded];
+    if (newImage == image) {
+        [image release];
+        [self retain];
+        return self;
+    }
+    WebImageRenderer *newRenderer = [[WebImageRenderer alloc] init];
+    newRenderer->image = newImage;
+    return newRenderer;
+}
+
+- (void)increaseUseCount
+{
+    [image increaseUseCount];
+}
+
+- (void)decreaseUseCount
+{
+    [image decreaseUseCount];
+}
+
+- (void)flushRasterCache
+{
+    [image flushRasterCache];
+}
+
+- (CGImageRef)imageRef
+{
+    return [image imageRef];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    WebImageRenderer *copy = [[WebImageRenderer alloc] init];
+    copy->image = [image copy];
+    return copy;
+}
+
+@end
 
 //------------------------------------------------------------------------------------
 
index 436fc7a..da7ab64 100644 (file)
 
 - (id <WebCoreImageRenderer>)imageRendererWithMIMEType:(NSString *)MIMEType
 {
-    NSImage *imageRenderer = [[WebImageRenderer alloc] initWithMIMEType:MIMEType];
+    WebImageRenderer *imageRenderer = [[WebImageRenderer alloc] initWithMIMEType:MIMEType];
 
 #ifndef USE_CGIMAGEREF
+    NSImage *image = [imageRenderer image];
+
     if (![MIMEType isEqual:@"application/pdf"]) {
         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initForIncrementalLoad];
-        [imageRenderer addRepresentation:rep];
+        [image addRepresentation:rep];
         [rep autorelease];
     }
 
-    [imageRenderer setFlipped:YES];
+    [image setFlipped:YES];
     
     // Turn the default caching mode back on when the image has completed load.
     // Caching intermediate progressive representations causes problems for
     // progressive loads.  We also rely on the NSBitmapImageRep surviving during
     // incremental loads.  See 3165631 and 3262592.
-    [imageRenderer setCacheMode: NSImageCacheNever];
+    [image setCacheMode: NSImageCacheNever];
 
-    [imageRenderer setScalesWhenResized:NO];
+    [image setScalesWhenResized:NO];
 #endif
         
     return [imageRenderer autorelease];
     WebImageRenderer *imageRenderer = [[WebImageRenderer alloc] initWithData:data MIMEType:MIMEType];
 
 #ifndef USE_CGIMAGEREF
-    NSArray *reps = [imageRenderer representations];
+    NSImage *image = [imageRenderer image];
+
+    NSArray *reps = [image representations];
     if ([reps count] == 0){
         [imageRenderer release];
         return nil;
     }
     
     // Force the image to use the pixel size and ignore the dpi.
-    [imageRenderer setScalesWhenResized:NO];
+    [image setScalesWhenResized:NO];
     if ([reps count] > 0){
         NSImageRep *rep = [reps objectAtIndex:0];
         [rep setSize:NSMakeSize([rep pixelsWide], [rep pixelsHigh])];
         if ([imageRenderer frameCount] > 1)
-            imageRenderer->originalData = [data retain];
+            [imageRenderer setOriginalData:data];
     }
     
-    [imageRenderer setFlipped:YES];
+    [image setFlipped:YES];
 #endif
 
     return [imageRenderer autorelease];
 {
     WebImageRenderer *imageRenderer = [[[WebImageRenderer alloc] initWithSize:s] autorelease];
 #ifndef USE_CGIMAGEREF
-    [imageRenderer setScalesWhenResized:NO];
+    [[imageRenderer image] setScalesWhenResized:NO];
 #endif
     return imageRenderer;
 }
 {
     WebImageRenderer *imageRenderer = [[[WebImageRenderer alloc] initWithContentsOfFile:name] autorelease];
 #ifndef USE_CGIMAGEREF
-    [imageRenderer setScalesWhenResized:NO];
-    [imageRenderer setFlipped:YES];
+    [[imageRenderer image] setScalesWhenResized:NO];
+    [[imageRenderer image] setFlipped:YES];
 #endif
     return imageRenderer;
 }
index 9df5558..c75f2e0 100644 (file)
 
 - (NSImage *)image
 {
-#ifdef USE_CGIMAGEREF
     return [[rep image] image];
-#else
-    return [rep image];
-#endif
 }
 
 #pragma mark PRINTING