计算格式化字符串的宽度& C#中的高度

时间:2009-07-24 17:09:05

标签: c# printing xslt gdi+ gdi

我正在尝试使用XSL(XML-FO)生成PDF以从数据库转换生成的XML。

由于在本文档的分页方面存在复杂的规则,因此在生成将由XSL使用的XML时,在确定分页符时进行计算。我注意到我用这些计算得到了不一致的结果。例如,高度所需的打印区域为9英寸,然后我将其乘以72(每英寸72点)= 648点转换为点数。

因此,对于每一行,我使用MeasureString来获取行的高度,然后从648中减去该行以查看是否仍有可用空间来打印该行。但是无论何时确定分页符,都会有一个留在底部的大空格。就好像648pt转换是错误的。现在我也担心MeasureString方法返回的高度也可能是错误的。

我为这篇长篇文章道歉但我很欣赏任何关于我可能做错的意见。

非常感谢!

3 个答案:

答案 0 :(得分:2)

我认为最大的问题是您正在使用GDI方法来测量将在PDF中显示的字符串。这只是不够准确。 (即使你得到相同的字体,他们也会使用我记忆中的不同渲染技术。)

所以,你应该尝试其他形式的计算。一个简单的第一步是估计每行的字符数,然后估计每行的高度,就像它在PDF中出现一样。然后,只需使用这些数字。一旦接近,您可以通过关注特定字符来改进估算技术。 (您可能不希望达到计算字距调整的水平。)

另一种技巧可能是做一些我在过去的项目中工作的东西。使用iTextSharp,我们不得不在页面上对角添加空心文本(作为一种水印)。由于文本未知,我们猜测原始字体大小。然后代码进入一个循环,它将测量渲染文本的大小,并向上或向下调整,直到填充页面的大小合适,而不剪切任何文本。 (所有这些猜测和测量都是通过iTextSharp完成的。)

答案 1 :(得分:0)

我假设您在MeasureString类上使用方法System.Drawing.Graphics方法。您必须将PageUnit属性设置为GraphicsUnit.Point才能获得分数。

XSL-FO很可能不会以与GDI +相同的方式呈现。特别是包装文本的算法会有所不同。

但是,假设PageUnit是正确的并且您有一个简单的布局不涉及已被包装的文本,那么在估算XSL-FO生成的PDF的大小时,您可能忽略了一些明显的东西。也许,您可以尝试以1英寸的间隔将页面大小从1英寸更改为9英寸。然后,您可以使用标尺来测量多余的空白,并尝试确定页面大小和多余空白之间的关系。然后,您应该重新访问您的代码,以确定您对文本大小的错误假设。

答案 2 :(得分:0)

几年前我遇到了一个非常类似的问题。

我在自己的项目中发现,通过P / Invoke,我使用旧的Win32 gdi函数获得了更好的结果,用于文本指标(http://msdn.microsoft.com/en-us/library/dd144821(VS.85).aspx)。它返回的报价与GDI + MeasureString不同。它们与PDF中的内容更为一致。