【问题标题】:How do I rotate text in Quartz running on iOS so the origin does not move?如何在 iOS 上运行的 Quartz 中旋转文本以使原点不动?
【发布时间】:2015-04-27 15:18:49
【问题描述】:

我正在尝试创建可在 iOS 设备(仅限 iPad)上运行的 PDF。我已经创建了我的 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 上下文有关,但真的不知道。任何帮助将不胜感激。

【问题讨论】:

    标签: ios objective-c pdf-generation quartz-2d


    【解决方案1】:

    经过大量研究和实验,我想通了。我不确定是否可以回答我自己的问题,如果没有,请让我知道,我会删除它。我确实认为答案及其背后的原因可能对其他社区成员很有价值。

    这是工作代码:

    -(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
    

    }

    同样有趣或更有趣的是它背后的原因。所有这些都写在其他问题和答案中,尽管通常是分段的,并且其他问答中的代码示例中的许多代码已经被弃用了。

    所以原因:iOS 以左上角的原点矩阵开头,如 Windows。但是iOS的文本渲染功能是从OSX继承下来的(从NEXT继承而来),出处在左下角。 PDF 通常从左下角编写,但标准做法是编写转换,以便从左上角运行。但由于这些是使用 Core Text 的文本渲染函数,我们再次翻转。因此,您需要考虑并正确进行转换,否则您的文本将上下颠倒或打印在屏幕外。

    之后我们需要在原点旋转,至少按照我设置的方式,现在位于左下角。如果我们不在原点旋转,我们的文本似乎会飞来飞去:离原点越远,它飞得越多。所以我们平移到原点,旋转,然后平移回来。这不是 PDF 独有的,适用于 Quartz 中的任何旋转。

    最后一篇关于在 iOS 设备上制作 PDF 的编辑评论不容忽视:它可能会很慢并且会消耗大量内存。我认为当您想要高质量的矢量输出以打印或嵌入到 Office 文档之类的东西中时,对少量页面执行此操作是可以的;图表,图表,也许是游戏说明,可打印的门票......小东西。但如果您要打印大型报告或书籍等内容,最好在服务器上生成 PDF。

    【讨论】:

    • 当然欢迎你回答你自己的问题——尤其是像这样一个非常好的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 2019-08-04
    • 2020-10-21
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多