Revision: 14315
http://sourceforge.net/p/skim-app/code/14315
Author: hofman
Date: 2024-06-08 17:30:41 +0000 (Sat, 08 Jun 2024)
Log Message:
-----------
Update snapshot thumbnails async on thumbnail queue. For this to work create an
intermediate object to hold the page configuration for the snapshot, as drqing
using the pdfView is not thread safe. When snapshots are not shown, initialize
snapshots with a placeholder thumbnail and update on a low priority queue.
Modified Paths:
--------------
trunk/SKMainWindowController.h
trunk/SKMainWindowController.m
trunk/SKSnapshotWindowController.h
trunk/SKSnapshotWindowController.m
Modified: trunk/SKMainWindowController.h
===================================================================
--- trunk/SKMainWindowController.h 2024-06-08 14:37:38 UTC (rev 14314)
+++ trunk/SKMainWindowController.h 2024-06-08 17:30:41 UTC (rev 14315)
@@ -119,8 +119,6 @@
NSMapTable<PDFAnnotation *, id> *widgetValues;
NSMutableArray<SKSnapshotWindowController *> *snapshots;
- NSMutableArray<SKSnapshotWindowController *> *dirtySnapshots;
- NSTimer *snapshotTimer;
CGFloat snapshotThumbnailSize;
NSArray<NSString *> *tags;
@@ -318,7 +316,6 @@
- (void)resetSnapshotSizeIfNeeded;
- (void)snapshotNeedsUpdate:(SKSnapshotWindowController *)dirstySnapshot;
- (void)allSnapshotsNeedUpdate;
-- (void)updateSnapshotsIfNeeded;
- (void)setPdfDocument:(nullable PDFDocument *)pdfDocument
addAnnotationsFromDictionaries:(nullable NSArray<NSDictionary<NSString *, id>
*> *)noteDicts;
- (void)addAnnotationsFromDictionaries:(NSArray<NSDictionary<NSString *, id>
*> *)noteDicts removeAnnotations:(nullable NSArray<PDFAnnotation *>
*)notesToRemove;
Modified: trunk/SKMainWindowController.m
===================================================================
--- trunk/SKMainWindowController.m 2024-06-08 14:37:38 UTC (rev 14314)
+++ trunk/SKMainWindowController.m 2024-06-08 17:30:41 UTC (rev 14315)
@@ -246,7 +246,6 @@
tags = [[NSArray alloc] init];
rating = 0.0;
snapshots = [[NSMutableArray alloc] init];
- dirtySnapshots = [[NSMutableArray alloc] init];
pageLabels = [[NSArray alloc] init];
lastViewedPages = [[NSPointerArray alloc]
initWithOptions:NSPointerFunctionsOpaqueMemory |
NSPointerFunctionsIntegerPersonality];
rowHeights = [[NSMapTable alloc]
initWithKeyOptions:NSPointerFunctionsStrongMemory |
NSPointerFunctionsObjectPersonality valueOptions:NSPointerFunctionsOpaqueMemory
| NSPointerFunctionsIntegerPersonality capacity:0];
@@ -1354,7 +1353,6 @@
}
- (void)removeObjectFromSnapshotsAtIndex:(NSUInteger)theIndex {
- [dirtySnapshots removeObject:[snapshots objectAtIndex:theIndex]];
[snapshots removeObjectAtIndex:theIndex];
}
@@ -1363,8 +1361,6 @@
NSIndexSet *indexes = [NSIndexSet
indexSetWithIndexesInRange:NSMakeRange(0, [snapshots count])];
[self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes
forKey:SNAPSHOTS_KEY];
- [dirtySnapshots removeAllObjects];
-
[snapshots removeAllObjects];
[self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes
forKey:SNAPSHOTS_KEY];
@@ -1470,7 +1466,6 @@
[rightSideController
replaceSideView:rightSideController.noteOutlineView.enclosingScrollView
animate:animate];
} else {
[rightSideController
replaceSideView:rightSideController.snapshotTableView.enclosingScrollView
animate:animate];
- [self updateSnapshotsIfNeeded];
}
}
@@ -2327,8 +2322,14 @@
if (openType == SKSnapshotOpenPreview)
return;
- NSImage *image = [controller thumbnailWithSize:snapshotCacheSize
scale:[[self window] backingScaleFactor]];
+ NSImage *image;
+ BOOL isVisible = [self rightSidePaneIsOpen] && [self rightSidePaneState]
== SKSidePaneStateSnapshot;
+ if (isVisible || openType == SKSnapshotOpenFromSetup)
+ image = [[controller currentConfiguration]
thumbnailWithSize:snapshotCacheSize scale:[[self window] backingScaleFactor]];
+ else
+ image = [controller placeholderThumbnailWithSize:snapshotCacheSize
scale:[[self window] backingScaleFactor]];
+
[image setAccessibilityDescription:[NSString
stringWithFormat:NSLocalizedString(@"Page %@", @""), [controller pageLabel]]];
[controller setThumbnail:image];
@@ -2335,6 +2336,7 @@
if (openType == SKSnapshotOpenFromSetup) {
[self insertObject:controller inSnapshotsAtIndex:[snapshots count]];
[rightSideController.snapshotTableView reloadData];
+ [self snapshotNeedsUpdate:controller];
} else {
[rightSideController.snapshotTableView beginUpdates];
[self insertObject:controller inSnapshotsAtIndex:[snapshots count]];
@@ -2341,12 +2343,14 @@
NSUInteger row = [[rightSideController.snapshotArrayController
arrangedObjects] indexOfObject:controller];
if (row != NSNotFound) {
NSTableViewAnimationOptions options =
NSTableViewAnimationEffectGap | NSTableViewAnimationSlideDown;
- if ([self rightSidePaneIsOpen] == NO || [self rightSidePaneState]
!= SKSidePaneStateSnapshot || [NSView shouldShowSlideAnimation] == NO)
+ if (isVisible == NO || [NSView shouldShowSlideAnimation] == NO)
options = NSTableViewAnimationEffectNone;
[rightSideController.snapshotTableView
insertRowsAtIndexes:[NSIndexSet indexSetWithIndex:row] withAnimation:options];
}
[rightSideController.snapshotTableView endUpdates];
[self setRecentInfoNeedsUpdate:YES];
+ if (isVisible == NO)
+ [self snapshotNeedsUpdate:controller];
}
}
@@ -2811,6 +2815,24 @@
#pragma mark Thumbnails
++ (dispatch_queue_t)thumbnailQueue {
+ static dispatch_queue_t thumbnailQueue = nil;
+ if (thumbnailQueue == nil) {
+ dispatch_queue_attr_t queuePriority =
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
QOS_CLASS_DEFAULT, 0);
+ thumbnailQueue =
dispatch_queue_create("net.sourceforge.skim-app.skim.queue.thumbnails",
queuePriority);
+ }
+ return thumbnailQueue;
+}
+
++ (dispatch_queue_t)lowPriorityThumbnailQueue {
+ static dispatch_queue_t thumbnailQueue = nil;
+ if (thumbnailQueue == nil) {
+ dispatch_queue_attr_t queuePriority =
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
QOS_CLASS_UTILITY, 0);
+ thumbnailQueue =
dispatch_queue_create("net.sourceforge.skim-app.skim.queue.thumbnails",
queuePriority);
+ }
+ return thumbnailQueue;
+}
+
- (PDFPage *)pageForThumbnail:(SKThumbnail *)thumbnail {
return [[pdfView document] pageAtIndex:[thumbnail pageIndex]];
}
@@ -2827,11 +2849,7 @@
if ([self interactionMode] == SKPresentationMode &&
mwcFlags.thumbnailsNeedUpdateAfterPresentaton == 0 && fabs([mainWindow
backingScaleFactor] - scale) > 0.0)
mwcFlags.thumbnailsNeedUpdateAfterPresentaton = 1;
- static dispatch_queue_t thumbnailQueue = nil;
- if (thumbnailQueue == nil)
- thumbnailQueue =
dispatch_queue_create("net.sourceforge.skim-app.skim.queue.thumbnails",
DISPATCH_QUEUE_CONCURRENT);
-
- dispatch_async(thumbnailQueue, ^{
+ dispatch_async([[self class] thumbnailQueue], ^{
NSImage *image = [page thumbnailWithSize:thumbnailCacheSize
scale:scale forBox:box hasShadow:YES highlights:highlights];
[image setAccessibilityDescription:[NSString
stringWithFormat:NSLocalizedString(@"Page %@", @""), [page displayLabel]]];
@@ -3001,58 +3019,46 @@
if (fabs(snapshotSize - snapshotCacheSize) > FUDGE_SIZE) {
snapshotCacheSize = snapshotSize;
- if (snapshotTimer) {
- [snapshotTimer invalidate];
- snapshotTimer = nil;
- }
-
if ([[self snapshots] count])
[self allSnapshotsNeedUpdate];
}
}
-- (void)snapshotNeedsUpdate:(SKSnapshotWindowController *)dirtySnapshot {
- if ([dirtySnapshots containsObject:dirtySnapshot] == NO) {
- [dirtySnapshots addObject:dirtySnapshot];
- [self updateSnapshotsIfNeeded];
- }
-}
-
-- (void)allSnapshotsNeedUpdate {
- [dirtySnapshots setArray:[self snapshots]];
- [self updateSnapshotsIfNeeded];
-}
-
-- (void)updateSnapshot {
- if ([dirtySnapshots count]) {
- SKSnapshotWindowController *controller = [dirtySnapshots
objectAtIndex:0];
- NSSize newSize, oldSize = [[controller thumbnail] size];
- NSImage *image = [controller thumbnailWithSize:snapshotCacheSize
scale:[[self window] backingScaleFactor]];
+- (void)snapshotNeedsUpdate:(SKSnapshotWindowController *)controller {
+ CGFloat backingScale = [[self window] backingScaleFactor];
+ SKSnapshotConfiguration *configuration = [controller currentConfiguration];
+ dispatch_queue_t queue;
+
+ if ([rightSideController.snapshotTableView window])
+ queue = [[self class] thumbnailQueue];
+ else
+ queue = [[self class] lowPriorityThumbnailQueue];
+
+ dispatch_async(queue, ^{
- [image setAccessibilityDescription:[NSString
stringWithFormat:NSLocalizedString(@"Page %@", @""), [controller pageLabel]]];
- [controller setThumbnail:image];
- [dirtySnapshots removeObject:controller];
+ NSImage *image = [configuration thumbnailWithSize:snapshotCacheSize
scale:backingScale];
- newSize = [image size];
- if (fabs(newSize.width - oldSize.width) > 1.0 || fabs(newSize.height -
oldSize.height) > 1.0) {
- NSUInteger idx = [[rightSideController.snapshotArrayController
arrangedObjects] indexOfObject:controller];
- if (idx != NSNotFound)
- [rightSideController.snapshotTableView
noteHeightOfRowChanged:idx animating:YES];
- }
- }
- if ([dirtySnapshots count] == 0) {
- [snapshotTimer invalidate];
- snapshotTimer = nil;
- }
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSSize newSize = [image size];
+ NSSize oldSize = [[controller thumbnail] size];
+
+ [image setAccessibilityDescription:[NSString
stringWithFormat:NSLocalizedString(@"Page %@", @""), [controller pageLabel]]];
+
+ [controller setThumbnail:image];
+
+ if (fabs(newSize.width - oldSize.width) > 1.0 ||
fabs(newSize.height - oldSize.height) > 1.0) {
+ NSUInteger idx = [[rightSideController.snapshotArrayController
arrangedObjects] indexOfObject:controller];
+ if (idx != NSNotFound)
+ [rightSideController.snapshotTableView
noteHeightOfRowChanged:idx animating:YES];
+ }
+ });
+ });
}
-- (void)updateSnapshotsIfNeeded {
- if ([rightSideController.snapshotTableView window] != nil &&
[dirtySnapshots count] > 0 && snapshotTimer == nil) {
- __weak SKMainWindowController *weakSelf = self;
- snapshotTimer = [NSTimer scheduledTimerWithTimeInterval:0.03
repeats:YES block:^(NSTimer *timer){
- [weakSelf updateSnapshot];
- }];
- }
+- (void)allSnapshotsNeedUpdate {
+ for (SKSnapshotWindowController *controller in [self snapshots])
+ [self snapshotNeedsUpdate:controller];
+
}
- (void)updateSnapshotFilterPredicate {
Modified: trunk/SKSnapshotWindowController.h
===================================================================
--- trunk/SKSnapshotWindowController.h 2024-06-08 14:37:38 UTC (rev 14314)
+++ trunk/SKSnapshotWindowController.h 2024-06-08 17:30:41 UTC (rev 14315)
@@ -37,6 +37,7 @@
*/
#import <Cocoa/Cocoa.h>
+#import <Quartz/Quartz.h>
#import "SKSnapshotPDFView.h"
NS_ASSUME_NONNULL_BEGIN
@@ -43,7 +44,7 @@
extern NSString *SKSnapshotCurrentSetupKey;
-@class PDFDocument, PDFPage, PDFDestination;
+@class PDFDocument, PDFPage, PDFDestination, SKSnapshotConfiguration;
@protocol SKSnapshotWindowControllerDelegate;
typedef NS_ENUM(NSInteger, SKSnapshotOpenType) {
@@ -73,6 +74,7 @@
@property (nonatomic, readonly) BOOL hasWindow;
@property (weak, nonatomic, readonly) NSDictionary<NSString *, id>
*currentSetup;
@property (nonatomic) BOOL forceOnTop;
+@property (weak, nonatomic, readonly) SKSnapshotConfiguration
*currentConfiguration;
@property (weak, nonatomic, readonly) NSAttributedString *thumbnailAttachment,
*thumbnail512Attachment, *thumbnail256Attachment, *thumbnail128Attachment,
*thumbnail64Attachment, *thumbnail32Attachment;
@@ -86,7 +88,7 @@
- (void)updatePageLabel;
-- (NSImage *)thumbnailWithSize:(CGFloat)size scale:(CGFloat)scale;
+- (NSImage *)placeholderThumbnailWithSize:(CGFloat)size scale:(CGFloat)scale;
- (NSAttributedString *)thumbnailAttachmentWithSize:(CGFloat)size;
@@ -119,4 +121,22 @@
@end
+@interface SKSnapshotConfiguration : NSObject {
+ NSSize size;
+ CGFloat scaleFactor;
+ PDFDisplayBox displayBox;
+ PDFInterpolationQuality interpolationQuality;
+ NSArray<PDFDestination *> *pages;
+}
+
+@property (nonatomic) NSSize size;
+@property (nonatomic) CGFloat scaleFactor;
+@property (nonatomic) PDFDisplayBox displayBox;
+@property (nonatomic) PDFInterpolationQuality interpolationQuality;
+@property (nonatomic, nullable, copy) NSArray<PDFDestination *> *pages;
+
+- (NSImage *)thumbnailWithSize:(CGFloat)aSize scale:(CGFloat)scale;
+
+@end
+
NS_ASSUME_NONNULL_END
Modified: trunk/SKSnapshotWindowController.m
===================================================================
--- trunk/SKSnapshotWindowController.m 2024-06-08 14:37:38 UTC (rev 14314)
+++ trunk/SKSnapshotWindowController.m 2024-06-08 17:30:41 UTC (rev 14315)
@@ -91,7 +91,7 @@
@implementation SKSnapshotWindowController
-@synthesize pdfView, delegate, thumbnail, pageLabel, string, hasWindow,
forceOnTop;
+@synthesize pdfView, delegate, thumbnail, pageLabel, string, hasWindow,
forceOnTop, currentConfiguration;
@dynamic bounds, pageIndex, currentSetup, thumbnailAttachment,
thumbnail512Attachment, thumbnail256Attachment, thumbnail128Attachment,
thumbnail64Attachment, thumbnail32Attachment;
- (NSString *)windowNibName {
@@ -393,6 +393,24 @@
return @{PAGE_KEY:[NSNumber numberWithUnsignedInteger:[self pageIndex]],
RECT_KEY:NSStringFromRect([self bounds]), SCALEFACTOR_KEY:[NSNumber
numberWithDouble:[pdfView scaleFactor]], AUTOFITS_KEY:[NSNumber
numberWithBool:[pdfView autoFits]], HASWINDOW_KEY:[NSNumber
numberWithBool:[[self window] isVisible]],
WINDOWFRAME_KEY:NSStringFromRect([[self window] frame])};
}
+- (SKSnapshotConfiguration *)currentConfiguration {
+ SKSnapshotConfiguration *configuration = [[SKSnapshotConfiguration alloc]
init];
+ NSRect bounds = [pdfView visibleContentRect];
+ PDFDisplayBox box = [pdfView displayBox];
+ NSMutableArray *pages = [NSMutableArray array];
+ for (PDFPage *page in [pdfView visiblePages]) {
+ NSRect pageRect = [pdfView convertRect:[page boundsForBox:box]
fromPage:page];
+ if (NSIntersectsRect(pageRect, bounds))
+ [pages addObject:[[PDFDestination alloc] initWithPage:page
atPoint:SKSubstractPoints(pageRect.origin, bounds.origin)]];
+ }
+ [configuration setSize:bounds.size];
+ [configuration setScaleFactor:[pdfView scaleFactor]];
+ [configuration setDisplayBox:box];
+ [configuration setInterpolationQuality:[pdfView interpolationQuality]];
+ [configuration setPages:pages];
+ return configuration;
+}
+
#pragma mark Actions
- (IBAction)doGoToNextPage:(id)sender {
@@ -470,53 +488,18 @@
#pragma mark Thumbnails
-- (NSImage *)thumbnailWithSize:(CGFloat)size scale:(CGFloat)scale {
+- (NSImage *)placeholderThumbnailWithSize:(CGFloat)size scale:(CGFloat)scale {
+ PDFPage *page = [[PDFPage alloc] init];
NSRect bounds = [pdfView visibleContentRect];
- NSAffineTransform *transform = [NSAffineTransform transform];
- NSSize thumbnailSize = bounds.size;
- CGFloat shadowBlurRadius = 0.0;
- CGFloat shadowOffset = 0.0;
- NSImage *image;
-
- if (size > 0.0) {
- shadowBlurRadius = round(scale * size / 32.0) / scale;
- shadowOffset = -ceil(scale * shadowBlurRadius * 0.75) / scale;
- 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 translateXBy:shadowBlurRadius yBy:shadowBlurRadius -
shadowOffset];
- [transform scaleXBy:(thumbnailSize.width - 2.0 * shadowBlurRadius) /
NSWidth(bounds) yBy:(thumbnailSize.height - 2.0 * shadowBlurRadius) /
NSHeight(bounds)];
- }
-
- if (NSEqualPoints(bounds.origin, NSZeroPoint) == NO)
- [transform translateXBy:-NSMinX(bounds) yBy:-NSMinY(bounds)];
-
- image = [NSImage bitmapImageWithSize:thumbnailSize scale:scale
drawingHandler:^(NSRect dstRect){
-
- [[NSGraphicsContext currentContext]
setImageInterpolation:NSImageInterpolationHigh];
- [transform concat];
-
- [NSGraphicsContext saveGraphicsState];
- [[NSColor whiteColor] set];
- if (shadowBlurRadius > 0.0)
- [NSShadow setShadowWithWhite:0.0 alpha:0.3
blurRadius:shadowBlurRadius yOffset:shadowOffset];
- NSRectFill(bounds);
- [[NSGraphicsContext currentContext]
setImageInterpolation:NSImageInterpolationDefault];
- [NSGraphicsContext restoreGraphicsState];
- [[NSBezierPath bezierPathWithRect:bounds] addClip];
-
- CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
- [pdfView drawPagesInRect:bounds toContext:context];
-
- }];
-
- return image;
+ bounds.origin = NSZeroPoint;
+ [page setBounds:bounds forBox:kPDFDisplayBoxMediaBox];
+ return [page thumbnailWithSize:size scale:scale
forBox:kPDFDisplayBoxMediaBox hasShadow:YES highlights:nil];
}
- (NSAttributedString *)thumbnailAttachmentWithSize:(CGFloat)size {
- NSBitmapImageRep *imageRep1 = (NSBitmapImageRep *)[[[self
thumbnailWithSize:size scale:1.0] representations] firstObject];
- NSBitmapImageRep *imageRep2 = (NSBitmapImageRep *)[[[self
thumbnailWithSize:size scale:2.0] representations] firstObject];
+ SKSnapshotConfiguration *configuration = [self currentConfiguration];
+ NSBitmapImageRep *imageRep1 = (NSBitmapImageRep *)[[[configuration
thumbnailWithSize:size scale:1.0] representations] firstObject];
+ NSBitmapImageRep *imageRep2 = (NSBitmapImageRep *)[[[configuration
thumbnailWithSize:size scale:2.0] representations] firstObject];
NSData *data = [NSBitmapImageRep
TIFFRepresentationOfImageRepsInArray:@[imageRep1, imageRep2]];
NSFileWrapper *wrapper = [[NSFileWrapper alloc]
initRegularFileWithContents:data];
@@ -741,8 +724,9 @@
}
- (void)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider
writePromiseToURL:(NSURL *)fileURL completionHandler:(void (^)(NSError
*))completionHandler {
- NSBitmapImageRep *imageRep1 = (NSBitmapImageRep *)[[[self
thumbnailWithSize:0.0 scale:1.0] representations] firstObject];
- NSBitmapImageRep *imageRep2 = (NSBitmapImageRep *)[[[self
thumbnailWithSize:0.0 scale:2.0] representations] firstObject];
+ SKSnapshotConfiguration *configuration = [self currentConfiguration];
+ NSBitmapImageRep *imageRep1 = (NSBitmapImageRep *)[[[configuration
thumbnailWithSize:0.0 scale:1.0] representations] firstObject];
+ NSBitmapImageRep *imageRep2 = (NSBitmapImageRep *)[[[configuration
thumbnailWithSize:0.0 scale:2.0] representations] firstObject];
NSData *data = [NSBitmapImageRep
TIFFRepresentationOfImageRepsInArray:@[imageRep1, imageRep2]];
NSError *error = nil;
[data writeToURL:fileURL options:NSDataWritingAtomic error:&error];
@@ -750,3 +734,64 @@
}
@end
+
+
+@implementation SKSnapshotConfiguration
+
+@synthesize size, scaleFactor, displayBox, interpolationQuality, pages;
+
+- (NSImage *)thumbnailWithSize:(CGFloat)aSize scale:(CGFloat)scale {
+ NSRect bounds = (NSRect){NSZeroPoint, [self size]};
+ NSAffineTransform *transform = [NSAffineTransform transform];
+ NSSize thumbnailSize = bounds.size;
+ CGFloat shadowBlurRadius = 0.0;
+ CGFloat shadowOffset = 0.0;
+ NSImage *image;
+
+ if (aSize > 0.0) {
+ shadowBlurRadius = round(scale * aSize / 32.0) / scale;
+ shadowOffset = -ceil(scale * shadowBlurRadius * 0.75) / scale;
+ if (NSHeight(bounds) > NSWidth(bounds))
+ thumbnailSize = NSMakeSize(round((aSize - 2.0 * shadowBlurRadius)
* NSWidth(bounds) / NSHeight(bounds) + 2.0 * shadowBlurRadius), aSize);
+ else
+ thumbnailSize = NSMakeSize(aSize, round((aSize - 2.0 *
shadowBlurRadius) * NSHeight(bounds) / NSWidth(bounds) + 2.0 *
shadowBlurRadius));
+ [transform translateXBy:shadowBlurRadius yBy:shadowBlurRadius -
shadowOffset];
+ [transform scaleXBy:(thumbnailSize.width - 2.0 * shadowBlurRadius) /
NSWidth(bounds) yBy:(thumbnailSize.height - 2.0 * shadowBlurRadius) /
NSHeight(bounds)];
+ }
+
+ if (NSEqualPoints(bounds.origin, NSZeroPoint) == NO)
+ [transform translateXBy:-NSMinX(bounds) yBy:-NSMinY(bounds)];
+
+ image = [NSImage bitmapImageWithSize:thumbnailSize scale:scale
drawingHandler:^(NSRect dstRect){
+
+ [[NSGraphicsContext currentContext]
setImageInterpolation:NSImageInterpolationHigh];
+ [transform concat];
+
+ [NSGraphicsContext saveGraphicsState];
+ [[NSColor whiteColor] set];
+ if (shadowBlurRadius > 0.0)
+ [NSShadow setShadowWithWhite:0.0 alpha:0.3
blurRadius:shadowBlurRadius yOffset:shadowOffset];
+ NSRectFill(bounds);
+ [[NSGraphicsContext currentContext]
setImageInterpolation:NSImageInterpolationDefault];
+ [NSGraphicsContext restoreGraphicsState];
+ [[NSBezierPath bezierPathWithRect:bounds] addClip];
+
+ CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
+ PDFDisplayBox *box = [self displayBox];
+ CGFloat scale = [self scaleFactor];
+ CGContextSetInterpolationQuality(context, [self interpolationQuality]
+ 1);
+ for (PDFDestination *dest in [self pages]) {
+ NSPoint point = [dest point];
+ CGContextSaveGState(context);
+ CGContextTranslateCTM(context, point.x, point.y);
+ CGContextScaleCTM(context, scale, scale);
+ [[dest page] drawWithBox:box toContext:context];
+ CGContextRestoreGState(context);
+ }
+
+ }];
+
+ return image;
+}
+
+@end
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit