我正在尝试在我的新 Cocoa 应用程序中实现打印。除了缩放(即以 75%、125% 等打印)之外,一切都工作正常一段时间了。
据我从 Apple 文档中得知,该程序应该根据比例因子调整从 rectForPage: 方法返回的矩形。我发现了一些似乎可以这种方式工作的 Apple 代码示例,以及 cocoabuilder 上的一篇旧帖子。
http://www.cocoabuilder.com/archive/cocoa/211683-scaled-printing.html
我的 rectForPage: 代码如下所示:
NSPrintInfo *pi = [[NSPrintOperation currentOperation] printInfo];
NSSize paperSize = [pi paperSize]; // Calculate the page dimensions in points
// Convert dimensions to the scaled view
CGFloat pageScale = [[[pi dictionary] objectForKey:NSPrintScalingFactor] floatValue];
CGFloat topMargin = [pi topMargin];
CGFloat leftMargin = [pi leftMargin];
CGFloat bottomMargin = [pi bottomMargin];
CGFloat rightMargin = [pi rightMargin];
CGFloat pageHeight = (paperSize.height - topMargin - bottomMargin) / pageScale;
CGFloat pageWidth = (paperSize.width - leftMargin - rightMargin) / pageScale;
NSRect bounds = [self bounds];
NSRect actualPageRect = NSMakeRect(
NSMinX(bounds),
NSMinY(bounds),
pageWidth * pageScale,
pageHeight * pageScale);
return actualPageRect;
Run Code Online (Sandbox Code Playgroud)
但是,我无法让它正常工作。无论此方法返回什么大小的矩形,输出始终以 100% 打印。我确实验证了实际页面矩形会根据比例设置而变化,并且打印输出将裁剪到指定的矩形,但它不会缩放。我本来以为苹果会根据比例因子来缩放视图,但事实并非如此。
经过长时间的研究,我放弃了这个策略,并尝试了另一种方法。现在我有 rectForPage: 总是返回实际页面大小,并且我更改了 drawRect: 以使用仿射变换绘制缩放输出:
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
NSAffineTransform* xform = [NSAffineTransform transform];
[xform scaleXBy:pageScale yBy:pageScale];
[xform concat];
[self layoutReport];
[xform invert];
[xform concat];
}
Run Code Online (Sandbox Code Playgroud)
我还修改了knowPageRange:方法以考虑缩放。
结果是——这有效。该程序现在可以生成我想要的任何缩放输出,并且它可以正确分页。但我很确定这是错误的解决方案。我认为一定有一些我遗漏的细节,可以通过缩放从 rectForPage: 返回的矩形来正确缩放,但我在这一点上感到困惑。既然它有效,我可以保留它,但如果这不是正确的方法,我宁愿修复它。
让我们从文档rectForPage:中 ,的定义开始:
\n\n\n由子类实现以确定要打印页码的视图部分
\npage。
和
\n\n\n\n\n定义要打印的视图区域的矩形
\npageNumber。NSZeroRect如果pageNumber超出 view\xe2\x80\x99s 范围,则此方法返回。
所以这些是裁剪矩形。无论您绘制什么,都会被裁剪到该矩形,并且该绘制将被视为该页面的内容。(您也可能会返回该矩形drawRect:,并期望您将跳过在其之外绘制任何内容。)这些矩形既采用边界单位(即,与中的单位相同self.bounds)又采用实际单位(默认为1/72 英寸)。
scalingFactor那么,打印信息呢?
据我所知,截至 10.12.6,AppKit\xe2\x80\x94 尚未为您应用它,您必须自己检索和使用scalingFactor。(我可能会遗漏一些东西。)
缩放绘图drawRect:是一种完全合理的方法。您的页面矩形将保持不变;您在其中的绘图将被缩放。如果scalingFactor是 2,您的绘图将加倍,并且页面矩形内将有四分之一(每个轴上的 1/2)。
由于页面矩形以边界为单位,因此缩放边界(使用setBoundsSize:或scaleUnitSquareToSize:)是另一种方法。然后你的绘图和页面矩形将一致缩放。问题是这适用于屏幕绘图和打印绘图。当您有单独的视图或视图层次结构用于打印时,它最有意义。
因此,根据参考文档(以及我在 10.12.6 上的实验),我认为你是对的。
\n\n至于文档中的示例,我认为它是为 TextEdit 的页面视图之类的内容编写的,其中边距是视图绘图的一部分(例如,它会被裁剪掉 和)topMargin。bottomMargin也就是说,我建议您在发现示例代码似乎错误、不清楚或建立在未声明的假设之上时,随时提交错误。