Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flipped NSString drawing in CGContext

Tags:

iphone

I try to draw a string in this texture:

http://picasaweb.google.it/lh/photo/LkYWBv_S_9v2d6BAfbrhag?feat=directlink

but the green numbers seem vertical flipped. I've created my context in this way:

    colorSpace = CGColorSpaceCreateDeviceRGB();
data = malloc(height * width * 4);
context = CGBitmapContextCreate(data, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

and i've draw the strings:

    UIGraphicsPushContext(context);

for(int i=0;i<packs.size();++i)
{
    CGPoint points[4] = 
    {
        gltextures[i].texCoords[0] * size.width,        //0
        gltextures[i].texCoords[1] * size.height,       //1

        gltextures[i].texCoords[2] * size.width,        //2
        gltextures[i].texCoords[3] * size.height,       //3

        gltextures[i].texCoords[4] * size.width,        //4
        gltextures[i].texCoords[5] * size.height,       //5

        gltextures[i].texCoords[6] * size.width,        //6
        gltextures[i].texCoords[7] * size.height        //7

    };

    CGRect debugRect = CGRectMake
    (
     gltextures[i].texCoords[0] * size.width, 
     gltextures[i].texCoords[1] * size.height, 
     gltextures[i].width, 
     gltextures[i].height
     );
    CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextAddLines(context, points, 4);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathStroke);  

    NSString* s = [NSString stringWithFormat:@"%d",gltextures[i].texID];
    UIFont* font = [UIFont fontWithName:@"Arial" size:12];
    CGContextSetRGBFillColor(context, 0, 1, 0, 1);
    [s drawAtPoint:points[0] withFont:font];
}
UIGraphicsPopContext();

The transformation matrix seems the Identity matrix... no CGAffineTransform is applied to THIS context. If the string is flipped, maybe, all my images are flipped! Any suggestion?

PS: sorry for my english ;)

like image 290
Chiodo Avatar asked Dec 22 '22 09:12

Chiodo


2 Answers

As describe here, the coordinate system for a context within a UIView or its layer is inverted when compared to the normal Quartz drawing space. However, when using Quartz to draw to an image, this is no longer the case. The UIStringDrawing Cocoa Touch category on NSString that gives you the -drawAtPoint:withFont: method assumes an inverted layout, and that's why you're seeing the flipped text in your image.

One way to work around this would be to save the graphics state, apply an invert transform to the image, draw the text, and restore the old graphics state. This would look something like the following:

CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0f, self.bounds.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);

[text drawAtPoint:CGPointMake(0.0f, 0.0f) withFont:font];

CGContextRestoreGState(context);

This is a fairly crude example, in that I believe it just draws the text at the bottom of the image, but you should be able to adjust the translation or the coordinate of the text to place it where it's needed.

like image 197
Brad Larson Avatar answered Jan 10 '23 07:01

Brad Larson


Better save the text 's matrix before draw, otherwise it will affect other text draw by CoreGraphic:

CGContextSaveGState(ctx);
CGAffineTransform save = CGContextGetTextMatrix(ctx);
CGContextTranslateCTM(ctx, 0.0f, self.bounds.size.height);
CGContextScaleCTM(ctx, 1.0f, -1.0f);
[str drawAtPoint:point withFont:font];
CGContextSetTextMatrix(ctx, save);
CGContextRestoreGState(ctx);
like image 28
Jiejing Zhang Avatar answered Jan 10 '23 07:01

Jiejing Zhang