iOS inverted coordinates chaos

2.9k views Asked by At

So I am using CGBitmapContext to adapt a software blitter to iOS. I write my data to the bitmap, then I use CoreGraphics functions to write text over the CGBitmapContext. The software blitter uses Upper Left Hand Origin, while the CoreGraphics functions use Lower Left Hand Origin. So when I draw an image using the blitter at (0, 0), it appears in the upper left hand corner. When I draw text using CG at (0, 0) it appears in the lower left hand corner and it is NOT INVERTED. Yes I have read all the other questions about inverting coordinates and I am doing that to the the resulting CG image to display it in the view properly. Perhaps a code example would help...

    // This image is at the top left corner using the custom blitter.
screen->write(image, ark::Point(0, 0));
// This text is at the bottom left corner RIGHT SIDE UP
// cg context is a CGBitmapContext
CGContextShowTextAtPoint(
    cgcontext, 
    0, 0, 
    str.c_str(), 
    str.length());

// Send final image to video output.
CGImageRef screenImage = CGBitmapContextCreateImage(cgcontext);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, 480);
// Here I flip the whole image, so if I flip the text above, then
// it ends up upside down.
CGContextScaleCTM(context, 1, -1); 
CGContextDrawImage(context, 
    CGRectMake(0, 0, 320, 480), screenImage);
CGContextRestoreGState(context);

CGImageRelease(screenImage);

How can I mix coordinate systems? How can I draw my text right side up with ULC origin?

1

There are 1 answers

0
Peter Hosey On

Flipping the co-ordinate system means you will draw upside down. You can't do that transformation without that result. (The reason to do it is when you're going to hand your result off to something that will flip it back, so that upside down will be right-side-up again.)

Everything always draws with positive y going up and negative y going down. The text rises toward positive y, and descends below the baseline toward negative y. Consecutive lines' baselines have lower and lower y positions. The same is true of images and (non-textual) paths—everything draws this way.

What you do by transforming the co-ordinate system is not change how things draw; they always draw with positive y going up. To transform the co-ordinate system is to redefine up and down. You make positive y into negative y, and vice versa. You also change where 0, 0 is.

So what you need to do is not to flip the co-ordinate system, but to (only) translate it. You need to translate up by the entire height of the context, minus the height of a line of text. Then, with 0,0 defined as that position, you can show your text at 0,0 and it will draw from that position, and the right way up (and down).

Or, don't translate, and just show the text from that point. Either way will work.

I'm pretty sure you don't need and won't want any transformation in the destination context. The translation (if you translate) should happen in the bitmap context.