我正在尝试创建一个可在iOS设备上运行的PDF(仅限iPad)。我创建了PDF,我可以在其中编写文本和图形。但是我很难写出旋转的文本,这样文本就会旋转,但原点会保持不变。这是我想要实现的输出的图像:
我像这样创建PDF:
-(void)drawPDF:(NSString*)fileName
{
self.pageSize = CGSizeMake(792, 612);
// Create the PDF context using the default page size of 612 x 792.
UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
// Get the graphics context.
context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, 654);
CGContextScaleCTM(context, 1.0, -1.0);
UIFont *font = [UIFont fontWithName:@"Helvetica-Light" size:8];
[self drawText:@"here is a really long line of text so we can see" withFrame:CGRectMake(400, 100, 50, 50) withFont:font rotation:-50];
// Close the PDF context and write the contents out.
UIGraphicsEndPDFContext();
}
然后我有这个用于绘制文本的功能,我尝试了很多变种:
-(void)drawText:(NSString *)text withFrame:(CGRect)rect withFont:(UIFont *)font rotation:(float)degrees
{
float radians = [PDFMaker DegreesToRadians:degrees];
NSDictionary *attribs = @{NSFontAttributeName:[UIFont fontWithName:@"Helvetica-Light" size:10.0]};
CGContextSaveGState(context);
CGPoint pos = CGPointMake(rect.origin.x, -50 - rect.origin.y);
// Translate so we're drawing in the right coordinate space
CGContextScaleCTM(context, 1.0, -1.0);
CGSize stringSize = [text sizeWithAttributes:attribs];
CGContextTranslateCTM(context, 0-stringSize.width/2, 0-stringSize.height/2);
CGContextRotateCTM(context, radians);
CGContextTranslateCTM(context, stringSize.width/2, stringSize.height/2);
[text drawAtPoint:CGPointMake(pos.x, pos.y) withAttributes:attribs];
CGContextRestoreGState(context);
}
但无论我在翻译中玩多少,文本都会跳转,好像围绕原点的轴旋转一样。我已经阅读了其他答案,将原点上的文本旋转到原点并尝试了但是这似乎不起作用(或者更确切地说,我无法使其工作)。我怀疑问题可能与使用PDF上下文有关,但实际上并不知道。任何帮助将不胜感激。
答案 0 :(得分:4)
经过大量的研究和实验,我发现了它。我不确定是否可以回答我自己的问题,如果没有,请告诉我,我会删除它。我认为答案和答案背后的原因可能对其他社区成员有价值。
以下是工作代码:
-(void)drawText:(NSString *)text withFrame:(CGRect)rect withFont:(UIFont *)font
rotation:(float)degrees alignment:(int)alignment center:(BOOL)center
{ //透视矩形 rect = CGRectMake(rect.origin.x,rect.origin.y * -1,rect.size.width,rect.size.height);
float radians = [PDFMaker DegreesToRadians:degrees];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = alignment;
NSDictionary *attributes = @{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle,
NSForegroundColorAttributeName: [Util ColorFromHexString:@"FFFFFF"] };
CGContextSaveGState(context);
// Translate so we're drawing in the right coordinate space
CGContextScaleCTM(context, 1.0, -1.0);
// Save this is we want/need to offset by size
CGRect textSize = [text boundingRectWithSize:rect.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
// Translate to origin, rotate, translate back
CGContextTranslateCTM(context, rect.origin.x, rect.origin.y);
CGContextRotateCTM(context, radians);
CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);
// Center if necessary
if(center==YES)
{
CGContextTranslateCTM(context, 0, (rect.size.height/2)-(textSize.size.height/2));
}
[text drawInRect:rect withAttributes:attributes];
CGContextRestoreGState
}
背后有什么有趣或更有趣的原因。所有这些都写在其他问题和答案中,虽然通常是碎片,其他Q& A中的代码样本的许多代码已被弃用。
原因如此:iOS以左上角的原点开始,就像Windows一样。但是iOS的文本渲染功能是从OSX(从NEXT继承)继承而来,原点在左下角。 PDF通常是从左下角开始编写的,但标准做法是编写一个变换,使其从左上角开始运行。但由于这些是使用Core Text的文本渲染功能,我们再次翻转。因此,您需要考虑并确保转换正确,否则您的文字将颠倒,向后或在屏幕外打印。
之后我们需要在原点旋转,至少我设置的方式现在位于左下角。如果我们不在原点旋转,我们的文本似乎会飞来飞去:离原点越远,它就越飞。所以我们转换为原点,旋转,然后转换回来。这不是PDF独有的,适用于Quartz中的任何旋转。
最后有一篇关于在iOS设备上制作PDF的社论评论不应该被忽视:它可能很慢而且消耗大量内存。当你想要高质量的矢量输出打印或嵌入像Office文档这样的东西时,我觉得对少量页面做的很好。图表,图表,可能是游戏说明,可打印的门票..小东西。但是,如果您打印的内容类似于大型报告或书籍,则最好在服务器上生成PDF。