Revision: 12197 http://bibdesk.svn.sourceforge.net/bibdesk/?rev=12197&view=rev Author: amaxwell Date: 2008-01-02 10:29:14 -0800 (Wed, 02 Jan 2008)
Log Message: ----------- - size check in needsRenderForSize: was incorrect - cancel pending loads in -releaseResources - decrease full image size for caching (significantly reduces memory usage and compression overhead) Modified Paths: -------------- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVWebViewIcon.m Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVWebViewIcon.m =================================================================== --- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVWebViewIcon.m 2008-01-02 17:37:02 UTC (rev 12196) +++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVWebViewIcon.m 2008-01-02 18:29:14 UTC (rev 12197) @@ -86,9 +86,9 @@ - (void)_releaseWebView { NSAssert2(pthread_main_np() != 0, @"*** threading violation *** -[%@ [EMAIL PROTECTED] requires main thread", [self class], NSStringFromSelector(_cmd)); - [_webView stopLoading:nil]; [_webView setPolicyDelegate:nil]; [_webView setFrameLoadDelegate:nil]; + [_webView stopLoading:nil]; [_webView release]; _webView = nil; } @@ -107,10 +107,22 @@ [super dealloc]; } +- (void)_releaseWebViewAndRetryIfNeeded +{ + if (nil != _webView) { + _triedWebView = NO; + [self _releaseWebView]; + } +} + - (void)releaseResources { // the thumbnail is small enough to always keep around pthread_mutex_lock(&_mutex); + + // Cancel any pending loads; set _triedWebView to NO if there was a non-nil webview (i.e. it was loading), or else -renderOffscreenOnMainThread will never complete if it gets called again. + [self performSelectorOnMainThread:@selector(_releaseWebViewAndRetryIfNeeded) withObject:nil waitUntilDone:YES]; + CGImageRelease(_fullImageRef); _fullImageRef = NULL; @@ -119,8 +131,15 @@ pthread_mutex_unlock(&_mutex); } -- (NSSize)size { return (NSSize){ 1000, 900 }; } +// size of the _fullImageRef +- (NSSize)size { return (NSSize){ 500, 450 }; } +// actual size of the webview; large enough to fit a reasonably sized page +- (NSSize)_webviewSize { return (NSSize){ 1000, 900 }; } + +// size of the _thumbnailRef (1/5 of webview size) +- (NSSize)_thumbnailSize { return (NSSize){ 200, 180 }; } + - (BOOL)needsRenderForSize:(NSSize)size { BOOL needsRender = NO; @@ -134,7 +153,7 @@ if (YES == _webviewFailed) needsRender = (nil == _fallbackIcon || [_fallbackIcon needsRenderForSize:size]); - else if (size.height > 1.2 * [self size].height) + else if (size.height > 1.2 * [self _thumbnailSize].height) needsRender = (NULL == _fullImageRef); else needsRender = (NULL == _thumbnailRef); @@ -154,17 +173,16 @@ return reachable; } -// returns a 1/5 scale image; change this if -size changes (small image should be <= 200 pixels) -- (CGImageRef)_createResampledImage; +- (CGImageRef)_createResampledImageOfSize:(NSSize)size fromCGImage:(CGImageRef)largeImage; { - CGFloat width = [self size].width / 5; - CGFloat height = [self size].height / 5; + CGFloat width = size.width; + CGFloat height = size.height; // these will always be the same size, so use the context cache CGContextRef ctxt = [FVBitmapContextCache newBitmapContextOfWidth:width height:height]; CGContextSaveGState(ctxt); CGContextSetInterpolationQuality(ctxt, kCGInterpolationHigh); - CGContextDrawImage(ctxt, CGRectMake(0, 0, CGBitmapContextGetWidth(ctxt), CGBitmapContextGetHeight(ctxt)), _fullImageRef); + CGContextDrawImage(ctxt, CGRectMake(0, 0, CGBitmapContextGetWidth(ctxt), CGBitmapContextGetHeight(ctxt)), largeImage); CGContextRestoreGState(ctxt); CGImageRef smallImage = CGBitmapContextCreateImage(ctxt); @@ -201,7 +219,7 @@ WebFrameView *view = [[_webView mainFrame] frameView]; [view setAllowsScrolling:NO]; - NSSize size = [self size]; + NSSize size = [self _webviewSize]; CGContextRef context = [FVBitmapContextCache newBitmapContextOfWidth:size.width height:size.height]; NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:[view isFlipped]]; @@ -223,19 +241,23 @@ [NSGraphicsContext restoreGraphicsState]; // restore previous context + // temporary CGImage from the full webview + CGImageRef largeImage = CGBitmapContextCreateImage(context); + pthread_mutex_lock(&_mutex); // full image is large, so cache it to disk in case we get a -releaseResources or another view needs it CGImageRelease(_fullImageRef); - _fullImageRef = CGBitmapContextCreateImage(context); + _fullImageRef = [self _createResampledImageOfSize:[self size] fromCGImage:largeImage]; [FVIconCache cacheCGImage:_fullImageRef withName:_diskCacheName]; // resample to a thumbnail size that will draw quickly CGImageRelease(_thumbnailRef); - _thumbnailRef = [self _createResampledImage]; + _thumbnailRef = [self _createResampledImageOfSize:[self _thumbnailSize] fromCGImage:largeImage]; pthread_mutex_unlock(&_mutex); + CGImageRelease(largeImage); [FVBitmapContextCache disposeOfBitmapContext:context]; } @@ -299,10 +321,10 @@ _triedWebView = YES; - NSSize size = [self size]; + NSSize size = [self _webviewSize]; // always use the WebKit cache, and use a short timeout (default is 60 seconds) - NSURLRequest *request = [NSURLRequest requestWithURL:_httpURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:1.0]; + NSURLRequest *request = [NSURLRequest requestWithURL:_httpURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0]; // See also http://lists.apple.com/archives/quicklook-dev/2007/Nov/msg00047.html // Note: changed from blocking to non-blocking; we now just keep state and rely on the @@ -338,7 +360,7 @@ // this may have been added to the disk cache by another instance; in that case, we need to create a new thumbnail if (NULL == _thumbnailRef) - _thumbnailRef = [self _createResampledImage]; + _thumbnailRef = [self _createResampledImageOfSize:[self _thumbnailSize] fromCGImage:_fullImageRef]; pthread_mutex_unlock(&_mutex); return; @@ -387,7 +409,8 @@ if (pthread_mutex_trylock(&_mutex) == 0) { CGRect drawRect = [self _drawingRectWithRect:dstRect]; - if (_fullImageRef && (NULL == _thumbnailRef || CGRectGetHeight(drawRect) > 1.2 * CGImageGetHeight(_thumbnailRef))) + // if we have _fullImageRef, we're guaranteed to have _thumbnailRef + if (_fullImageRef && CGRectGetHeight(drawRect) > 1.2 * [self _thumbnailSize].height) CGContextDrawImage(context, drawRect, _fullImageRef); else if (_thumbnailRef) CGContextDrawImage(context, drawRect, _thumbnailRef); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Bibdesk-commit mailing list Bibdesk-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bibdesk-commit