PdfSharp.Drawing.XGraphics对象有一个MeasureString方法可以返回所需的内容。
var pdfDoc = new PdfSharp.Pdf.PdfDocument();
var pdfPage = pdfDoc.AddPage();
var pdfGfx = PdfSharp.Drawing.XGraphics.FromPdfPage(pdfPage);
var pdfFont = new PdfSharp.Drawing.XFont("Helvetica", 20);
while (pdfGfx.MeasureString("Hello World!").Width > pdfPage.Width)
--pdfFont.Size;
pdfGfx.DrawString("Hello World!", pdfFont
, PdfSharp.Drawing.XBrushes.Black
, new PdfSharp.Drawing.XPoint(100, 100));
这应该会对你有所帮助。请注意,我没有测试这段代码,因为我是在快速写作以帮助你。它可能包含一些编译时错误,但你可以得到大致的思路。
在.NET中,您可以调用Graphics.MeasureString来查找绘制文本的大小。
没错,但是在使用PDFsharp时,您需要调用XGraphics.MeasureString。
我曾遇到过类似的问题,因此我实现了这个扩展方法:
public static double MeasureHeight(this PdfSharp.Drawing.XGraphics gfx, string text, PdfSharp.Drawing.XFont font, int width)
{
var lines = text.Split('\n');
double totalHeight = 0;
foreach (string line in lines)
{
var size = gfx.MeasureString(line, font);
double height = size.Height + (size.Height * Math.Floor(size.Width / width));
totalHeight += height;
}
return totalHeight;
}
Public Function PrintString(text As String, ft As XFont, rect As XRect, graph As XGraphics, b As SolidBrush, Optional tf As XTextFormatter = Nothing) As Integer
If Not IsNothing(tf) Then
tf.DrawString(text, ft, b, rect)
Else
Dim drawLeft As New XStringFormat
drawLeft.Alignment = XStringAlignment.Near
graph.DrawString(text, ft, b, rect, drawLeft)
End If
Dim width As Double = graph.MeasureString(text, ft).Width
Dim multiplier As Integer = 0
While width > 0
multiplier += 1
width -= rect.Width
End While
Dim height As Double = (graph.MeasureString(text, ft).Height) * multiplier
Return height
End Function
代码解释:
首先,打印文本。我包含了一个可选的XTextFormatter(称为tf),因为在我的应用程序中可以交替使用XGraphics或XTextFormatters。
然后,通过MeasureString().Width计算文本的长度。
接下来,计算有多少行文本。这是通过将之前找到的文本总长度除以提供的矩形框的宽度来完成的。我在这里使用while循环完成。
将文本的高度(使用graph.MeasureString().Height)乘以行数。这是您的文本的最终高度。
返回高度值。现在,调用PrintString()函数将打印所提供的文本,并在打印文本后返回打印文本的高度。
OP询问如何根据可用宽度和字体计算文本高度。Windows .NET提供了一个API调用,可以使用宽度参数进行计算;我正在使用的PDFsharp版本(0.9.653,.NET 1.1)没有这个功能。
我的解决方案是使用.NET API调用,并为自定义创建的位图对象分配一个Graphics对象来获取答案。
对我有效的方法是使用具有100 DPI分辨率(关键)并且恰好是纵向页面大小的位图(可能不太关键)。
然后,我只需询问.NET在该位图上绘制时的像素大小即可。
您可能还需要将单位从英寸的1/100转换为点(用于PDFsharp)。
''' 适应代码 - 这不是经过测试甚至编译的 - 购买时请注意! ''' 目标:Visual Basic,.NET 1.1(VS2003)[根据需要进行调整]PDFsharp包含一个XTextFormatter类,可用于绘制带有换行的文本。
但它无法确定所需文本的高度。受@Wakka02评论的启发,我改进了这个类,生成了XTextFormatterEx类。
在我看来,它也回答了原始问题,因此我发布了一个答案。
我知道这是一个老问题,答案可能对提问者没有帮助,但这是一个经常被问到的问题,答案可能会帮助其他人。
新类有500行代码 - 我认为这对于此帖子来说太多了。
源代码可以在PDFsharp论坛上找到:
http://forum.pdfsharp.net/viewtopic.php?p=9213#p9213
它还可以在我的博客中找到:
http://developer.th-soft.com/developer/pdfsharp-improving-the-xtextformatter-class-measuring-the-height-of-the-text/
当使用新类时,您可以首先调用PrepareDrawString
来找出文字适合的长度以及适合的高度。然后您的解码器可以绘制准备好的文本或准备另一个文本或使用不同矩形准备相同的文本。
我在工作中使用的新类: XTextFormatterEx tf = new XTextFormatterEx(gfx); int lastCharIndex; double neededHeight;
// Draw the text in a box with the optimal height
// (magic: we know that one page is enough).
XRect rect = new XRect(40, 100, 250, double.MaxValue);
//tf.Alignment = ParagraphAlignment.Left;
tf.PrepareDrawString(text, font, rect,
out lastCharIndex, out neededHeight);
rect = new XRect(40, 100, 250, neededHeight);
gfx.DrawRectangle(XBrushes.SeaShell, rect);
// Both variants should look the same.
// Optimized version: draw the prepared string.
tf.DrawString(XBrushes.Black, XStringFormats.TopLeft);
准备文本会多次调用 MeasureString。稍后,可以绘制已准备好的文本,而无需再次调用 MeasureString。
截至今天(2015 年 7 月 17 日),XTextFormatterEx 类(就像原始的 XTextFormatter 一样)使用 XFont 类的内部字段。这需要在编译类时进行特殊处理。我决定将我的 XTextFormatterEx 类复制到 PDFsharp 文件夹中,在下载完整的 PDFsharp 1.32 源码包后。
任何尝试修改 XTextFormatter 或 XTextFormatterEx 类的人都将面临同样的问题。
我希望 PDFsharp 的未来版本可以解决这个问题,允许将这些类的修改版本包含在应用程序项目中。