I have a simple Obj C program that, at the moment, lets you load an image, draws it up, and theoretically should let you zoom and rotate. I'm using NSAffineTranslations.
I want the image to be locked to the upper left (As opposed to the PS/PDF standard of lower left), so I'm using isFlipped, and calling [afTrans scaleXBy:1.0 yBy:-1.0];
The problem is that for some reason, after the first time my drawRect is called, the transformation doesn't happen.
When I load an image, it comes up, and looks correct. If I change the size of the window (Which calls drawRect), the image draws, but is upside-down and reversed. This means that the transformation didn't take effect. I don't see any differences in any of the data the 2nd time through.
here is a stripped down version of the code:
- (void)drawRect:(NSRect)rect 
{
    // Drawing code here.
//    NSLog(@"window type: %d", [[self window] backingType]);
   NSAffineTransform *afTrans = [[NSAffineTransform alloc] init];
   NSGraphicsContext *context = [NSGraphicsContext currentContext];
   NSSize sz;
   NSRect windowFrame = [[self window] frame];
   NSRect cv =[[[self window] contentView] frame];
   float deltaX, deltaY;
   NSSize superSize = [[self superview] frame].size;
   float height, width, sHeight, sWidth;
   NSRect imageRect;
   sz = [ image size];
   imageRect.size = sz;
   imageRect.origin = NSZeroPoint;
   height = sz.height  ;
   width = sz.width  ;
//    sHeight and sWidth are the hieght and with of the super-view. ie,
//    the size of the whole window view including the space for the
//    scroll bars, etc, but not including the panel or the borders,
   sHeight = superSize.height;
   sWidth = superSize.width;
   [context saveGraphicsState];
   deltaX = 0;
   deltaY = 0;
   deltaY += height; // account for flipping
   [afTrans translateXBy:deltaX yBy:deltaY];
   [afTrans scaleXBy:1.0 yBy:-1.0];
   [afTrans concat];
   NSRect drawingRect = imageRect;
   NSRect frame = imageRect;
   [self setFrame:frame];
   [image drawInRect:drawingRect
         fromRect:imageRect
         operation:NSCompositeSourceOver
         fraction:1];
   [afTrans release];
   [context restoreGraphicsState];
}
ETA: here's some more code that MIGHT be relevant.
-(void )setImage:( NSImage * )newImage
{
    [newImage retain];
    [image release];
    rotation = 0;
    zoom = 1.0;
    image = newImage;
    NSSize imageSize = [newImage size];
    NSRect tFrame = [self frame];
    tFrame = [[self window] frame];
    tFrame.size.width = MAX(tFrame.size.width, imageSize.width);
    tFrame.size.height = MAX(tFrame.size.height, imageSize.height);
    [self setFrame:tFrame];
    [self setNeedsDisplay:YES];
}
I'm not sure exactly what you're trying to achieve, but if you want to just draw an image in a NSView and keep it in the upper left, you can do something a bit simpler, in your NSView subclass:
- (BOOL)isFlipped
{
    return YES;
}
- (void)setImage:(NSImage *)newImage
{
    [newImage retain];
    [image release];
    image = newImage;
    [image setFlipped:YES];
    [self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)rect
{
    [image drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
    // Or stretch image to fill view
    //[image drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
}
I was also able to get similar results with your code by getting rid of the [self setFrame:...]; calls in drawRect and setImage methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With