Why does CGPDFPageGetDrawingTransform() crash with SIGABRT when specifying a rotation? - iphone

When I call CGPDFPageGetDrawingTransform() with a rotation argument, the application crashes. If I specify no rotation, there is no crash.
Here is my drawLayer:inContext: method:
- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context
{
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
CGRect boundingBox = CGContextGetClipBoundingBox(context);
CGContextFillRect(context, boundingBox);
//convert to UIKit native coodinate system
CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//Rotate the pdf_page
CGAffineTransform pfd_transform = CGPDFPageGetDrawingTransform(self.page, kCGPDFCropBox, self.frame, 58.46f, true);
CGContextSaveGState (context);
CGContextConcatCTM (context, pfd_transform);
CGContextClipToRect (context, self.frame);
CGContextDrawPDFPage (context, self.page);
CGContextRestoreGState (context);
}
In the long run, I would like to rotate the pdf dynamically to follow a users heading. Maybe I am going at this all wrong...
Thank you for your time.

From the documentation for CGPDFPageGetDrawingTransform:
CGAffineTransform CGPDFPageGetDrawingTransform (CGPDFPageRef page, CGPDFBox box, CGRect rect, int rotate, bool preserveAspectRatio);
Parameters
rotate An integer, that must be a multiple of 90, that specifies the angle by which the specified rectangle is rotated clockwise.
58.46f is neither an integer nor a multiple of 90.

Related

iPhone - Draw some text with CGContext : ok but... mirrored

When I draw some text using CGContext, it is drawn mirrored.
I tried to apply some transformations, then it is draw well, but then the rest of the drawing and all coordinates seems to be draw bad.
I tried to save and restore the context, before and ater drawing the text (and aplying transformation), but that does not help.
How some text must be drawn onto a View using CGContext without affecting the rest of the drawing, nor the onscreen CGPoint coords for that text ?
Can you clarify what you mean as 'mirrored'? Here is some code for drawing some black text. It should not be 'mirrored'.
CGRect viewBounds = self.bounds;
CGContextTranslateCTM(ctx, 0, viewBounds.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextSetRGBFillColor(ctx, 0.0, 1.0, 0.0, 1.0);
CGContextSetLineWidth(ctx, 2.0);
CGContextSelectFont(ctx, "Helvetica", 10.0, kCGEncodingMacRoman);
CGContextSetCharacterSpacing(ctx, 1.7);
CGContextSetTextDrawingMode(ctx, kCGTextFill);
CGContextShowTextAtPoint(ctx, 100.0, 100.0, "SOME TEXT", 9);
I think you have to reverse the text matrix :
CGAffineTransform transform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
CGContextSetTextMatrix(context, transform);

Why is my text flip over when using CGContextShowAtPoint?

I am writing a simple practice. However, my text is flip upside down when I trying to use CGContext to put some string on the UIView, I am wondering why and how to change it into correct format.
Here is my code in the drawRect
char *string = "TEST";
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath(context);
CGContextSelectFont (context,"Helvetica-Bold",12, kCGEncodingMacRoman);
CGContextShowTextAtPoint(context, 5, 5, string, strlen(string));
CGContextClosePath(context);
Thanx for your help.
CoreGraphics uses cartesian coordinates, so you need to translate your context before doing any drawing
CGContextRef context = UIGraphicsGetCurrentContext();
// transforming context
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// your drawing code
Quartz2D has an inverted y axis - handy eh? If you are inside a drawRect method, you can use the following to flip the text over.
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
Another way is;
transform = CGAffineTransformMake(1.0,0.0,0.0,-1.0,0.0,0.0);
CGContextSetTextMatrix(context, transform);
Or on one line;
CGContextSetTextMatrix(context, CGAffineTransformMake(1.0,0.0, 0.0, -1.0, 0.0, 0.0));
Use the UIKit additions in NSString:
NSString *string = #"TEST";
[string drawAtPoint:CGPointMake(5, 5)
withFont:[UIFont boldSystemFontOfSize:12]];

UIImage Rotation Offset

I have the following code
- (void)ComputeRotationWithRadians:(CGFloat)rad {
CGFloat width = exportImage.size.width;
CGFloat height = exportImage.size.height;
UIGraphicsBeginImageContext(CGSizeMake(width, height));
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGContextScaleCTM(ctxt, 1.0, -1.0);
CGContextTranslateCTM(ctxt, 0.0, -exportImage.size.height);
CGContextRotateCTM(ctxt, rad);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), exportImage.CGImage);
exportImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[imageView setImage:exportImage];
}
The issue is that the rotation happens around the bottom left corner, when it has been calculated around the center. Is there anyway to change this?
Your code is translating the matrix before rotating it. Try flipping the calls to CGContextConcatCTM and CGContextTranslateCTM so you rotate first. Or perhaps you are looking for something else?

Drawing a PDF Right-Side-Up in CGContext

I'm overriding the drawRect: method in a custom UIView, and I'm doing some custom drawing. All was going well, until I needed to draw a PDF resource (a vector glyph, to be precise) into the context. First I retrieve the PDF from a file:
NSURL *pdfURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"CardKit.bundle/A.pdf"]];
CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDoc, 1);
Then I create a box with the same dimensions as the loaded PDF:
CGRect box = CGPDFPageGetBoxRect(pdfPage, kCGPDFArtBox);
Then I save my graphics state, so that I don't screw anything up:
CGContextSaveGState(context);
And then I perform a scale+translate of the CTM, theoretically flipping the whole context:
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0.0, rect.size.height);
I then scale the PDF so that it fits into the view properly:
CGContextScaleCTM(context, rect.size.width/box.size.width, rect.size.height/box.size.height);
And finally, I draw the PDF and restore the graphics state:
CGContextDrawPDFPage(context, pdfPage);
CGContextRestoreGState(context);
The issue is that there is nothing visible drawn. All this code should theoretically draw the PDF glyph into the view, right?
If I remove the scale+translate used to flip the context, it draws perfectly: it just draws upside-down.
Any ideas?
Try doing the translate before the scale:
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, currentPage);
CGContextSaveGState(context);
CGRect box = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
CGContextScaleCTM(context, self.bounds.size.width/box.size.width, self.bounds.size.height/box.size.height);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
This is the right answer to your question
To scale before translate, I think we can put minus when translate.
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0.0, -rect.size.height);
This flips everything right side up for me:
pdfDisplayView.layer.geometryFlipped = YES; //(NO)

How to do a radar animation in the iPhone SDK?

Does anyone know how to animate a radar animation like the image below?
alt text http://img197.imageshack.us/img197/7124/circle0.png
With it growing outwards? I have to draw the circle using Quartz or some other way?
To draw a static circle in a UIView subclass:
- (void)drawRect:(CGRect)rect
{
CGRect rect = { 0.0f, 0.0f, 100.0f, 100.0f };
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextSetLineWidth(context, 2.0f);
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
}
From there you just need to animate it with a timer, vary the size of the rect, and add more circles.