PDFsharpを使用して、データベースからその場でPDFドキュメントを作成しています。
使用するフォントと使用可能な幅に基づいてテキスト領域の高さを計算する最良の方法を知る必要があります。
必要に応じてページ分割を処理できるように、高さを知る必要があります。
PDFsharpを使用して、データベースからその場でPDFドキュメントを作成しています。
使用するフォントと使用可能な幅に基づいてテキスト領域の高さを計算する最良の方法を知る必要があります。
必要に応じてページ分割を処理できるように、高さを知る必要があります。
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;
}
.NETでは、Graphics.MeasureStringを呼び出して、描画されるテキストの大きさを確認できます。
XGraphicオブジェクトに小さな拡張メソッドを作成して、それを実行しました。maxWidthを指定して、正確なテキストの高さ(および幅)を計算します。コードについては、次の要点を参照してください:https ://gist.github.com/erichillah/d198f4a1c9e8f7df0739b955b245512a
OPは、使用可能な幅とフォントに基づいてテキストの高さを計算する方法を尋ねました。Windows .NETは、width引数を取るこのためのAPI呼び出しを提供します。私が使用しているPDFsharpのバージョン(0.9.653、.NET 1.1)はそうではありません。
私の解決策-カスタム作成されたビットマップオブジェクトに割り当てられたGraphicsオブジェクトで.NETAPI呼び出しを使用して、答えを取得します。
私にとってうまくいったのは、100 DPIの解像度(クリティカル)で、たまたまポートレートページのサイズ(おそらくそれほどクリティカルではない)のビットマップを使用することでした。
次に、そのビットマップにペイントするためのピクセルサイズを.NETに尋ねました。
次に、単位を1/100インチからポイント(PDFsharpの場合)に変換することをお勧めします。
'''適応コード-これはテストもコンパイルもされていません-CaveatEmptor! '''ターゲット:Visual Basic、.NET 1.1(VS2003)[必要に応じて適応] ''''''''''''''''''''' 'GraphicsAlt.MeasureString()は、System.Drawing MeasureString(...、Integer)が実行することを実質的に実行します。 ''''''''''''''''''''' パブリックモジュールGraphicsAlt ' '以下のMeasureString()を計算するためにのみ使用される静的データ。 ' 'これら2つのオブジェクトの単一のコピーをキャッシュして、説明のつかない断続的な例外に対処します。 ' プライベート共有myImageAsBitmap = Nothing グラフィックとしてのプライベート共有myGraphics=Nothing パブリック共有関数GetMeasureGraphics()As Graphics myImageが何もない場合 myImage = New Bitmap(1700、2200)''...8.5x11を指定 myImage.SetResolution(100、100)''...および100DPI(異なる単位が必要な場合は、これを変更できます) myGraphics = Graphics.FromImage(myImage) 終了する場合 myGraphicsを返す 終了機能 '最大幅が1/100THインチの場合、Rectを1/100THインチの単位で保持するように戻します。 ' パブリック関数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) 終了機能 エンドモジュール
それでも答えを見つけたい人のために、結果のテキストの高さを見つけるために、かなり理解しやすい方法を実装しました。
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のいずれかを同じ意味で使用するため、tfというオプションのXTextFormatterを含めました。
次に、MeasureString()。Widthによってテキストの長さを計算します。
次に、テキストの行数を計算します。これは、以前に見つかったテキストの全長を、税金が印刷される提供された長方形(ボックス)の幅で割ることによって行われます。ここでは、whileループを使用して実行しました。
テキストの高さ(graph.MeasureString()。Heightを使用)に、行数を掛けます。これは、テキストの最終的な高さです。
高さの値を返します。ここで、PrintString()関数を呼び出すと、提供されたテキストが印刷され、後で印刷されたテキストの高さが返されます。
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; ダブル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の将来のバージョンで解決され、これらのクラスの変更されたバージョンをアプリケーションプロジェクトに含めることができるようになることを願っています。