Drawing a PDF Right-Side-Up in CGContext - iphone

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)

Related

iPhone - Image drawn upside down into a CGGraphic context (custom UIView)

I have a custom view with that code :
- (void)drawRect:(CGRect)rect
{
UIImage* theImage = [UIImage imageNamed:#"blue_arrow"];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGPoint posOnScreen = self.center;
CGContextDrawImage(context, CGRectMake(posOnScreen.x - theImage.size.width/2,
posOnScreen.y - theImage.size.height/2,
theImage.size.width,
theImage.size.height),
theImage .CGImage);
}
The image is an arrow, pointiing to the top.
But when drawn, it is draw upside down, pointing to bottom.
What causes that problem ?
How may I correct that, naturally without side effect ?
This is because Core Graphics is using a flipped coordinate system.
You could try flipping the object you're drawing to using the isFlipped property.
Or you could try using this code in your drawing method (Source):
CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

Problem with using quartz 2d to draw a PDF

I have problem with quartz 2d to draw a pdf, I have it up and running fine
but I am not so sure how to progress to the next page
Here's the code
-(void)drawInContext:(CGContextRef)context{
CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
CGContextSaveGState(context);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, self.bounds, 0, true);
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
}
I know that I can change 1 to x for to get the page but how do i redraw the frame??
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
To make view redraw call
[view setNeedsDisplay];

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]];

how to go to next page of pdf in objective-c if pdf have multi pages

i have multi pages pdf,i want to go to the next page of pdf,
how to go this.
(page -> the page you want to display, pdfReference: a reference to a CGPDFDocumentRef)
pageReference = CGPDFDocumentGetPage(pdfReference, page);
CGContextRef context = UIGraphicsGetCurrentContext();
#try {
CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, scale, -scale);
CGContextSaveGState(context);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(pageReference, kCGPDFCropBox, self.bounds, 0, true);
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, pageReference);
CGContextRestoreGState(context);
}
#finally {
UIGraphicsEndImageContext();
}
insert this into a drawRect:(CGRect) and you are fine to go

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

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.