123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- //
- // KMSnapshotWindowController.swift
- // PDF Master
- //
- // Created by tangchao on 2023/12/12.
- //
- import Cocoa
- class KMSnapshotWindowController: NSWindowController {
-
- /*
- extern NSString *SKSnapshotCurrentSetupKey;
- @class SKSnapshotPDFView, PDFDocument, PDFPage;
- @protocol SKSnapshotWindowControllerDelegate;
- @interface SKSnapshotWindowController : NSWindowController <NSWindowDelegate> {
- SKSnapshotPDFView* pdfView;
- NSImage *thumbnail;
- id <SKSnapshotWindowControllerDelegate> delegate;
- NSString *pageLabel;
- NSImage *windowImage;
- NSString *string;
- BOOL hasWindow;
- BOOL forceOnTop;
- BOOL animating;
- }
- @property (nonatomic, retain) IBOutlet SKSnapshotPDFView *pdfView;
- @property (nonatomic, assign) id <SKSnapshotWindowControllerDelegate> delegate;
- @property (nonatomic, retain) NSImage *thumbnail;
- @property (nonatomic, readonly) NSUInteger pageIndex;
- @property (nonatomic, readonly, copy) NSString *pageLabel;
- @property (nonatomic, copy) NSString *string;
- @property (nonatomic, readonly) BOOL hasWindow;
- @property (nonatomic, readonly) NSDictionary *pageAndWindow;
- @property (nonatomic, readonly) NSDictionary *currentSetup;
- @property (nonatomic) BOOL forceOnTop;
- @property (nonatomic, readonly) NSAttributedString *thumbnailAttachment, *thumbnail512Attachment, *thumbnail256Attachment, *thumbnail128Attachment, *thumbnail64Attachment, *thumbnail32Attachment;
- - (void)setPdfDocument:(PDFDocument *)pdfDocument goToPageNumber:(NSInteger)pageNum rect:(NSRect)rect scaleFactor:(CGFloat)factor autoFits:(BOOL)autoFits;
- - (void)setPdfDocument:(PDFDocument *)pdfDocument setup:(NSDictionary *)setup;
- - (BOOL)isPageVisible:(PDFPage *)page;
- - (void)redisplay;
- - (NSImage *)thumbnailWithSize:(CGFloat)size;
- - (NSAttributedString *)thumbnailAttachmentWithSize:(CGFloat)size;
- - (void)miniaturize;
- - (void)deminiaturize;
- - (void)handlePageChangedNotification:(NSNotification *)notification;
- - (void)handleDocumentDidUnlockNotification:(NSNotification *)notification;
- - (void)handlePDFViewFrameChangedNotification:(NSNotification *)notification;
- - (void)handleViewChangedNotification:(NSNotification *)notification;
- - (void)handleDidAddRemoveAnnotationNotification:(NSNotification *)notification;
- - (void)handleDidMoveAnnotationNotification:(NSNotification *)notification;
- - (void)setNeedsDisplayInRect:(NSRect)rect ofPage:(PDFPage *)page;
- - (void)setNeedsDisplayForAnnotation:(PDFAnnotation *)annotation onPage:(PDFPage *)page;
- @end
- @protocol SKSnapshotWindowControllerDelegate <NSObject>
- @optional
- - (void)snapshotControllerDidFinishSetup:(SKSnapshotWindowController *)controller;
- - (void)snapshotControllerWillClose:(SKSnapshotWindowController *)controller;
- - (void)snapshotControllerDidChange:(SKSnapshotWindowController *)controller;
- - (NSRect)snapshotController:(SKSnapshotWindowController *)controller miniaturizedRect:(BOOL)isMiniaturize;
- @end
- */
-
- /*
- #define EM_DASH_CHARACTER (unichar)0x2014
- #define SMALL_DELAY 0.1
- #define RESIZE_TIME_FACTOR 0.6
- NSString *SKSnapshotCurrentSetupKey = @"currentSetup";
- #define PAGE_KEY @"page"
- #define RECT_KEY @"rect"
- #define SCALEFACTOR_KEY @"scaleFactor"
- #define AUTOFITS_KEY @"autoFits"
- #define WINDOWFRAME_KEY @"windowFrame"
- #define HASWINDOW_KEY @"hasWindow"
- #define PAGELABEL_KEY @"pageLabel"
- #define PAGEANDWINDOW_KEY @"pageAndWindow"
- #define SKSnapshotWindowFrameAutosaveName @"SKSnapshotWindow"
- #define SKSnapshotViewChangedNotification @"SKSnapshotViewChangedNotification"
- static char SKSnaphotWindowDefaultsObservationContext;
- @interface SKSnapshotWindowController ()
- @property (nonatomic, copy) NSString *pageLabel;
- @property (nonatomic) BOOL hasWindow;
- @end
- */
- override func windowDidLoad() {
- super.windowDidLoad()
-
- // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
- }
-
- /*
- + (NSSet *)keyPathsForValuesAffectingPageAndWindow {
- return [NSSet setWithObjects:PAGELABEL_KEY, HASWINDOW_KEY, nil];
- }
- - (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver: self];
- delegate = nil;
- SKDESTROY(thumbnail);
- SKDESTROY(pageLabel);
- SKDESTROY(pdfView);
- SKDESTROY(windowImage);
- SKDESTROY(string);
- [super dealloc];
- }
- - (NSString *)windowNibName {
- return @"SnapshotWindow";
- }
- - (void)updateWindowLevel {
- BOOL onTop = forceOnTop || [[NSUserDefaults standardUserDefaults] boolForKey:SKSnapshotsOnTopKey];
- [[self window] setLevel:onTop ? NSFloatingWindowLevel : NSNormalWindowLevel];
- [[self window] setHidesOnDeactivate:onTop];
- }
- - (void)windowDidLoad {
- if ([NSWindow instancesRespondToSelector:@selector(setTabbingMode:)])
- [[self window] setTabbingMode:NSWindowTabbingModeDisallowed];
- if ([NSWindow instancesRespondToSelector:@selector(toggleFullScreen:)])
- [[self window] setCollectionBehavior:[[self window] collectionBehavior] | NSWindowCollectionBehaviorFullScreenAuxiliary];
- if ([[self window] respondsToSelector:@selector(contentLayoutRect)]) {
- [[self window] setStyleMask:[[self window] styleMask] | NSFullSizeContentViewWindowMask];
- [pdfView setFrame:[[self window] contentLayoutRect]];
- }
- [self updateWindowLevel];
- [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeys:[NSArray arrayWithObjects:SKSnapshotsOnTopKey, SKShouldAntiAliasKey, SKGreekingThresholdKey, SKBackgroundColorKey, SKPageBackgroundColorKey, nil] context:&SKSnaphotWindowDefaultsObservationContext];
- // the window is initialially exposed. The windowDidExpose notification is useless, it has nothing to do with showing the window
- [self setHasWindow:YES];
- }
- // these should never be reached, but just to be sure
- - (void)windowDidMiniaturize:(NSNotification *)notification {
- [[self window] orderOut:nil];
- [self setHasWindow:NO];
- }
- - (void)windowDidDeminiaturize:(NSNotification *)notification {
- [self updateWindowLevel];
- [self setHasWindow:YES];
- }
- - (NSString *)windowTitleForDocumentDisplayName:(NSString *)displayName {
- return [NSString stringWithFormat:@"%@ %C %@", displayName, EM_DASH_CHARACTER, [NSString stringWithFormat:NSLocalizedString(@"Page %@", @""), [self pageLabel]]];
- }
- - (void)setNeedsDisplayInRect:(NSRect)rect ofPage:(PDFPage *)page {
- NSRect aRect = [pdfView convertRect:rect fromPage:page];
- CGFloat scale = [pdfView scaleFactor];
- CGFloat maxX = ceil(NSMaxX(aRect) + scale);
- CGFloat maxY = ceil(NSMaxY(aRect) + scale);
- CGFloat minX = floor(NSMinX(aRect) - scale);
- CGFloat minY = floor(NSMinY(aRect) - scale);
-
- aRect = NSIntersectionRect([pdfView bounds], NSMakeRect(minX, minY, maxX - minX, maxY - minY));
- if (NSIsEmptyRect(aRect) == NO)
- [pdfView setNeedsDisplayInRect:aRect];
- }
- - (void)setNeedsDisplayForAnnotation:(PDFAnnotation *)annotation onPage:(PDFPage *)page {
- [self setNeedsDisplayInRect:[annotation displayRect] ofPage:page];
- }
- - (void)redisplay {
- [pdfView requiresDisplay];
- }
- - (void)updateString {
- NSMutableString *mutableString = [NSMutableString string];
- NSView *clipView = [[pdfView scrollView] contentView];
- NSRect rect = [clipView convertRect:[clipView visibleRect] toView:pdfView];
-
- for (PDFPage *page in [pdfView displayedPages]) {
- PDFSelection *sel = [page selectionForRect:[pdfView convertRect:rect toPage:page]];
- if ([sel hasCharacters]) {
- if ([mutableString length] > 0)
- [mutableString appendString:@"\n"];
- [mutableString appendString:[sel string]];
- }
- }
- [self setString:mutableString];
- }
- - (void)handlePageChangedNotification:(NSNotification *)notification {
- [self setPageLabel:[[pdfView currentPage] displayLabel]];
- [self handlePDFViewFrameChangedNotification:nil];
- }
- - (void)handleDocumentDidUnlockNotification:(NSNotification *)notification {
- [self setPageLabel:[[pdfView currentPage] displayLabel]];
- [self handlePDFViewFrameChangedNotification:nil];
- }
- - (void)handlePDFViewFrameChangedNotification:(NSNotification *)notification {
- if ([[self delegate] respondsToSelector:@selector(snapshotControllerDidChange:)]) {
- NSNotification *note = [NSNotification notificationWithName:SKSnapshotViewChangedNotification object:self];
- [[NSNotificationQueue defaultQueue] enqueueNotification:note postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];
- }
- }
- - (void)handleViewChangedNotification:(NSNotification *)notification {
- [self updateString];
- if ([[self delegate] respondsToSelector:@selector(snapshotControllerDidChange:)])
- [[self delegate] snapshotControllerDidChange:self];
- }
- - (void)handleDidAddRemoveAnnotationNotification:(NSNotification *)notification {
- PDFAnnotation *annotation = [[notification userInfo] objectForKey:SKPDFViewAnnotationKey];
- PDFPage *page = [[notification userInfo] objectForKey:SKPDFViewPageKey];
- if ([[page document] isEqual:[pdfView document]] && [self isPageVisible:page])
- [self setNeedsDisplayForAnnotation:annotation onPage:page];
- }
- - (void)handleDidMoveAnnotationNotification:(NSNotification *)notification {
- PDFAnnotation *annotation = [[notification userInfo] objectForKey:SKPDFViewAnnotationKey];
- PDFPage *oldPage = [[notification userInfo] objectForKey:SKPDFViewOldPageKey];
- PDFPage *newPage = [[notification userInfo] objectForKey:SKPDFViewNewPageKey];
- if ([[newPage document] isEqual:[pdfView document]]) {
- if ([self isPageVisible:oldPage])
- [self setNeedsDisplayForAnnotation:annotation onPage:oldPage];
- if ([self isPageVisible:newPage])
- [self setNeedsDisplayForAnnotation:annotation onPage:newPage];
- }
- }
- - (void)windowWillClose:(NSNotification *)notification {
- @try { [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeys:[NSArray arrayWithObjects:SKSnapshotsOnTopKey, SKShouldAntiAliasKey, SKGreekingThresholdKey, SKBackgroundColorKey, SKPageBackgroundColorKey, nil]]; }
- @catch (id e) {}
- if ([[self delegate] respondsToSelector:@selector(snapshotControllerWillClose:)])
- [[self delegate] snapshotControllerWillClose:self];
- [self setDelegate:nil];
- // Yosemite and El Capitan have a retain cycle when we leave the PDFView with a document
- if (RUNNING_AFTER(10_9) && RUNNING_BEFORE(10_12))
- [pdfView setDocument:nil];
- }
- - (void)notifiyDidFinishSetup {
- [[self delegate] snapshotControllerDidFinishSetup:self];
- }
- - (void)goToRect:(NSValue *)rectValue {
- [pdfView goToRect:[rectValue rectValue] onPage:[pdfView currentPage]];
- [pdfView resetHistory];
-
- [self updateString];
-
- [[self window] makeFirstResponder:pdfView];
-
- [self handlePageChangedNotification:nil];
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePageChangedNotification:)
- name:PDFViewPageChangedNotification object:pdfView];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDocumentDidUnlockNotification:)
- name:PDFDocumentDidUnlockNotification object:[pdfView document]];
-
- NSView *clipView = [[[pdfView documentView] enclosingScrollView] contentView];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:)
- name:NSViewFrameDidChangeNotification object:clipView];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:)
- name:NSViewBoundsDidChangeNotification object:clipView];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleViewChangedNotification:)
- name:SKSnapshotViewChangedNotification object:self];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDidAddRemoveAnnotationNotification:)
- name:SKPDFViewDidAddAnnotationNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDidAddRemoveAnnotationNotification:)
- name:SKPDFViewDidRemoveAnnotationNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDidMoveAnnotationNotification:)
- name:SKPDFViewDidMoveAnnotationNotification object:nil];
- if ([[self delegate] respondsToSelector:@selector(snapshotControllerDidFinishSetup:)])
- [self performSelector:@selector(notifiyDidFinishSetup) withObject:nil afterDelay:SMALL_DELAY];
-
- if ([self hasWindow])
- [self showWindow:nil];
- }
- - (void)setPdfDocument:(PDFDocument *)pdfDocument goToPageNumber:(NSInteger)pageNum rect:(NSRect)rect scaleFactor:(CGFloat)factor autoFits:(BOOL)autoFits {
- NSWindow *window = [self window];
-
- [pdfView setScaleFactor:factor];
- [pdfView setAutoScales:NO];
- [pdfView setDisplaysPageBreaks:NO];
- [pdfView setDisplayBox:kPDFDisplayBoxCropBox];
- [pdfView setShouldAntiAlias:[[NSUserDefaults standardUserDefaults] floatForKey:SKShouldAntiAliasKey]];
- [pdfView setGreekingThreshold:[[NSUserDefaults standardUserDefaults] floatForKey:SKGreekingThresholdKey]];
- [pdfView setBackgroundColor:[[NSUserDefaults standardUserDefaults] colorForKey:SKBackgroundColorKey]];
- [pdfView applyDefaultPageBackgroundColor];
- [pdfView applyDefaultInterpolationQuality];
- [pdfView setDocument:pdfDocument];
-
- [self setWindowFrameAutosaveNameOrCascade:SKSnapshotWindowFrameAutosaveName];
-
- NSView *controlView = [pdfView scalePopUpButton];
- NSRect controlFrame, frame;
- NSDivideRect([pdfView frame], &controlFrame, &frame, NSHeight([controlView frame]), NSMinYEdge);
- controlFrame.size.width = NSWidth([controlView frame]);
- [controlView setFrame:controlFrame];
- [controlView setAutoresizingMask:NSViewMaxXMargin | NSViewMaxYMargin];
- [[window contentView] addSubview:controlView];
- [pdfView setFrame:frame];
- [window setBackgroundColor:[NSColor colorWithCalibratedWhite:0.97 alpha:1.0]];
-
- PDFPage *page = [pdfDocument pageAtIndex:pageNum];
- frame = [pdfView convertRect:rect fromPage:page];
- frame = [pdfView convertRect:frame toView:nil];
- frame.size.height += NSHeight(controlFrame);
- frame = [NSWindow frameRectForContentRect:frame styleMask:[window styleMask] & ~NSWindowStyleMaskFullSizeContentView];
- frame.origin.x = NSMinX([window frame]);
- frame.origin.y = NSMaxY([window frame]) - NSHeight(frame);
- [[self window] setFrame:NSIntegralRect(frame) display:NO animate:NO];
-
- [pdfView goToPage:page];
-
- if (autoFits)
- [pdfView setAutoFits:autoFits];
-
- // Delayed to allow PDFView to finish its bookkeeping
- // fixes bug of apparently ignoring the point but getting the page right.
- [self performSelector:@selector(goToRect:) withObject:[NSValue valueWithRect:rect] afterDelay:SMALL_DELAY];
- }
- - (void)setPdfDocument:(PDFDocument *)pdfDocument setup:(NSDictionary *)setup {
- [self setPdfDocument:pdfDocument
- goToPageNumber:[[setup objectForKey:PAGE_KEY] unsignedIntegerValue]
- rect:NSRectFromString([setup objectForKey:RECT_KEY])
- scaleFactor:[[setup objectForKey:SCALEFACTOR_KEY] doubleValue]
- autoFits:[[setup objectForKey:AUTOFITS_KEY] boolValue]];
-
- [self setHasWindow:[[setup objectForKey:HASWINDOW_KEY] boolValue]];
- if ([setup objectForKey:WINDOWFRAME_KEY])
- [[self window] setFrame:NSRectFromString([setup objectForKey:WINDOWFRAME_KEY]) display:NO];
- }
- - (BOOL)isPageVisible:(PDFPage *)page {
- return [[page document] isEqual:[pdfView document]] && NSLocationInRange([page pageIndex], [pdfView displayedPageIndexRange]);
- }
- #pragma mark Acessors
- - (NSRect)bounds {
- NSView *clipView = [[[pdfView documentView] enclosingScrollView] contentView];
- return [pdfView convertRect:[pdfView convertRect:[clipView bounds] fromView:clipView] toPage:[pdfView currentPage]];
- }
- - (NSUInteger)pageIndex {
- return [[pdfView currentPage] pageIndex];
- }
- - (void)setPageLabel:(NSString *)newPageLabel {
- if (pageLabel != newPageLabel) {
- [pageLabel release];
- pageLabel = [newPageLabel retain];
- [self synchronizeWindowTitleWithDocumentName];
- }
- }
- - (NSDictionary *)pageAndWindow {
- return [NSDictionary dictionaryWithObjectsAndKeys:[self pageLabel], SKSnapshotPageCellLabelKey, [NSNumber numberWithBool:[self hasWindow]], SKSnapshotPageCellHasWindowKey, nil];
- }
- - (void)setForceOnTop:(BOOL)flag {
- forceOnTop = flag;
- if ([[self window] isVisible])
- [self updateWindowLevel];
- }
- - (NSDictionary *)currentSetup {
- NSView *clipView = [[[pdfView documentView] enclosingScrollView] contentView];
- NSRect rect = [pdfView convertRect:[pdfView convertRect:[clipView bounds] fromView:clipView] toPage:[pdfView currentPage]];
- BOOL autoFits = [pdfView autoFits];
- return [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:[self pageIndex]], PAGE_KEY, NSStringFromRect(rect), RECT_KEY, [NSNumber numberWithDouble:[pdfView scaleFactor]], SCALEFACTOR_KEY, [NSNumber numberWithBool:autoFits], AUTOFITS_KEY, [NSNumber numberWithBool:[[self window] isVisible]], HASWINDOW_KEY, NSStringFromRect([[self window] frame]), WINDOWFRAME_KEY, nil];
- }
- #pragma mark Actions
- - (IBAction)doGoToNextPage:(id)sender {
- [pdfView goToNextPage:sender];
- }
- - (IBAction)doGoToPreviousPage:(id)sender {
- [pdfView goToPreviousPage:sender];
- }
- - (IBAction)doGoToFirstPage:(id)sender {
- [pdfView goToFirstPage:sender];
- }
- - (IBAction)doGoToLastPage:(id)sender {
- [pdfView goToLastPage:sender];
- }
- - (IBAction)doGoBack:(id)sender {
- [pdfView goBack:sender];
- }
- - (IBAction)doGoForward:(id)sender {
- [pdfView goForward:sender];
- }
- - (IBAction)doZoomIn:(id)sender {
- [pdfView zoomIn:sender];
- }
- - (IBAction)doZoomOut:(id)sender {
- [pdfView zoomOut:sender];
- }
- - (IBAction)doZoomToPhysicalSize:(id)sender {
- [pdfView setPhysicalScaleFactor:1.0];
- }
- - (IBAction)doZoomToActualSize:(id)sender {
- [pdfView setScaleFactor:1.0];
- }
- - (IBAction)toggleAutoScale:(id)sender {
- [pdfView setAutoFits:[pdfView autoFits] == NO];
- }
- - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
- SEL action = [menuItem action];
- if (action == @selector(doGoToNextPage:)) {
- return [pdfView canGoToNextPage];
- } else if (action == @selector(doGoToPreviousPage:)) {
- return [pdfView canGoToPreviousPage];
- } else if (action == @selector(doGoToFirstPage:)) {
- return [pdfView canGoToFirstPage];
- } else if (action == @selector(doGoToLastPage:)) {
- return [pdfView canGoToLastPage];
- } else if (action == @selector(doGoBack:)) {
- return [pdfView canGoBack];
- } else if (action == @selector(doGoForward:)) {
- return [pdfView canGoForward];
- } else if (action == @selector(doZoomIn:)) {
- return [pdfView canZoomIn];
- } else if (action == @selector(doZoomOut:)) {
- return [pdfView canZoomOut];
- } else if (action == @selector(doZoomToActualSize:)) {
- return fabs([pdfView scaleFactor] - 1.0 ) > 0.01;
- } else if (action == @selector(doZoomToPhysicalSize:)) {
- return fabs([pdfView physicalScaleFactor] - 1.0 ) > 0.01;
- } else if (action == @selector(toggleAutoScale:)) {
- [menuItem setState:[pdfView autoFits] ? NSOnState : NSOffState];
- return YES;
- }
- return YES;
- }
- #pragma mark Thumbnails
- - (NSImage *)thumbnailWithSize:(CGFloat)size {
- NSView *clipView = [[[pdfView documentView] enclosingScrollView] contentView];
- NSRect bounds = [pdfView convertRect:[clipView bounds] fromView:clipView];
- if (CGRectEqualToRect(CGRectZero, bounds) || CGRectIsNull(bounds)) {
- return nil;
- }
- NSBitmapImageRep *imageRep = [pdfView bitmapImageRepForCachingDisplayInRect:bounds];
- NSAffineTransform *transform = nil;
- NSSize thumbnailSize = bounds.size;
- CGFloat shadowBlurRadius = 0.0;
- CGFloat shadowOffset = 0.0;
- NSImage *image;
-
- [pdfView cacheDisplayInRect:bounds toBitmapImageRep:imageRep];
-
- bounds.origin = NSZeroPoint;
-
- if (size > 0.0) {
- shadowBlurRadius = round(size / 32.0);
- shadowOffset = -ceil(shadowBlurRadius * 0.75);
- if (NSHeight(bounds) > NSWidth(bounds))
- thumbnailSize = NSMakeSize(round((size - 2.0 * shadowBlurRadius) * NSWidth(bounds) / NSHeight(bounds) + 2.0 * shadowBlurRadius), size);
- else
- thumbnailSize = NSMakeSize(size, round((size - 2.0 * shadowBlurRadius) * NSHeight(bounds) / NSWidth(bounds) + 2.0 * shadowBlurRadius));
- transform = [NSAffineTransform transform];
- [transform translateXBy:shadowBlurRadius yBy:shadowBlurRadius - shadowOffset];
- [transform scaleXBy:(thumbnailSize.width - 2.0 * shadowBlurRadius) / NSWidth(bounds) yBy:(thumbnailSize.height - 2.0 * shadowBlurRadius) / NSHeight(bounds)];
- }
-
- if (CGSizeEqualToSize(CGSizeZero, thumbnailSize)) {
- return nil;
- }
- image = [[[NSImage alloc] initWithSize:thumbnailSize] autorelease];
-
- if (CGSizeEqualToSize(CGSizeZero, image.size)) {
- return nil;
- }
- [image lockFocus];
- [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
- [transform concat];
- [NSGraphicsContext saveGraphicsState];
- [[PDFView defaultPageBackgroundColor] set];
- if (shadowBlurRadius > 0.0)
- [NSShadow setShadowWithColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.5] blurRadius:shadowBlurRadius yOffset:shadowOffset];
- NSRectFill(bounds);
- [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationDefault];
- [NSGraphicsContext restoreGraphicsState];
- [imageRep drawInRect:bounds];
- [image unlockFocus];
-
- return image;
- }
- - (NSAttributedString *)thumbnailAttachmentWithSize:(CGFloat)size {
- NSImage *image = [self thumbnailWithSize:size];
-
- NSFileWrapper *wrapper = [[NSFileWrapper alloc] initRegularFileWithContents:[image TIFFRepresentation]];
- NSString *filename = [NSString stringWithFormat:@"snapshot_page_%lu.tiff",(unsigned long)( [self pageIndex] + 1)];
- [wrapper setFilename:filename];
- [wrapper setPreferredFilename:filename];
- NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:wrapper];
- [wrapper release];
- NSAttributedString *attrString = [NSAttributedString attributedStringWithAttachment:attachment];
- [attachment release];
-
- return attrString;
- }
- - (NSAttributedString *)thumbnailAttachment {
- return [self thumbnailAttachmentWithSize:0.0];
- }
- - (NSAttributedString *)thumbnail512Attachment {
- return [self thumbnailAttachmentWithSize:512.0];
- }
- - (NSAttributedString *)thumbnail256Attachment {
- return [self thumbnailAttachmentWithSize:256.0];
- }
- - (NSAttributedString *)thumbnail128Attachment {
- return [self thumbnailAttachmentWithSize:128.0];
- }
- - (NSAttributedString *)thumbnail64Attachment {
- return [self thumbnailAttachmentWithSize:64.0];
- }
- - (NSAttributedString *)thumbnail32Attachment {
- return [self thumbnailAttachmentWithSize:32.0];
- }
- #pragma mark Miniaturize / Deminiaturize
- - (NSRect)miniaturizedRectForDockingRect:(NSRect)dockRect {
- NSView *clipView = [[[pdfView documentView] enclosingScrollView] contentView];
- NSRect sourceRect = [clipView convertRect:[clipView bounds] toView:nil];
- NSRect targetRect;
- NSSize windowSize = [[self window] frame].size;
- NSSize thumbSize = [thumbnail size];
- CGFloat thumbRatio = thumbSize.height / thumbSize.width;
- CGFloat dockRatio = NSHeight(dockRect) / NSWidth(dockRect);
- CGFloat scaleFactor;
- CGFloat shadowRadius = round(fmax(thumbSize.width, thumbSize.height) / 32.0);
- CGFloat shadowOffset = ceil(0.75 * shadowRadius);
-
- if (thumbRatio > dockRatio) {
- targetRect = NSInsetRect(dockRect, 0.5 * NSWidth(dockRect) * (1.0 - dockRatio / thumbRatio), 0.0);
- scaleFactor = NSHeight(targetRect) / thumbSize.height;
- } else {
- targetRect = NSInsetRect(dockRect, 0.0, 0.5 * NSHeight(dockRect) * (1.0 - thumbRatio / dockRatio));
- scaleFactor = NSWidth(targetRect) / thumbSize.width;
- }
- shadowRadius *= scaleFactor;
- shadowOffset *= scaleFactor;
- targetRect = NSOffsetRect(NSInsetRect(targetRect, shadowRadius, shadowRadius), 0.0, shadowOffset);
- scaleFactor = thumbRatio > dockRatio ? NSHeight(targetRect) / NSHeight(sourceRect) : NSWidth(targetRect) / NSWidth(sourceRect);
-
- return NSMakeRect(NSMinX(targetRect) - scaleFactor * NSMinX(sourceRect), NSMinY(targetRect) - scaleFactor * NSMinY(sourceRect), scaleFactor * windowSize.width, scaleFactor * windowSize.height);
- }
- - (void)miniaturizeWindowFromRect:(NSRect)startRect toRect:(NSRect)endRect {
- if (windowImage == nil)
- windowImage = [[(SKSnapshotWindow *)[self window] windowImage] retain];
-
- SKAnimatedBorderlessWindow *miniaturizeWindow = [[SKAnimatedBorderlessWindow alloc] initWithContentRect:startRect];
- [miniaturizeWindow setLevel:NSFloatingWindowLevel];
- [miniaturizeWindow setBackgroundImage:windowImage];
-
- [miniaturizeWindow orderFront:nil];
-
- animating = YES;
-
- [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
- [context setDuration:RESIZE_TIME_FACTOR * [miniaturizeWindow animationResizeTime:endRect]];
- [[miniaturizeWindow animator] setFrame:endRect display:YES];
- }
- completionHandler:^{
- if ([self hasWindow]) {
- if ([[self window] respondsToSelector:@selector(setAnimationBehavior:)])
- [[self window] setAnimationBehavior:NSWindowAnimationBehaviorNone];
- [[self window] orderFront:nil];
- [self updateWindowLevel];
- if ([[self window] respondsToSelector:@selector(setAnimationBehavior:)])
- [[self window] setAnimationBehavior:NSWindowAnimationBehaviorDefault];
- }
- [miniaturizeWindow orderOut:nil];
- animating = NO;
- }];
-
- [miniaturizeWindow release];
- }
- - (void)miniaturize {
- if (animating)
- return;
- if ([[self delegate] respondsToSelector:@selector(snapshotController:miniaturizedRect:)]) {
- NSRect dockRect = [[self delegate] snapshotController:self miniaturizedRect:YES];
- NSRect startRect = [[self window] frame];
- NSRect endRect = [self miniaturizedRectForDockingRect:dockRect];
-
- [self miniaturizeWindowFromRect:startRect toRect:endRect];
-
- if ([[self window] respondsToSelector:@selector(setAnimationBehavior:)])
- [[self window] setAnimationBehavior:NSWindowAnimationBehaviorNone];
- }
- [[self window] orderOut:nil];
- if ([[self window] respondsToSelector:@selector(setAnimationBehavior:)])
- [[self window] setAnimationBehavior:NSWindowAnimationBehaviorDefault];
- [self setHasWindow:NO];
- }
- - (void)deminiaturize {
- if (animating)
- return;
- if ([[self delegate] respondsToSelector:@selector(snapshotController:miniaturizedRect:)]) {
- NSRect dockRect = [[self delegate] snapshotController:self miniaturizedRect:NO];
- NSRect endRect = [[self window] frame];
- NSRect startRect = [self miniaturizedRectForDockingRect:dockRect];
-
- [self miniaturizeWindowFromRect:startRect toRect:endRect];
-
- SKDESTROY(windowImage);
- } else {
- [self showWindow:self];
- }
- [self setHasWindow:YES];
- }
- #pragma mark KVO
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
- if (context == &SKSnaphotWindowDefaultsObservationContext) {
- NSString *key = [keyPath substringFromIndex:7];
- if ([key isEqualToString:SKSnapshotsOnTopKey]) {
- if ([[self window] isVisible])
- [self updateWindowLevel];
- } else if ([key isEqualToString:SKShouldAntiAliasKey]) {
- [pdfView setShouldAntiAlias:[[NSUserDefaults standardUserDefaults] boolForKey:SKShouldAntiAliasKey]];
- [pdfView applyDefaultInterpolationQuality];
- } else if ([key isEqualToString:SKGreekingThresholdKey]) {
- [pdfView setGreekingThreshold:[[NSUserDefaults standardUserDefaults] floatForKey:SKGreekingThresholdKey]];
- } else if ([key isEqualToString:SKBackgroundColorKey]) {
- [pdfView setBackgroundColor:[[NSUserDefaults standardUserDefaults] colorForKey:SKBackgroundColorKey]];
- } else if ([key isEqualToString:SKPageBackgroundColorKey]) {
- [pdfView applyDefaultPageBackgroundColor];
- }
- } else {
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
- }
- }
- */
- }
|