2009-05-23 28 views

答えて

10

.NETでは、あなたは 大きな描かれたテキストがあることを行っている方法を見つけるために Graphics.MeasureStringを呼び出すことができます。

ただし、PDFsharpを使用している場合はXGraphics.MeasureStringを呼び出します。

+1

これは答えのようには見えません。 MeasureStringはrect/widthをとらないので、描画された高さを知ることができません。 – noelicus

+1

XGraphics.MeasureStringを使用して、1行のテキストの寸法を検索します。自動で行を区切るコード(MeasureString()を使用)については、XTextFormatterクラスを参照してください。高さを返す新しいメソッドXTextFormatter.MeasureStringを追加するのは簡単です。私たちは通常アプリケーションにMigraDocを使用していますので、文書にテキストを追加し、MigraDocは改行と改行を気にします。 –

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」クラスは何ですか? –

+0

@Chanipoz:これは実際にはクラスではなく、コード側でPDFファイルの作成を手助けするPDFのn層アプリケーションです。 –

0

オペレータは利用可能な幅とフォントに基づいてテキストの高さを計算する方法を尋ねました。 Windows .NETはこれに対してwidth引数をとるAPI呼び出しを提供します。私が使っているPDFsharpのバージョン(0.9.653、.NET 1.1)はありません。

私の解決策 - .NET API呼び出しを使用して、カスタム作成のBitmapオブジェクトに割り当てられたGraphicsオブジェクトを使用して回答を取得します。

私にとっては、100 DPI解像度(クリティカル)を持ち、ポートレートページのサイズになったビットマップ(おそらくあまり重要ではない)を使用することでした。

次に、.NETに、ビットマップにペイントするためのピクセルサイズを尋ねました。

おそらく単位を1/100インチからポイント(PDFシャープの場合)に変換したいと思うでしょう。

 
''' 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

丸め誤差、カーニング、ボールド体やイタリック体の別の処理のために、結果がPDFsharp/MigraDocで内部的に使用されるXGraphics.MeasureStringと異なる場合があります。 –

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

これは、すばやく簡単な解決策として私にとってはうまくいきました。しかし、size.Height * Math.Floor(size.Width/width)を実行すると、幅を過小評価することがあります(または、テキストを折り返すときにTextFormatterが幅を大きく見積もることがあります)。だから私はそれをより正確にするために幅の値を約15%増やさなければなりませんでした。なぜ誰かがそれが役に立つと説明できるのかどうかはわかりません。 –

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 

コードを説明します。私はアプリケーションでXGraphicsまたはXTextFormattersを互換的に使用するため、オプションのXTextFormatterをtfという名前で使用しました。

次に、テキストの長さをMeasureString()で計算します。幅。

次に、テキストの行数を計算します。これは、以前に見つかったテキストの全長を、税が印刷される提供された長方形(ボックス)の幅で割ることによって行われます。私はここでwhileループでやった。

graph.MeasureString()。Heightを使用して、テキストの高さに行数を掛けます。これはテキストの最終的な高さです。

高さの値を返します。今、PrintString()関数を呼び出すと、後で印刷されたテキストの高さを返しながら、提供されたテキストが印刷されます。

+0

このコードでは、XTextFormatterが単語間の改行だけを追加することを考慮していません。 PrintStringの結果は、1行またはそれ以上の行で消えている可能性があります。 XtextFormatterクラスのソースコードはPDFsharpに含まれています。このクラスは、人々を始めさせるためのもので、ページ区切りや高さを返すoutパラメーターを追加できます。 Whileループは除算で置き換えることができます(ただし、結果は改善されません)。 –

+0

@PDFsharpTeam私はそれをする方法を知っていることが大変です。私はいつもXTextFormatterクラスが結果として得られるテキストの高さを自動的に返さない理由を疑問に思ってきました。どのようにクラスを編集するのですか? – Wakka02

+0

@ Wakka02 XTextFormatterに基づいてXTextFormatterExクラスを作成しました。クラスを編集するのは簡単でしたが、コンパイルするには技術的な問題がありました。完全なソースコードはPDFsharpフォーラムにあります。この質問に対する私の答えを見てください。 –

0

PDFsharpには、改行でテキストを描画するために使用できるクラスXTextFormatterが含まれています。

しかし、テキストに必要な高さを決定することはできません。 @ Wakka02からのコメントに触発されて、私はこのクラスを改良し、クラスXTextFormatterExを生成しました。
私の意見では、それも元の質問に答えるので、私は答えを投稿します。
これは古い質問であり、その回答がOPに役立つわけではないことは知っていますが、よくある質問です。

新しいクラスには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クラスの内部フィールドを使用します。これはクラスをコンパイルするときに特別な処理が必要です。 PDFsharp 1.32用の完全なソースパッケージをダウンロードした後、私のXTextFormatterExクラスをPDFsharpフォルダにコピーすることにしました。
XTextFormatterクラスまたはXTextFormatterExクラスのいずれかを変更しようとする人は、同じ問題に直面します。
私はこの問題がPDFsharpの将来のバージョンで解決され、これらのクラスの修正版をアプリケーションプロジェクトに含めることができれば幸いです。

1

私はXGraphicオブジェクトに小さなエクステンションメソッドを書いて、それを行うだけです:maxWidthを指定して正確なテキストの高さ(および幅)を計算します。 コードについては、次の要点を参照してください。https://gist.github.com/erichillah/d198f4a1c9e8f7df0739b955b245512a

関連する問題