Search code examples
c#.netpdfsharpmigradoc

PDFsharp - XStringFormatFlags missing in newer version


A project I'm currently working on uses MigraDoc and PDFsharp. So far it used the latest stable version, 1.32.2608, but we are trying to migrate to a newer, prerelease version (because of a connected project using 1.50.4619-beta4c). And almost everything looks fine, but there is one thing I'm not sure how to get around.
There is a function measuring a string's size, looking (to put it simply) something about that:

protected SSize GetSize(string text, MigraDoc.DocumentObjectModel.Font font)
{
  var doc = new PdfDocument();
  var page = doc.AddPage;
  var sizer = XGraphics.FromPdfPage(page);
  var style = XFontStyle.Regular;
  //some style checks

  var xf = new XFont(font.Name, font.Size, style);
  var st = new XStringFormat();
  st.FormatFlags = XStringFormatFlags.MeasureTrailingSpaces;
  var xs = sizer.MeasureString(text, xf, st);
  return new SSize {
    Height = XUnit.FromPoint(xs.Height * _measureCorrection).Centimeter,
    Width = XUnit.FromPoint(xs.Width * _measureCorrection).Centimeter
  };
}

and the problematic line is:

st.FormatFlags = XStringFormatFlags.MeasureTrailingSpaces;

as the XStringFormat lost the FormatFlags property, and there is no longer the XStringFormatFlags enum. Does anyone have any similar experience and could give a clue, how to transform it properly to a new version?


Solution

  • On the official PDFsharp forum you can find this implementation of a TextMeasurement class that appears to be much more efficient than your code snippet above:
    https://forum.pdfsharp.net/viewtopic.php?f=8&t=3196 Your code creates a new PDF document and a new PDF page just to measure a string - for every string.

    To deal with trailing spaces:

    • One option is measuring the spaces separately - measure "X X" and "XX" and use the difference as the width of a space.
    • Or append "X" to every string and subtract the width of "X" afterwards to get the width of the string with trailing spaces.

    You can take the TextMeasurement class to get started and save the width of "X" or " " respectively inside the class to get a more efficient implementation.