I have been pulling my hair out on this one for ages now, so thought I'd try to get some help... I'm working with PDFsharp (may or may not be significant) and trying to put a watermark into a pdf document when it gets downloaded via my asp.net web app.
My problem comes with that the user needs to be able to define the text in the watermark, so I can't use a fixed text size, also, the pdf page size can change.
Assuming that I'm using Arial and bold, and can find the page width in cm/mm/inch/pt, how do I calculate the font's emSize that is needed so that whatever text is entered grows/shrinks to fill the width?
The PDFsharp XFont constructor takes font name and emSize.
Edit: Many thanks for the suggestions guys, this is what I implemented in the end:
PdfDocument doc = PdfReader.Open(stream, PdfDocumentOpenMode.Modify);
foreach (PdfPage page in doc.Pages)
{
double watermarkWidth = (Math.Sqrt(Math.Pow(page.Height.Point, 2) + Math.Pow(page.Width.Point, 2)));
//reduce by 10% so that the wording doesn't go right into the corners
watermarkWidth -= (watermarkWidth / 10);
XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
double emSize = 150;
XFont font = new XFont("Arial", emSize, XFontStyle.Bold);
XSize size = gfx.MeasureString(watermark, font);
while (size.Width > watermarkWidth && emSize > 10)
{
emSize -= 5;
font = new XFont("Arial", emSize, XFontStyle.Bold);
size = gfx.MeasureString(watermark, font);
}
gfx.TranslateTransform(page.Width / 2, page.Height / 2);
gfx.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
gfx.TranslateTransform(-page.Width / 2, -page.Height / 2);
XGraphicsPath path = new XGraphicsPath();
path.AddString(watermark, font.FontFamily, XFontStyle.Bold, emSize,
new XPoint((page.Width - size.Width) / 2, (page.Height - size.Height) / 2),
XStringFormats.Default);
XPen pen = new XPen(XColor.FromArgb(75, 255, 0, 0), 2);
gfx.DrawPath(pen, path);
}
doc.Save(stream, false);
Is the length of the watermark (in characters) limited? If so, you can take the allowed number of characters and calculate the width of strings like "@@@...", "WWW..." and "MMM..." in a loop with decreasing font sizes until it fits.
Then you will have a single font size that can be used for all texts.
The watermark will then be smaller - if you calculate the width for 30 "@" and the user just enters "Top Secret" ...
Better method: let the user enter the watermark, then use a loop with decreasing font sizes until the desired text fits into the available space.