2009-05-23 106 views

回答

10

在.NET中你可以調用 Graphics.MeasureString找出 大繪製的文本將如何定。

沒錯,但是當使用PDFsharp時,你可以調用XGraphics.MeasureString。

+1

這似乎不是答案。 MeasureString不採用矩形/寬度,所以不能知道繪製的高度 - 或者我錯過了什麼? – noelicus 2012-12-11 12:45:39

+1

使用XGraphics.MeasureString查找單行文本的尺寸。有關自動斷行的代碼,請參閱XTextFormatter類(使用MeasureString())。應該很容易添加一個返回高度的新方法XTextFormatter.MeasureString。我們通常在我們的應用程序中使用MigraDoc,因此我們只向文檔添加文本,MigraDoc關心換行符和分頁符。 – 2012-12-11 12:56:33

20

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)); 

這應該對你有所幫助。請考慮一下,我沒有測試這個代碼,因爲我是爲了幫助而在飛行中寫的。它可能包含一些編譯時錯誤,但您可能會明白。

+0

什麼是「PdfSharp」類? – 2013-04-02 13:29:16

+0

@Chanipoz:這實際上並不是一個類,這是一個PDF n層應用程序,用於幫助在代碼端動態生成PDF文件。 – 2013-06-12 13:28:58

0

OP問及如何根據可用寬度和字體計算文本高度。 Windows .NET爲此提供了一個API調用,它需要一個寬度參數;我使用的PDFsharp版本(0.9.653,.NET 1.1)沒有。

我的解決方案 - 使用.NET API調用和分配給自定義創建的Bitmap對象的Graphics對象來獲得答案。

對我而言,使用的位圖具有100 DPI分辨率(嚴重),並且恰好是縱向頁面的大小(可能不那麼重要)。

然後我只是問了.NET在該位圖上繪製的像素大小。

您可能會想要將單位從1/100英寸轉換爲Points(對於PDFsharp)。

 
''' Adapted Code - this not tested or even compiled - Caveat Emptor! 
''' Target: Visual Basic, .NET 1.1 (VS2003) [adapt as necessary] 

' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 
' GraphicsAlt.MeasureString() does substantially what System.Drawing MeasureString(...,Integer) does. 
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 
Public Module GraphicsAlt 

    ' 
    ' Static data used Only to compute MeasureString() below. 
    ' 
    '  Cache a single copy of these two objects, to address an otherwise unexplained intermittent exception. 
    ' 
    Private Shared myImage As Bitmap = Nothing 
    Private Shared myGraphics As Graphics = Nothing 

    Public Shared Function GetMeasureGraphics() As Graphics 
     If myImage Is Nothing Then 
      myImage = New Bitmap(1700, 2200) '' ... Specify 8.5x11 
      myImage.SetResolution(100, 100) '' ... and 100 DPI (if you want different units, you might change this) 
      myGraphics = Graphics.FromImage(myImage) 
     End If 
     Return myGraphics 
    End Function 

    'Given 1/100TH inch max width, return Rect to hold with units 1/100TH inch 
    ' 
    Public Function MeasureString(ByVal text As String, ByVal aFont As System.Drawing.Font, ByVal width As Integer) As System.Drawing.SizeF 
     Return (GraphicsAlt.GetMeasureGraphics()).MeasureString(text, aFont, width) 
    End Function 

End Module 
+0

這聽起來像是黑客,因爲結果可能與PDF格式/ MigraDoc在內部使用的XGraphics.MeasureString有所不同,因爲舍入錯誤,字距縮小,粗體和斜體的不同處理。 – 2016-01-14 09:20:07

5

我有一個類似的問題,所以我實現了這個擴展方法:

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; 
} 
0

在任何情況下,仍希望找到一個答案,我已經實現了一個相當容易理解的方法找到超出最終文本的高度。

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 

解釋代碼:

首先,打印文本。我包含一個名爲tf的可選XTextFormatter,因爲我在應用程序中可互換地使用XGraphics或XTextFormatters。

然後,通過MeasureString()。Width計算文本的長度。

然後,計算出有多少行文字。這是通過將前面找到的文本的總長度除以提供的打印稅的矩形(框)的寬度來完成的。我在這裏做了一個while循環。

乘以文本的高度(使用graph.MeasureString()。高度)乘以行數。這是你文字的最後高度。

返回高度值。現在,調用PrintString()函數將打印提供的文本,同時返回打印文本的高度。

0

PDFsharp包含一個類XTextFormatter,可用於使用換行符繪製文本。

但是它無法確定文本所需的高度。受@ Wakka02評論的啓發我改進了這個類,生成了類XTextFormatterEx。
在我看來,它也回答了原來的問題,因此我張貼了一個答案。
我知道這是一個老問題,答案可能無助於OP,但這是一個常見問題,答案可能有助於其他人。

新班級有500行代碼 - 我認爲這對這篇文章來說太多了。
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

的源代碼可以在PDFsharp論壇找到找出適合的文本具有多少文本以及哪個高度。然後你的解碼器可以繪製準備好的文本或準備另一個文本或準備一個不同的矩形相同的文本。

我的新班級在工作: 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類的內部字段。編譯課程時需要特殊處理。我決定在下載PDFsharp 1.32的完整源代碼包後,將我的XTextFormatterEx類複製到PDFsharp文件夾中。
任何試圖修改XTextFormatter或XTextFormatterEx類的人都會面臨同樣的問題。
我希望這個問題能夠在未來的PDFsharp版本中得到解決,允許這些類的修改版本被包含在應用程序項目中。