Revision: 2539
http://skim-app.svn.sourceforge.net/skim-app/?rev=2539&view=rev
Author: hofman
Date: 2007-07-20 13:40:54 -0700 (Fri, 20 Jul 2007)
Log Message:
-----------
Allow restricting CoreGraphics transitions to the page extent. Animate the
transitionWindow with OGL view instead of the PDFView's window in that case.
Restrict to the page by default, as the full transition is typically less
efficient and can be too flashy.
Modified Paths:
--------------
trunk/SKPDFView.m
trunk/SKTransitionController.h
trunk/SKTransitionController.m
Modified: trunk/SKPDFView.m
===================================================================
--- trunk/SKPDFView.m 2007-07-19 23:25:01 UTC (rev 2538)
+++ trunk/SKPDFView.m 2007-07-20 20:40:54 UTC (rev 2539)
@@ -153,7 +153,7 @@
transitionController = nil;
transitionStyle = SKNoTransition;
transitionDuration = 1.0;
- transitionShouldRestrict = NO;
+ transitionShouldRestrict = YES;
spellingTag = [NSSpellChecker uniqueSpellDocumentTag];
@@ -590,7 +590,7 @@
if (transitionController == nil)
transitionController = [[SKTransitionController alloc]
initWithView:self];
NSRect rect = [self convertRect:[[self currentPage] boundsForBox:[self
displayBox]] fromPage:[self currentPage]];
- [transitionController prepareForAnimationWithTransitionStyle:[self
transitionStyle] fromRect:rect];
+ [transitionController prepareForAnimationWithTransitionStyle:[self
transitionStyle] fromRect:rect shouldRestrict:transitionShouldRestrict];
if (next)
[super goToNextPage:self];
else
Modified: trunk/SKTransitionController.h
===================================================================
--- trunk/SKTransitionController.h 2007-07-19 23:25:01 UTC (rev 2538)
+++ trunk/SKTransitionController.h 2007-07-20 20:40:54 UTC (rev 2539)
@@ -129,7 +129,7 @@
- (NSView *)view;
- (void)setView:(NSView *)newView;
--
(void)prepareForAnimationWithTransitionStyle:(SKAnimationTransitionStyle)transitionStyle
fromRect:(NSRect)rect;
+-
(void)prepareForAnimationWithTransitionStyle:(SKAnimationTransitionStyle)transitionStyle
fromRect:(NSRect)rect shouldRestrict:(BOOL)shouldRestrict;
- (void)animateWithTransitionStyle:(SKAnimationTransitionStyle)transitionStyle
direction:(CGSTransitionOption)direction duration:(float)duration
fromRect:(NSRect)rect shouldRestrict:(BOOL)shouldRestrict;
@end
Modified: trunk/SKTransitionController.m
===================================================================
--- trunk/SKTransitionController.m 2007-07-19 23:25:01 UTC (rev 2538)
+++ trunk/SKTransitionController.m 2007-07-20 20:40:54 UTC (rev 2539)
@@ -69,11 +69,15 @@
@interface SKTransitionView : NSOpenGLView {
SKTransitionAnimation *animation;
+ CIImage *image;
CIContext *context;
BOOL needsReshape;
}
- (SKTransitionAnimation *)animation;
- (void)setAnimation:(SKTransitionAnimation *)newAnimation;
+- (CIImage *)image;
+- (void)setImage:(CIImage *)newImage;
+- (CIImage *)currentImage;
@end
#pragma mark -
@@ -144,6 +148,22 @@
return inputMaskImage;
}
+- (CIImage *)cropImage:(CIImage *)image toRect:(NSRect)rect {
+ CIFilter *cropFilter = [self filterWithName:@"CICrop"];
+ [cropFilter setValue:[CIVector vectorWithX:NSMinX(rect) Y:NSMinY(rect)
Z:NSWidth(rect) W:NSHeight(rect)] forKey:@"inputRectangle"];
+ [cropFilter setValue:image forKey:@"inputImage"];
+ return [cropFilter valueForKey:@"outputImage"];
+}
+
+- (CIImage *)translateImage:(CIImage *)image xBy:(float)dx yBy:(float)dy {
+ CIFilter *translationFilter = [self filterWithName:@"CIAffineTransform"];
+ NSAffineTransform *affineTransform = [NSAffineTransform transform];
+ [affineTransform translateXBy:dx yBy:dy];
+ [translationFilter setValue:affineTransform forKey:@"inputTransform"];
+ [translationFilter setValue:image forKey:@"inputImage"];
+ return [translationFilter valueForKey:@"outputImage"];
+}
+
- (CIFilter *)transitionFilter:(SKAnimationTransitionStyle)transitionStyle
forRect:(NSRect)rect inBounds:(NSRect)bounds
shouldRestrict:(BOOL)shouldRestrict initialCIImage:(CIImage *)initialCIImage
finalCIImage:(CIImage *)finalCIImage {
NSString *filterName = [[[self class] transitionFilterNames]
objectAtIndex:transitionStyle - SKCoreImageTransition];
CIFilter *transitionFilter = [self filterWithName:filterName];
@@ -176,25 +196,16 @@
[maskScalingFilter setValue:[NSNumber
numberWithFloat:yScale] forKey:@"inputScale"];
[maskScalingFilter setValue:[NSNumber
numberWithFloat:xScale / yScale] forKey:@"inputAspectRatio"];
[maskScalingFilter setValue:[self inputMaskImage]
forKey:@"inputImage"];
- CIFilter *maskTranslationFilter = [self
filterWithName:@"CIAffineTransform"];
- NSAffineTransform *affineTransform = [NSAffineTransform
transform];
- [affineTransform translateXBy:NSMinX(rect) -
NSMinX(bounds) yBy:NSMinY(rect) - NSMinY(bounds)];
- [maskTranslationFilter setValue:affineTransform
forKey:@"inputTransform"];
- [maskTranslationFilter setValue:[maskScalingFilter
valueForKey:@"outputImage"] forKey:@"inputImage"];
- [transitionFilter setValue:[maskTranslationFilter
valueForKey:@"outputImage"] forKey:key];
+ [transitionFilter setValue:[self
translateImage:[maskScalingFilter valueForKey:@"outputImage"] xBy:NSMinX(rect)
- NSMinX(bounds) yBy:NSMinY(rect) - NSMinY(bounds)] forKey:key];
}
}
}
}
if (NSEqualRects(rect, bounds) == NO) {
- CIFilter *cropFilter = [self filterWithName:@"CICrop"];
- [cropFilter setValue:[CIVector vectorWithX:NSMinX(rect) Y:NSMinY(rect)
Z:NSWidth(rect) W:NSHeight(rect)] forKey:@"inputRectangle"];
- [cropFilter setValue:initialCIImage forKey:@"inputImage"];
- initialCIImage = [cropFilter valueForKey:@"outputImage"];
- [cropFilter setValue:finalCIImage forKey:@"inputImage"];
- finalCIImage = [cropFilter valueForKey:@"outputImage"];
+ initialCIImage = [self cropImage:initialCIImage toRect:rect];
+ finalCIImage = [self cropImage:finalCIImage toRect:rect];
}
[transitionFilter setValue:initialCIImage forKey:@"inputImage"];
@@ -203,26 +214,53 @@
return transitionFilter;
}
--
(void)prepareForAnimationWithTransitionStyle:(SKAnimationTransitionStyle)transitionStyle
fromRect:(NSRect)rect {
+- (CIImage *)createCurrentImage {
+ NSRect bounds = [view bounds];
+ NSBitmapImageRep *contentBitmap = [view
bitmapImageRepForCachingDisplayInRect:bounds];
+ [contentBitmap clear];
+ [view cacheDisplayInRect:bounds toBitmapImageRep:contentBitmap];
+ return [[CIImage alloc] initWithBitmapImageRep:contentBitmap];
+}
+
+- (NSWindow *)transitionWindow {
+ if (transitionWindow == nil) {
+ transitionWindow = [[NSWindow alloc] initWithContentRect:NSZeroRect
styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ [transitionWindow setReleasedWhenClosed:NO];
+ [transitionWindow setIgnoresMouseEvents:YES];
+
+ transitionView = [[SKTransitionView alloc] init];
+ [transitionWindow setContentView:transitionView];
+ [transitionView release];
+ }
+ return transitionWindow;
+}
+
+- (SKTransitionView *)transitionView {
+ if (transitionView == nil)
+ [self transitionWindow];
+ return transitionView;
+}
+
+-
(void)prepareForAnimationWithTransitionStyle:(SKAnimationTransitionStyle)transitionStyle
fromRect:(NSRect)rect shouldRestrict:(BOOL)shouldRestrict {
if (transitionStyle == SKNoTransition) {
} else if (transitionStyle < SKCoreImageTransition) {
if (CoreGraphicsServicesTransitionsDefined()) {
+ if (shouldRestrict) {
+ [initialImage release];
+ initialImage = [self createCurrentImage];
+ }
// We don't want the window to draw the next state before the
animation is run
[[view window] disableFlushWindow];
}
} else {
- NSRect bounds = [view bounds];
[initialImage release];
- NSBitmapImageRep *initialContentBitmap = [view
bitmapImageRepForCachingDisplayInRect:bounds];
- [initialContentBitmap clear];
- [view cacheDisplayInRect:bounds toBitmapImageRep:initialContentBitmap];
- initialImage = [[CIImage alloc]
initWithBitmapImageRep:initialContentBitmap];
- imageRect = rect;
+ initialImage = [self createCurrentImage];
// We don't want the window to draw the next state before the
animation is run
[[view window] disableFlushWindow];
}
+ imageRect = rect;
}
- (void)animateWithTransitionStyle:(SKAnimationTransitionStyle)transitionStyle
direction:(CGSTransitionOption)direction duration:(float)duration
fromRect:(NSRect)rect shouldRestrict:(BOOL)shouldRestrict {
@@ -230,16 +268,43 @@
} else if (transitionStyle < SKCoreImageTransition) {
if (CoreGraphicsServicesTransitionsDefined()) {
+
+ CIImage *finalImage = nil;
+
+ if (shouldRestrict) {
+ if (initialImage == nil)
+ [self
prepareForAnimationWithTransitionStyle:transitionStyle fromRect:rect
shouldRestrict:shouldRestrict];
+
+ NSRect bounds = [view bounds];
+ imageRect =
NSIntegralRect(NSIntersectionRect(NSUnionRect(imageRect, rect), bounds));
+
+ finalImage = [self createCurrentImage];
+
+ float dx = NSMinX(bounds) - NSMinX(imageRect);
+ float dy = NSMinY(bounds) - NSMinY(imageRect);
+ initialImage = [self translateImage:[self
cropImage:[initialImage autorelease] toRect:rect] xBy:dx yBy:dy];
+ finalImage = [self translateImage:[self cropImage:[finalImage
autorelease] toRect:rect] xBy:dx yBy:dy];
+
+ NSRect frame = [view convertRect:imageRect toView:nil];
+ frame.origin = [[view window]
convertBaseToScreen:frame.origin];
+
+ [[self transitionView] setImage:initialImage];
+ initialImage = nil;
+
+ [[self transitionWindow] setFrame:frame display:YES];
+ [[self transitionWindow] orderBack:nil];
+ [[view window] addChildWindow:[self transitionWindow]
ordered:NSWindowAbove];
+ }
+
// declare our variables
int handle = -1;
CGSTransitionSpec spec;
-
// specify our specifications
spec.unknown1 = 0;
spec.type = transitionStyle;
spec.option = direction;
spec.backColour = NULL;
- spec.wid = [[view window] windowNumber];
+ spec.wid = [(shouldRestrict ? [self transitionWindow] : [view
window]) windowNumber];
// Let's get a connection
CGSConnection cgs = _CGSDefaultConnection();
@@ -247,6 +312,11 @@
// Create a transition
CGSNewTransition(cgs, &spec, &handle);
+ if (shouldRestrict) {
+ [[self transitionView] setImage:finalImage];
+ [[self transitionView] display];
+ }
+
// Redraw the window
[[view window] display];
// Remember we disabled flushing in the previous method, we need
to balance that.
@@ -259,18 +329,22 @@
CGSReleaseTransition(cgs, handle);
handle = 0;
+
+ if (shouldRestrict) {
+ [[view window] removeChildWindow:[self transitionWindow]];
+ [[self transitionWindow] orderOut:nil];
+ [[self transitionView] setImage:nil];
+ }
}
} else {
if (initialImage == nil)
- [self prepareForAnimationWithTransitionStyle:transitionStyle
fromRect:rect];
+ [self prepareForAnimationWithTransitionStyle:transitionStyle
fromRect:rect shouldRestrict:shouldRestrict];
+
NSRect bounds = [view bounds];
- imageRect = NSIntersectionRect(NSUnionRect(imageRect, rect), bounds);
+ imageRect = NSIntegralRect(NSIntersectionRect(NSUnionRect(imageRect,
rect), bounds));
- NSBitmapImageRep *finalContentBitmap = [view
bitmapImageRepForCachingDisplayInRect:bounds];
- [finalContentBitmap clear];
- [view cacheDisplayInRect:bounds toBitmapImageRep:finalContentBitmap];
- CIImage *finalImage = [[CIImage alloc]
initWithBitmapImageRep:finalContentBitmap];
+ CIImage *finalImage = [self createCurrentImage];
CIFilter *transitionFilter = [self transitionFilter:transitionStyle
forRect:imageRect inBounds:[view bounds] shouldRestrict:shouldRestrict
initialCIImage:initialImage finalCIImage:finalImage];
@@ -282,24 +356,12 @@
NSRect frame = [view convertRect:[view frame] toView:nil];
frame.origin = [window convertBaseToScreen:frame.origin];
- if (transitionWindow == nil) {
- transitionWindow = [[NSWindow alloc] initWithContentRect:frame
styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO
screen:[window screen]];
- [transitionWindow setReleasedWhenClosed:NO];
- [transitionWindow setDisplaysWhenScreenProfileChanges:YES];
- [transitionWindow setIgnoresMouseEvents:YES];
-
- transitionView = [[SKTransitionView alloc] init];
- [transitionWindow setContentView:transitionView];
- [transitionView release];
- }
-
SKTransitionAnimation *animation = [[SKTransitionAnimation alloc]
initWithFilter:transitionFilter duration:duration
animationCurve:NSAnimationEaseInOut];
-
- [transitionView setAnimation:animation];
+ [[self transitionView] setAnimation:animation];
[animation release];
- [transitionWindow setFrame:frame display:NO];
- [transitionWindow orderBack:nil];
+ [[self transitionWindow] setFrame:frame display:NO];
+ [[self transitionWindow] orderBack:nil];
[window addChildWindow:transitionWindow ordered:NSWindowAbove];
[animation startAnimation];
@@ -307,12 +369,12 @@
// Update the view and its window, so it shows the correct state when
it is shown.
[view display];
// Remember we disabled flushing in the previous method, we need to
balance that.
- [[view window] enableFlushWindow];
- [[view window] flushWindow];
+ [window enableFlushWindow];
+ [window flushWindow];
[window removeChildWindow:transitionWindow];
- [transitionWindow orderOut:nil];
- [transitionView setAnimation:nil];
+ [[self transitionWindow] orderOut:nil];
+ [[self transitionView] setAnimation:nil];
}
}
@@ -414,6 +476,22 @@
}
}
+- (CIImage *)image {
+ return image;
+}
+
+- (void)setImage:(CIImage *)newImage {
+ if (image != newImage) {
+ [image release];
+ image = [newImage retain];
+ [self setNeedsDisplay:YES];
+ }
+}
+
+- (CIImage *)currentImage {
+ return image ? image : [animation currentImage];
+}
+
- (void)drawRect:(NSRect)rect {
NSRect bounds = [self bounds];
@@ -430,10 +508,13 @@
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+
+ [[self openGLContext] update];
+
needsReshape = NO;
}
- glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glBegin(GL_POLYGON);
glVertex2f(NSMinX(rect), NSMinY(rect));
glVertex2f(NSMaxX(rect), NSMinY(rect));
@@ -441,7 +522,9 @@
glVertex2f(NSMinX(rect), NSMaxY(rect));
glEnd();
- if (animation) {
+ CIImage *currentImage = [self currentImage];
+
+ if (currentImage) {
if (context == nil) {
NSOpenGLPixelFormat *pf = [self pixelFormat];
@@ -450,7 +533,7 @@
context = [[CIContext contextWithCGLContext:CGLGetCurrentContext()
pixelFormat:[pf CGLPixelFormatObj] options:nil] retain];
}
- [context drawImage:[animation currentImage] inRect:*(CGRect*)&bounds
fromRect:*(CGRect*)&bounds];
+ [context drawImage:currentImage inRect:*(CGRect*)&bounds
fromRect:*(CGRect*)&bounds];
}
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/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit