How to add a watermark to the footer without overlapping content of a converted office file

Question:

I converted a docx file to a PDF but need to add a watermark to the footer of the page without overlapping any content.

Answer:

The following C# code shows how you can calculate the used area of a page, and determine the size of a stamp. Using this information, you can calculate whether or not a stamp will fit in within the footer without overlapping any content. This uses the first page to calculate the usable area, but can easily be expanded as needed.

string stampText = "IMPORTANT INFORMATION\nthis is a test stamp";
using (PDFDoc doc = new PDFDoc())
using (Stamper s = new Stamper(Stamper.SizeType.e_font_size, 12, 12))
{
	//////////////////////////////////////////////////////////////////////////////////////////////
	// NOTE: following code will only work with PDFs generated with OfficeToPDF API
	// code below will not necessarily work with ANY PDF file, due to page rotation complications.
	//Convert office document
	pdftron.PDF.Convert.OfficeToPDF(doc, "../../input.docx", null);
	//////////////////////////////////////////////////////////////////////////////////////////////

	//Get the size of the visible content on the first page
	Page firstPage = doc.GetPage(1);
	Rect firstPageCropBox = firstPage.GetCropBox();
	Rect pageContentSize = firstPage.GetVisibleContentBox();

	//Setup stamp settings for a centered, and at the foot stamp
	s.SetSize(Stamper.SizeType.e_font_size, 12, 0); // aim for 12pt font size
	s.SetAlignment(Stamper.HorizontalAlignment.e_horizontal_center, Stamper.VerticalAlignment.e_vertical_bottom);
	s.SetTextAlignment(Stamper.TextAlignment.e_align_center);
	s.SetFontColor(new ColorPt(1, 0, 0)); // set text color to red
	s.SetFont(Font.Create(doc, "Arial", stampText));

	//Create empty doc and blank page to place a test stamp
	PDFDoc testDoc = new PDFDoc();
	Page stampedPage = testDoc.PageCreate(new Rect(0, 0, 1200, 1200)); // make a large page so we know the true size.
	testDoc.PagePushBack(stampedPage);

	//Place the test stamp on the first empty page of the test document
	s.StampText(testDoc, stampText, new PageSet(1, 1));

	//Grab the visible size of the newly stamped page to get the size of the stamp
	Rect stampSize = stampedPage.GetVisibleContentBox();
	stampedPage.SetCropBox(stampSize);
	double requiredWidth = Math.Ceiling(stampSize.Width());
	double requiredHeight = Math.Ceiling(stampSize.Height());
	Console.WriteLine($"{requiredWidth} x {requiredHeight}");

	Rect targetPageContentBBox = firstPage.GetVisibleContentBox();
	double footerSpaceAvailable = targetPageContentBBox.y1 - firstPageCropBox.y1;
	double widthAvailable = targetPageContentBBox.Width() - requiredWidth;
	if (footerSpaceAvailable < 0.0 || widthAvailable < 0.0)
	{
		throw new Exception("Not enough space for footer watermark");
		// TODO switch Stamper to relative, rather than fixed size.
	}
	double yTop = targetPageContentBBox.y1;
	double yBottom = firstPage.GetCropBox().y1;
	double footerSpace = yTop - yBottom;
	// Centre in the footer. You may want to do a different placement, e.g. minimum height from the bottom edge.
	// Assuming space is available.
	double y = yTop - (footerSpaceAvailable / 2.0) - (requiredHeight / 2.0);
	s.SetSize(Stamper.SizeType.e_absolute_size, requiredWidth, requiredHeight);
	s.SetPosition(0.0, y);
	s.StampPage(doc, stampedPage, new PageSet(1, doc.GetPageCount()));

	doc.Save("../../output_01.pdf", SDFDoc.SaveOptions.e_linearized);
}