PDFsharpを使用して、データベースからその場でPDF文書を作成しています。利用可能な幅とフォントに基づいてテキストの高さを計算しますか?
に基づいてテキスト領域の高さを計算するには、使用するフォントと使用可能な幅を知る必要があります。
必要なときにページ区切りを処理できるように高さを知る必要があります。
PDFsharpを使用して、データベースからその場でPDF文書を作成しています。利用可能な幅とフォントに基づいてテキストの高さを計算しますか?
に基づいてテキスト領域の高さを計算するには、使用するフォントと使用可能な幅を知る必要があります。
必要なときにページ区切りを処理できるように高さを知る必要があります。
.NETでは、あなたは 大きな描かれたテキストがあることを行っている方法を見つけるために Graphics.MeasureStringを呼び出すことができます。
ただし、PDFsharpを使用している場合はXGraphics.MeasureStringを呼び出します。
Graphics.MeasureStringを呼び出すと、描画されるテキストの大きさを知ることができます。
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));
これはあなたに役立つでしょう。このコードをテストしていないと考えてください。いくつかのコンパイル時のエラーが含まれるかもしれませんが、あなたはそのアイデアを得るかもしれません。
「PdfSharp」クラスは何ですか? –
@Chanipoz:これは実際にはクラスではなく、コード側でPDFファイルの作成を手助けするPDFのn層アプリケーションです。 –
オペレータは利用可能な幅とフォントに基づいてテキストの高さを計算する方法を尋ねました。 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
丸め誤差、カーニング、ボールド体やイタリック体の別の処理のために、結果がPDFsharp/MigraDocで内部的に使用される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;
}
これは、すばやく簡単な解決策として私にとってはうまくいきました。しかし、size.Height * Math.Floor(size.Width/width)を実行すると、幅を過小評価することがあります(または、テキストを折り返すときにTextFormatterが幅を大きく見積もることがあります)。だから私はそれをより正確にするために幅の値を約15%増やさなければなりませんでした。なぜ誰かがそれが役に立つと説明できるのかどうかはわかりません。 –
場合は、私が見つけるため、合理的に理解しやすい方法を実装しました結果のテキストの高さを返します。
まず、テキストを印刷:
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()関数を呼び出すと、後で印刷されたテキストの高さを返しながら、提供されたテキストが印刷されます。
このコードでは、XTextFormatterが単語間の改行だけを追加することを考慮していません。 PrintStringの結果は、1行またはそれ以上の行で消えている可能性があります。 XtextFormatterクラスのソースコードはPDFsharpに含まれています。このクラスは、人々を始めさせるためのもので、ページ区切りや高さを返すoutパラメーターを追加できます。 Whileループは除算で置き換えることができます(ただし、結果は改善されません)。 –
@PDFsharpTeam私はそれをする方法を知っていることが大変です。私はいつもXTextFormatterクラスが結果として得られるテキストの高さを自動的に返さない理由を疑問に思ってきました。どのようにクラスを編集するのですか? – Wakka02
@ Wakka02 XTextFormatterに基づいてXTextFormatterExクラスを作成しました。クラスを編集するのは簡単でしたが、コンパイルするには技術的な問題がありました。完全なソースコードはPDFsharpフォーラムにあります。この質問に対する私の答えを見てください。 –
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の将来のバージョンで解決され、これらのクラスの修正版をアプリケーションプロジェクトに含めることができれば幸いです。
私はXGraphicオブジェクトに小さなエクステンションメソッドを書いて、それを行うだけです:maxWidthを指定して正確なテキストの高さ(および幅)を計算します。 コードについては、次の要点を参照してください。https://gist.github.com/erichillah/d198f4a1c9e8f7df0739b955b245512a
これは答えのようには見えません。 MeasureStringはrect/widthをとらないので、描画された高さを知ることができません。 – noelicus
XGraphics.MeasureStringを使用して、1行のテキストの寸法を検索します。自動で行を区切るコード(MeasureString()を使用)については、XTextFormatterクラスを参照してください。高さを返す新しいメソッドXTextFormatter.MeasureStringを追加するのは簡単です。私たちは通常アプリケーションにMigraDocを使用していますので、文書にテキストを追加し、MigraDocは改行と改行を気にします。 –