Revision: 25506 http://sourceforge.net/p/bibdesk/svn/25506 Author: hofman Date: 2021-01-31 15:02:23 +0000 (Sun, 31 Jan 2021) Log Message: ----------- Singleton icon for locked PDFs rather than adding a lock badge
Modified Paths: -------------- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVPDFIcon.m trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj Removed Paths: ------------- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.h trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.m Deleted: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.h =================================================================== --- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.h 2021-01-31 14:19:45 UTC (rev 25505) +++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.h 2021-01-31 15:02:23 UTC (rev 25506) @@ -1,47 +0,0 @@ -// -// FVLockBadge.h -// FileView -// -// Created by Christiaan Hofman on 01/14/21. -/* - This software is Copyright (c) 2021 - Christiaa Hofman. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - - Neither the name of Christiaan Hofman nor the names of any - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import <Cocoa/Cocoa.h> - - -@interface FVLockBadge : NSObject - -// returns a cached layer for overlay on an icon -+ (CGLayerRef)lockBadgeWithSize:(NSSize)size; - -@end Deleted: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.m =================================================================== --- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.m 2021-01-31 14:19:45 UTC (rev 25505) +++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVLockBadge.m 2021-01-31 15:02:23 UTC (rev 25506) @@ -1,99 +0,0 @@ -// -// FVLockBadge.m -// FileView -// -// Created by Christiaan Hofman on 01/14/21. -/* - This software is Copyright (c) 2021 - Christiaan hofman. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - - Neither the name of Christiaan Hofman nor the names of any - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "FVLockBadge.h" -#import "FVUtilities.h" - -@implementation FVLockBadge - -static NSMutableArray *_badges = nil; -static const NSUInteger _sizes[] = { 32, 64, 128, 256, 512 }; - -+ (void)initialize -{ - FVINITIALIZE(FVLockBadge); - - _badges = [NSMutableArray new]; - NSUInteger i, iMax = sizeof(_sizes) / sizeof(NSUInteger); - - // kLockedBadgeIcon looks much better than kLockedIcon, which gets jagged quickly - NSImage *lockBadge = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kLockedBadgeIcon)]; - - for (i = 0; i < iMax; i++) { - - CGRect dstRect = CGRectMake(0, 0, _sizes[i], _sizes[i]); - - NSGraphicsContext *windowContext = FVWindowGraphicsContextWithSize(NSRectFromCGRect(dstRect).size); - NSParameterAssert(nil != windowContext); - - CGLayerRef layer = CGLayerCreateWithContext([windowContext graphicsPort], dstRect.size, NULL); - CGContextRef context = CGLayerGetContext(layer); - - // don't use CGContextClearRect with non-window/bitmap contexts - CGContextSetRGBFillColor(context, 0, 0, 0, 0); - CGContextFillRect(context, dstRect); - - // rect needs to be a square, or else the aspect ratio of the arrow is wrong - // rect needs to be the same size as the full icon, or the scale of the arrow is wrong - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]]; - - // We don't know the size of the actual link arrow (and it changes with the size of dstRect), so fine-tuning the drawing isn't really possible as far as I can see. - [lockBadge drawInRect:NSRectFromCGRect(dstRect)]; - - [NSGraphicsContext restoreGraphicsState]; - - [_badges addObject:(id)layer]; - CGLayerRelease(layer); - } -} - -+ (CGLayerRef)lockBadgeWithSize:(NSSize)size; -{ - NSUInteger count = [_badges count]; - if (count == 0) - return NULL; - NSUInteger height = (NSUInteger)size.height; - NSUInteger i, iMax = sizeof(_sizes) / sizeof(NSUInteger); - for (i = 0; i < iMax; i++) - if (_sizes[i] >= height) break; - return (CGLayerRef)[_badges objectAtIndex:MIN(i, count - 1)]; -} - -@end Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVPDFIcon.m =================================================================== --- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVPDFIcon.m 2021-01-31 14:19:45 UTC (rev 25505) +++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVPDFIcon.m 2021-01-31 15:02:23 UTC (rev 25506) @@ -38,11 +38,18 @@ #import "FVPDFIcon.h" #import <pthread.h> -#import "FVLockBadge.h" #import "_FVMappedDataProvider.h" #import "_FVSplitSet.h" +@interface FVLockedPDFIcon : FVIcon { +@protected + CGImageRef _fullImage; + CGImageRef _thumbnail; +} ++ (id)sharedIcon; +@end + static pthread_mutex_t _releaseLock; static _FVSplitSet *_releaseableIcons = nil; static CGLayerRef _pageLayer = NULL; @@ -285,22 +292,6 @@ return document; } -// Draw a lock badge for encrypted PDF documents. If drawing the PDF page fails, pdf_error() logs "failed to create default crypt filter." to the console each time (and doesn't draw anything). Documents that just have restricted copy/print permissions will draw just fine (so shouldn't have the badge). -- (void)_drawLockBadgeInRect:(NSRect)pageRect ofContext:(CGContextRef)ctxt -{ - // square, unscaled rectangle since this is a badge icon - CGRect lockRect; - lockRect.size.width = MIN(pageRect.size.width, pageRect.size.height); - lockRect.size.height = lockRect.size.width; - lockRect.origin.x = CGRectGetMidX(pageRect) - 0.5 * lockRect.size.width; - lockRect.origin.y = CGRectGetMidY(pageRect) - 0.5 * lockRect.size.height; - - CGContextSaveGState(ctxt); - CGContextSetShadowWithColor(ctxt, CGSizeZero, 0, NULL); - CGContextDrawLayerInRect(ctxt, lockRect, [FVLockBadge lockBadgeWithSize:lockRect.size]); - CGContextRestoreGState(ctxt); -} - - (void)_drawPageInRect:(NSRect)pageRect ofContext:(CGContextRef)ctxt { if (_pdfPage == NULL || _isLocked) @@ -497,12 +488,17 @@ // no lock, so just draw the blank page and bail out [self _drawPlaceholderInRect:dstRect ofContext:context]; } + else if (_isLocked) + { + [self unlock]; + [[FVLockedPDFIcon sharedIcon] fastDrawInRect:dstRect ofContext:context]; + if (_drawsLinkBadge) + [self _badgeIconInRect:dstRect ofContext:context]; + } else if (NULL != _thumbnail) { NSRect drawRect = FVDrawingRectForRectInContext(dstRect, FVCGImageSize(_thumbnail), context); CGContextDrawImage(context, NSRectToCGRect(drawRect), _thumbnail); [self unlock]; - if (_isLocked) - [self _drawLockBadgeInRect:drawRect ofContext:context]; if (_drawsLinkBadge) [self _badgeIconInRect:dstRect ofContext:context]; } @@ -517,49 +513,48 @@ if (NO == [self tryLock]) { [self _drawPlaceholderInRect:dstRect ofContext:context]; } - else { + else if (_isLocked) { + [self unlock]; + [[FVLockedPDFIcon sharedIcon] drawInRect:dstRect ofContext:context]; + if (_drawsLinkBadge) + [self _badgeIconInRect:dstRect ofContext:context]; + } + else if (FVShouldDrawFullImageWithThumbnailSize(FVSizeForRectInContext(dstRect, context), _thumbnailSize) && NULL != _pdfDoc) { + // draw the PDF page for full size, if we have loaded the document - // draw the thumbnail if the rect is small or we have no PDF document (yet)...if we have neither, draw a blank page + // when we have a _pdfDoc, we should always have _fullSize set + NSRect drawRect = FVDrawingRectForRectInContext(dstRect, _fullSize, context); - if (FVShouldDrawFullImageWithThumbnailSize(FVSizeForRectInContext(dstRect, context), _thumbnailSize) && NULL != _pdfDoc) { - - // when we have a _pdfDoc, we should always have _fullSize set - NSRect drawRect = FVDrawingRectForRectInContext(dstRect, _fullSize, context); - - // don't clip, because the caller has a shadow set - CGContextDrawLayerInRect(context, NSRectToCGRect(drawRect), _pageLayer); + // don't clip, because the caller has a shadow set + CGContextDrawLayerInRect(context, NSRectToCGRect(drawRect), _pageLayer); - // get rid of any shadow, or we may draw a text shadow if the page is transparent - CGContextSaveGState(context); - CGContextSetShadowWithColor(context, CGSizeZero, 0, NULL); - - // draw the page if anything to draw - [self _drawPageInRect:drawRect ofContext:context]; - - [self unlock]; - if (_isLocked) - [self _drawLockBadgeInRect:drawRect ofContext:context]; - if (_drawsLinkBadge) - [self _badgeIconInRect:dstRect ofContext:context]; - - // restore shadow - CGContextRestoreGState(context); - } - else if (NULL != _thumbnail) { - NSRect drawRect = FVDrawingRectForRectInContext(dstRect, FVCGImageSize(_thumbnail), context); - CGContextDrawImage(context, NSRectToCGRect(drawRect), _thumbnail); - [self unlock]; - if (_isLocked) - [self _drawLockBadgeInRect:drawRect ofContext:context]; - if (_drawsLinkBadge) - [self _badgeIconInRect:dstRect ofContext:context]; - } - else { - // no doc and no thumbnail - [self unlock]; - [self _drawPlaceholderInRect:dstRect ofContext:context]; - } + // get rid of any shadow, or we may draw a text shadow if the page is transparent + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, CGSizeZero, 0, NULL); + + // draw the page if anything to draw + [self _drawPageInRect:drawRect ofContext:context]; + + [self unlock]; + if (_drawsLinkBadge) + [self _badgeIconInRect:dstRect ofContext:context]; + + // restore shadow + CGContextRestoreGState(context); } + else if (NULL != _thumbnail) { + // draw the thumbnail if the rect is small or we have no PDF document (yet) + NSRect drawRect = FVDrawingRectForRectInContext(dstRect, FVCGImageSize(_thumbnail), context); + CGContextDrawImage(context, NSRectToCGRect(drawRect), _thumbnail); + [self unlock]; + if (_drawsLinkBadge) + [self _badgeIconInRect:dstRect ofContext:context]; + } + else { + // no doc and no thumbnail + [self unlock]; + [self _drawPlaceholderInRect:dstRect ofContext:context]; + } } - (NSURL *)_fileURL { return _fileURL; } @@ -750,5 +745,65 @@ return pdfDoc; } +@end + +@implementation FVLockedPDFIcon + ++ (id)sharedIcon { + static id sharedIcon = nil; + if (sharedIcon == nil) + sharedIcon = [[self alloc] init]; + return sharedIcon; +} + +static CGImageRef __FVCreateImageWithIcon(NSImage *badgeIcon, NSSize size) +{ + FVBitmapContext *context = [FVBitmapContext bitmapContextWithSize:size]; + CGContextRef ctxt = [context graphicsPort]; + CGRect pageRect = CGRectZero; + pageRect.size = NSSizeToCGSize(size); + CGRect lockRect = CGRectZero; + lockRect.size.width = lockRect.size.height = MAX(size.width, size.height); + CGContextSetRGBFillColor(ctxt, 1.0, 1.0, 1.0, 1.0); + CGContextFillRect(ctxt, pageRect); + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[context graphicsContext]]; + [badgeIcon drawInRect:NSRectFromCGRect(lockRect)]; + [NSGraphicsContext restoreGraphicsState]; + return CGBitmapContextCreateImage(ctxt); +} + +- (id)init +{ + self = [super init]; + if (self) { + NSImage *lockBadge = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kLockedBadgeIcon)]; + NSSize size = NSMakeSize(FVDefaultPaperWidth * FVDefaultScale, FVDefaultPaperHeight * FVDefaultScale); + _fullImage = __FVCreateImageWithIcon(lockBadge, size); + __FVPDFIconLimitThumbnailSize(&size); + _thumbnail = __FVCreateImageWithIcon(lockBadge, size); + } + return self; +} + +- (void)dealloc +{ + CGImageRelease(_fullImage); + CGImageRelease(_thumbnail); + [super dealloc]; +} + +- (void)fastDrawInRect:(NSRect)dstRect ofContext:(CGContextRef)context +{ + [self _drawImage:_thumbnail inRect:dstRect ofContext:context]; +} + +- (void)drawInRect:(NSRect)dstRect ofContext:(CGContextRef)context +{ + if (FVShouldDrawFullImageWithThumbnailSize(FVSizeForRectInContext(dstRect, context), FVCGImageSize(_thumbnail))) + [self _drawImage:_fullImage inRect:dstRect ofContext:context]; + else + [self _drawImage:_thumbnail inRect:dstRect ofContext:context]; +} @end Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj =================================================================== --- trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj 2021-01-31 14:19:45 UTC (rev 25505) +++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FileView.xcodeproj/project.pbxproj 2021-01-31 15:02:23 UTC (rev 25506) @@ -52,8 +52,6 @@ CEA831140DC1FAB500B551D1 /* FVAccessibilityIconElement.h in Headers */ = {isa = PBXBuildFile; fileRef = CEA831120DC1FAB500B551D1 /* FVAccessibilityIconElement.h */; }; CEA831150DC1FAB500B551D1 /* FVAccessibilityIconElement.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA831130DC1FAB500B551D1 /* FVAccessibilityIconElement.m */; }; CEAD5FAD25B3A418002281E0 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEAD5FAC25B3A417002281E0 /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - CEC48F2325B090ED00A2B40A /* FVLockBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = CEC48F2125B090ED00A2B40A /* FVLockBadge.m */; }; - CEC48F2425B090ED00A2B40A /* FVLockBadge.h in Headers */ = {isa = PBXBuildFile; fileRef = CEC48F2225B090ED00A2B40A /* FVLockBadge.h */; }; CEC9932D1072B6C50089F20D /* FVPreviewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEC9932C1072B6C50089F20D /* FVPreviewer.xib */; }; CEFC19B10F693E8B00B2AEE6 /* FileView.h in Headers */ = {isa = PBXBuildFile; fileRef = CEFC19B00F693E8B00B2AEE6 /* FileView.h */; settings = {ATTRIBUTES = (Public, ); }; }; CEFC1CFC0F6AB84000B2AEE6 /* FVCacheFile.h in Headers */ = {isa = PBXBuildFile; fileRef = CEFC1CEF0F6AB84000B2AEE6 /* FVCacheFile.h */; }; @@ -204,8 +202,6 @@ CEA831130DC1FAB500B551D1 /* FVAccessibilityIconElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FVAccessibilityIconElement.m; sourceTree = "<group>"; }; CEAD5FAC25B3A417002281E0 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; CEAD5FAF25B3A504002281E0 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; - CEC48F2125B090ED00A2B40A /* FVLockBadge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FVLockBadge.m; sourceTree = "<group>"; }; - CEC48F2225B090ED00A2B40A /* FVLockBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FVLockBadge.h; sourceTree = "<group>"; }; CEC9932C1072B6C50089F20D /* FVPreviewer.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FVPreviewer.xib; sourceTree = "<group>"; }; CEFC19B00F693E8B00B2AEE6 /* FileView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileView.h; sourceTree = "<group>"; }; CEFC1CEF0F6AB84000B2AEE6 /* FVCacheFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FVCacheFile.h; sourceTree = "<group>"; }; @@ -420,8 +416,6 @@ CE05D4690D7B36DD0034C2A8 /* FVIcon_Private.m */, F9A2D3E60CCBE12B002F517B /* FVImageIcon.h */, F9A2D3E70CCBE12B002F517B /* FVImageIcon.m */, - CEC48F2225B090ED00A2B40A /* FVLockBadge.h */, - CEC48F2125B090ED00A2B40A /* FVLockBadge.m */, CE05D46A0D7B36DD0034C2A8 /* FVMIMEIcon.h */, CE05D46B0D7B36DD0034C2A8 /* FVMIMEIcon.m */, CE05D46C0D7B36DD0034C2A8 /* FVMovieIcon.h */, @@ -642,7 +636,6 @@ CEFC1CFE0F6AB84000B2AEE6 /* FVCGColorSpaceDescription.h in Headers */, CEFC1D000F6AB84000B2AEE6 /* FVCGImageDescription.h in Headers */, CEFC1D090F6AB8AD00B2AEE6 /* FVBitmapContext.h in Headers */, - CEC48F2425B090ED00A2B40A /* FVLockBadge.h in Headers */, CEFC1D0B0F6AB8AD00B2AEE6 /* FVCGImageUtilities.h in Headers */, CEFC1D0D0F6AB8AD00B2AEE6 /* FVImageBuffer.h in Headers */, CEFC1D190F6AB94F00B2AEE6 /* FVAllocator.h in Headers */, @@ -812,7 +805,6 @@ CEFC1D290F6ABA2300B2AEE6 /* FVAliasBadge.m in Sources */, CEFC1D2C0F6ABA2300B2AEE6 /* FVBaseIcon.m in Sources */, CEFC1F6E0F6AD4B300B2AEE6 /* FVQuickLookIcon.m in Sources */, - CEC48F2325B090ED00A2B40A /* FVLockBadge.m in Sources */, CE65FC5D0F72578D0089F9DC /* _FVMappedDataProvider.m in Sources */, CE65FC5F0F72578D0089F9DC /* _FVSplitSet.m in Sources */, CE07BD4310E789FE00686ACC /* _FVFullScreenContentView.m in Sources */, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ Bibdesk-commit mailing list Bibdesk-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bibdesk-commit