PDFSharp: Measuring height of long text with word wrap

﹥>﹥吖頭↗ 提交于 2019-11-29 22:13:15

问题


PDFSharp supports automatic text wrapping when drawing long text portions:

textFormatter.DrawString(text, font, XBrushes.Black, new XRect(x, y, textAreaWidth, 1000), XStringFormats.TopLeft);

This will wrap the text if it is longer than textAreaWidth.

How can I get the height of the text that has just been drawn?

I tried it with gfx.MeasureString(), but there is no overload that supports specifying a maximal width. gfx.MeasureString() returns the size of the text without text wrapping.

Thanks for any hints.


回答1:


This extension of PdfSharp didn't quite work for me. Don't know why but i was keeping getting a bigger height than expected (almost the double of the neededHeight). So I decided to write an extension method the the XGraphics object where i can specify a maxWidth and internally calculate the soft line breaks. The code uses the default XGraphics.MeasureString(string, XFont) to the inlined text Width and Aggregates with the words from the text to calclulate the Line breaks. The code to calculate the soft Line breaks looks like this :

/// <summary>
/// Calculate the number of soft line breaks
/// </summary>
private static int GetSplittedLineCount(this XGraphics gfx, string content, XFont font, double maxWidth)
{
    //handy function for creating list of string
    Func<string, IList<string>> listFor = val => new List<string> { val };
    // string.IsNullOrEmpty is too long :p
    Func <string, bool> nOe = str => string.IsNullOrEmpty(str);
    // return a space for an empty string (sIe = Space if Empty)
    Func<string, string> sIe = str => nOe(str) ? " " : str;
    // check if we can fit a text in the maxWidth
    Func<string, string, bool> canFitText = (t1, t2) => gfx.MeasureString($"{(nOe(t1) ? "" : $"{t1} ")}{sIe(t2)}", font).Width <= maxWidth;

    Func<IList<string>, string, IList<string>> appendtoLast =
            (list, val) => list.Take(list.Count - 1)
                               .Concat(listFor($"{(nOe(list.Last()) ? "" : $"{list.Last()} ")}{sIe(val)}"))
                               .ToList();

    var splitted = content.Split(' ');

    var lines = splitted.Aggregate(listFor(""),
            (lfeed, next) => canFitText(lfeed.Last(), next) ? appendtoLast(lfeed, next) : lfeed.Concat(listFor(next)).ToList(),
            list => list.Count());

    return lines;
}

See the following Gist for the complete code : https://gist.github.com/erichillah/d198f4a1c9e8f7df0739b955b245512a




回答2:


The XTextFormatter class (source code included with PDFsharp) is meant to get you started. Modify it if it doesn't suit your needs.

Since XTextFormatter keeps the Y position internally, it would be a rather simple change to return the height of the text that was just drawn.

Instead of modifying XTextFormatter, consider using MigraDoc Foundation (also included) instead.




回答3:


I found this extension of PdfSharp to be the answer to this problem:

http://developer.th-soft.com/developer/2015/07/17/pdfsharp-improving-the-xtextformatter-class-measuring-the-height-of-the-text/

You can clone or fork the relevant code here:

https://github.com/yolpsoftware/PdfSharp/tree/measure-text-height



来源:https://stackoverflow.com/questions/15461052/pdfsharp-measuring-height-of-long-text-with-word-wrap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!