你的问题有点不太清晰,关于“最好”的矩形具体指什么并没有明确说明。我假设你是指在打印时可以100%显示的最大矩形。
因此,让我们先确保我们理解打印文档图形对象的“原点”以及OriginAtMargins属性如何影响此原点位置。
OriginAtMargins-获取或设置一个值,表示与页面相关联的图形对象的位置是否位于用户指定的页边距内部或页面的可打印区域的左上角。
- MSDN上的PrintDocument Class Definition
如果OriginAtMargins
设置为false
(默认值),则图形对象将调整为可打印区域矩形(对于我的激光打印机,每个页面边缘约有5/32的空白,旧的激光打印机可能更多,新的喷墨打印机可以打印到边缘,软件PDF打印机将直接打印到边缘)。因此,在我的图形对象中,0,0实际上是在激光打印机的物理页面上的16,16位置(您的打印机可能不同)。
使用默认的1英寸页面边距和OriginAtMargins
设置为true
,图形对象将调整为100,100,650,1100矩形,适用于普通纵向信纸页面。这是每个物理页面边缘内部的一英寸。因此,在您的图形对象中,0,0实际上是在物理页面上的100,100位置。
边距也称为“软边距”,因为它们在软件中定义,不受物理打印设备的影响。这意味着它们将应用于软件中的当前页面大小,并反映实际的页面尺寸(纵向或横向)。
PrintableArea也被称为“硬边距”,它反映了打印设备的物理限制。这将因打印机和制造商而异。由于这些是硬件测量,所以当您将页面设置为横向/纵向时,它们不会旋转。无论如何更改软件打印设置,打印机上的物理限制都不会改变,因此我们需要根据打印文档(方向)的软件设置,在正确的轴上应用它们。
因此,根据您发布的示例代码的粗略模型,这里是一个PrintDocument.PrintPage事件处理程序,它将绘制一个尽可能大但仍然可见的矩形(默认情况下PrintDocument.OriginsAtMargins为false)。如果将PrintDocument.OriginsAtMargins设置为true,则它将在配置的软边距内绘制一个尽可能大但仍然可见的矩形(默认情况下距页面边缘1英寸)。
PrintAction printAction = PrintAction.PrintToFile;
private void printDocument_BeginPrint(object sender, PrintEventArgs e)
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
我认为你在问题中寻找的是确定可用宽度和可用高度的两行代码。这两行代码考虑了软边距或硬边距以及打印文档是横向还是纵向配置。
我使用
Math.Floor()
简单地舍弃小数点后的任何内容(例如:817.96 -> 817),以确保可用宽度和高度刚好在可用尺寸内。我在“安全失败”,如果您想要,可以维护基于浮点数的坐标(而不是整数),只需小心观察会导致裁剪图形的四舍五入误差(如果将817.96四舍五入到818,然后打印机驱动程序决定那不再可见)。
我在 Dell 3115CN、Samsung SCX-4x28 和 CutePDF 软件打印机上测试了此过程,包括横向和纵向以及硬边距和软边距。如果这没有充分解决您的问题,请考虑修改您的问题以澄清“magic rectangle”和“best rectangle”。
编辑说明:“软边距”相关注释
软边距应用于软件中,不考虑打印机的硬件限制。这是有意为之的设计。如果您想要将软边距设置在可打印区域之外,则输出可能会被打印机驱动程序裁剪。如果这对您的应用程序不利,请在程序代码中调整边距。您可以防止用户选择超出可打印区域的边距(或者在他们这样做时警告他们),或者在实际开始打印(绘制)文档时,在您的代码中强制执行一些最小/最大条件。
示例情况:如果您在Microsoft Word 2007中将页面边距设置为0,0,0,0,则会弹出一个警告对话框,显示“一个或多个边距设置在页面的可打印区域之外。选择“修复”按钮以增加相应的边距。”如果您点击修复,Word将简单地将硬边距复制到软边距中,因此对话框现在显示所有边距为0.16英寸(我的激光打印机的能力)。
这是预期的行为。如果用户忽略了警告并使用了0,0,0,0页面边距,那么Microsoft Word打印页面被剪裁不是一个错误/问题。在您的应用程序中也是一样的。您需要根据适当的使用情况强制执行限制。可以通过警告对话框或在代码中更强制地强制执行限制(不提供用户选择)来实现。
备选策略
好的,也许您不仅想获取硬边距,而是想获取软边距,并在打印时强制软边距保持在可打印区域内。让我们开发另一种策略。
在此示例中,我将使用边距作为原点,并允许用户选择任何边距,但我将在代码中强制选择的边距不超出可打印区域。如果所选边距超出了可打印区域,我将简单地调整它们以使其位于可打印区域内。
PrintAction printAction = PrintAction.PrintToFile;
private void printDocument_BeginPrint(object sender, PrintEventArgs e)
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)