Text rotation issue in CGContext

231 Views Asked by At

I'm using CGContext to create a PDF file containing some text labels. Because the text would normally be upside down, I do a flip along the x axis and a translation:

CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, textRect);    

// *** ROTATION CODE FROM BELOW IS ADDED HERE ***

// Flip the coordinate system
CGContextTranslateCTM(context, 0, 2 * textRect.origin.y + textRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

NSAttributedString *attString = [[NSAttributedString alloc] initWithString:string attributes:attributes];

CTFramesetterRef aframesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attString);
CTFrameRef frame = CTFramesetterCreateFrame(aframesetter, CFRangeMake(0, [attString length]), path, NULL);

CTFrameDraw(frame, context);

CFRelease(frame);
CFRelease(path);
CFRelease(aframesetter);

This draws text on a page like this: enter image description here

Now I want all text labels to be rotated by 180°. This is what I do:

CGContextTranslateCTM(context, -1 * (textRect.origin.x + textRect.size.width/2), -1 * (textRect.origin.y + textRect.size.height/2));
CGContextRotateCTM(context, M_PI);
CGContextTranslateCTM(context, (textRect.origin.x + textRect.size.width/2), (textRect.origin.y + textRect.size.height/2));

But this moves the labels out of the page:

enter image description here

When I reduce the rotation angle to PI/16 or PI/8 it results in this output (labels are filled red):

enter image description here

enter image description here

What's the problem here?

1

There are 1 best solutions below

0
On

In the first step you move the origin of your coordinates to a point below your view, probably not where you expect it to be due to the factor 2.

CGContextTranslateCTM(context, 0, 2 * textRect.origin.y + textRect.size.height);

I would expect this should be moving origin from upper left edge to lower left edge (it doesn't look like, but I can not really say from your code)
Then you flip it horizontally and it seems you see what you expect, but I would expect it to be too far down (again this might be because textRect is not what I expect it to be)

Next you move the origin to a point to the left of the view by half of the view's size + it's position and up again to some point which might be half of the views height above (if I got your first translation right) This is probably not where you want it to be - I expect you want it to be in the middle of the view, which might (or might not) be done by

CGContextTranslateCTM(context, textRect.size.width/2, -textRect.size.height/2);

I expect you to be still in the same context.

Now you rotate which should be just fine and finalize with an adjustment of the origin, that has the same issue as the one before ...