帮助在 Quartz 中创建 PDF

发布于 2024-12-06 11:20:15 字数 3510 浏览 0 评论 0原文

我正在阅读 iOS 绘图和打印指南(http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GeneratePDF/GeneratePDF.html#//apple_ref/doc/uid/ TP40010156-CH10-SW1)。我正在尝试对其进行一些修改以获得我需要的东西。我基本上是想绘制一个彩色矩形、来自 NSString 的文本、另一个彩色矩形、来自 NSString 的第二个文本块。我创建了两个框架设置器,每个字符串一个,并调用 renderPage: 方法两次。然而,它在屏幕底部颠倒地绘制了我的文本,我不知道为什么。 (我在//评论中提出了一些问题,以了解为什么代码会这样工作,以及在理解它为什么不工作时我必须遗漏什么)。谢谢!

 CFAttributedStringRef overviewText = CFAttributedStringCreate(NULL, (CFStringRef)overview, NULL);
    CFAttributedStringRef resultText = CFAttributedStringCreate(NULL, (CFStringRef)result, NULL);
    if (overviewText != NULL || resultText != NULL) {
        CTFramesetterRef overviewFramesetter = CTFramesetterCreateWithAttributedString(overviewText);
        CTFramesetterRef resultFramesetter = CTFramesetterCreateWithAttributedString(resultText);
        if (overviewFramesetter != NULL  || resultFramesetter != NULL) {
            // Create the PDF context using the default page size of 612 x 792.
            UIGraphicsBeginPDFContextToFile(filePath, CGRectZero, nil);

            CFRange currentRange = CFRangeMake(0, 0);
            NSInteger currentPage = 0;
            BOOL done = NO;

            do {
                // Mark the beginning of a new page.
                UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, PDF_WIDTH, PDF_HEIGHT), nil);

                [self drawPDFTitle:fileName];
                [self drawRectangleAtPosition:CGPointMake(MARGIN, 50)];

                // Draw a page number at the bottom of each page
                currentPage++;
                [self drawPageNumber:currentPage];

                // Render the current page and update the current range to
                // point to the beginning of the next page.
                currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:overviewFramesetter];
                NSLog(@"%ld, %ld", currentRange.location, currentRange.length);

            // at first I tried doing this, but would get an error at the CFRelease in renderPage method.  I'm not sure as to why I get the error since the function renderPage: seems to be the method to write the data to the PDF context.
currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:resultFramesetter];

                // If we're at the end of the text, exit the loop.
                if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)overviewText))
                    done = YES;
            } 
            while (!done);

            do {
                // I do not know why I would need to flip the context again since the method renderPage: already does this for me right?
                //CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, PDF_HEIGHT);
                //CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
                currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:resultFramesetter];
                NSLog(@"2nd loop: %ld, %ld", currentRange.location, currentRange.length);
                if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)overviewText))
                    done = YES;
            }
            while (!done);

            // Close the PDF context and write the contents out.
            UIGraphicsEndPDFContext();

            // Release the framewetter.
            CFRelease(overviewFramesetter);

        } 

I'm reading through the Drawing and Printing Guide for iOS (http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GeneratingPDF/GeneratingPDF.html#//apple_ref/doc/uid/TP40010156-CH10-SW1). I'm trying to modify it a bit in order to get what I need. I basically am trying to draw a colored rectangle, text from a NSString, another colored rectangle, a second block of text from NSString. I create two framesetters, one for each string, and call the renderPage: method twice. However, it draws my text in a upside down, at the bottom of the screen, and I'm not sure why. (I put some questions in the //comments to see why the code works the way it does, and what I must be missing in understanding why it isn't working). Thanks!

 CFAttributedStringRef overviewText = CFAttributedStringCreate(NULL, (CFStringRef)overview, NULL);
    CFAttributedStringRef resultText = CFAttributedStringCreate(NULL, (CFStringRef)result, NULL);
    if (overviewText != NULL || resultText != NULL) {
        CTFramesetterRef overviewFramesetter = CTFramesetterCreateWithAttributedString(overviewText);
        CTFramesetterRef resultFramesetter = CTFramesetterCreateWithAttributedString(resultText);
        if (overviewFramesetter != NULL  || resultFramesetter != NULL) {
            // Create the PDF context using the default page size of 612 x 792.
            UIGraphicsBeginPDFContextToFile(filePath, CGRectZero, nil);

            CFRange currentRange = CFRangeMake(0, 0);
            NSInteger currentPage = 0;
            BOOL done = NO;

            do {
                // Mark the beginning of a new page.
                UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, PDF_WIDTH, PDF_HEIGHT), nil);

                [self drawPDFTitle:fileName];
                [self drawRectangleAtPosition:CGPointMake(MARGIN, 50)];

                // Draw a page number at the bottom of each page
                currentPage++;
                [self drawPageNumber:currentPage];

                // Render the current page and update the current range to
                // point to the beginning of the next page.
                currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:overviewFramesetter];
                NSLog(@"%ld, %ld", currentRange.location, currentRange.length);

            // at first I tried doing this, but would get an error at the CFRelease in renderPage method.  I'm not sure as to why I get the error since the function renderPage: seems to be the method to write the data to the PDF context.
currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:resultFramesetter];

                // If we're at the end of the text, exit the loop.
                if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)overviewText))
                    done = YES;
            } 
            while (!done);

            do {
                // I do not know why I would need to flip the context again since the method renderPage: already does this for me right?
                //CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, PDF_HEIGHT);
                //CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
                currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:resultFramesetter];
                NSLog(@"2nd loop: %ld, %ld", currentRange.location, currentRange.length);
                if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)overviewText))
                    done = YES;
            }
            while (!done);

            // Close the PDF context and write the contents out.
            UIGraphicsEndPDFContext();

            // Release the framewetter.
            CFRelease(overviewFramesetter);

        } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

攒眉千度 2024-12-13 11:20:15

您必须转换 PDF 坐标,因为 PDF 坐标系与石英坐标系不同(y 轴被翻转)。有关详细信息,请查看 http://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_overview/dq_overview.htmlQuartz 2D 坐标系) 。

您可以使用以下代码进行翻译 -

CGContextTranslateCTM(pdfContext, 0.0, pageRect.size.height);
CGContextScaleCTM(pdfContext, 1.0, -1.0);

You will have to transform the PDF co-ordinates because the PDF co-ordinate system is different from the quartz co-ordinate system (the y-axis is flipped). For details, have a look at http://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_overview/dq_overview.html (Quartz 2D Co-ordinate systems).

You can translate using the following code-

CGContextTranslateCTM(pdfContext, 0.0, pageRect.size.height);
CGContextScaleCTM(pdfContext, 1.0, -1.0);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文