Confusion about -isFlipped in Cocoa

Moderator
Posts: 1,560
Joined: 2003.10
Post: #1
I'm working on a graphics program, and having a bit of trouble getting a grasp on my coordinate system. My intention is to have the drawing origin in the upper left corner. Internally, bitmap contents are stored as arrays of unsigned char. I draw them to the document window's view with NSDrawBitmap, as follows:

Code:
NSDrawBitmap(NSMakeRect(0, 0, width, height),
               width,
               height,
               8,
               4,
               (BYTES_PER_PIXEL * 8),
               (width * BYTES_PER_PIXEL),
               NO,
               NO,
               NSDeviceRGBColorSpace,
               (const unsigned char **) &pixels);
This is all fine and dandy. Up until recently, I'd been returning YES from -isFlipped in my NSView subclass. According to Apple's documentation, a flipped view's Y axis runs from top to bottom, whereas an unflipped view's Y axis runs from bottom to top. However, after some experimentation last night, I found that if I set the very first pixel in my bitmap to black, it shows up in the lower left corner when my view is flipped, and in the upper left corner when my view is unflipped.

Does anyone know what could be happening here? Does NSDrawBitmap draw things upside-down in relation to the rest of Quartz, or anything like that? Unless I'm missing something, what I'm seeing is the opposite behavior as the documentation would indicate.
Quote this message in a reply
Member
Posts: 204
Joined: 2002.09
Post: #2
Have you checked to see if you are a subview of another flipped view, hence re-flipping your flipped view?
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #3
Shouldn't be possible. My document window is currently nothing more than an NSWindow with a single NSView subclass inside it.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
I thought that NSDrawBitmap ignored the Quartz coordinate system and does a simple blit to the window...
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #5
I tried drawing my image to the window with NSBitmapImageRep/NSImage instead of NSDrawBitmap, and it gave me the same behavior.

Another piece in the puzzle: It turns out that I'm currently flipping the Y coordinate on all incoming events. If I don't do this, the Y axis on incoming events runs whichever way is opposite to the Y axis for drawing.

What the heck is going on? Blink
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #6
I think I understand what's happening now. According to #macdev, it seems that bitmaps are upside-down relative to the rest of Quartz. This seems crazy, but it's consistent with what I'm seeing.

This kind of thing makes me want to go back to QuickDraw. At least things made some amount of sense there. Sad
Quote this message in a reply
⌘-R in Chief
Posts: 1,261
Joined: 2002.05
Post: #7
I haven't been following this much at all, but just to ask, is there any reason you really need to fight against Quartz vs use it as is?

Code:
@implementation MyView


- (BOOL)isFlipped;
{
    return YES;
}


- (void)drawRect:(NSRect)rect;
{
    NSImage * image = [NSImage imageNamed:@"Nintendo"];
    [self drawImage:image atPoint:NSMakePoint(10, 10)];
}


- (void)drawImage:(NSImage *)image atPoint:(NSPoint)point;
{
    NSSize size = [image size];
    [image setFlipped:YES];
    [image drawInRect:NSMakeRect(point.x, point.y + size.height, size.width, -size.height)
        fromRect:NSMakeRect(0, 0, size.width, size.height)
            operation:NSCompositeSourceOver fraction:1.0];
}


@end
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #8
Why do you think I'm fighting against it? I'm just trying to get it to work.

If you're talking about the fact that I'm using an array of raw pixels internally rather than an NSImage, then yes, I have reasons for doing it that way. I need pixel-level access at all times, and NSImage doesn't appear to give that to me very easily. I'm assuming that I could add an NSBitmapImageRep to it, and access its pixels from -bitmapData, but why jump through those hoops unnecessarily? I don't need any of NSImage's capabilities, so it would be a complete waste to use it unless there was no simpler way to do what I need to do. It also looks as though going through NSBitmapImageRep/NSImage would be slow down my drawing noticeably, which would be unacceptible in this situation.

I'm simply using the right tool for the job.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL/C confusion spsweet 7 4,584 Mar 21, 2007 06:54 PM
Last Post: OneSadCookie
  OpenGL Confusion BinarySpike 10 4,715 Jan 15, 2005 10:59 PM
Last Post: SethWillits
  Confusion about native pixel format tigakub 3 5,871 May 14, 2002 02:45 PM
Last Post: OneSadCookie