Q: I am using the code below (VB.NET) to stamp/watermark existing PDF
documents. The results are fine for most PDF documents, however for
some files (usually rotated or unusual dimensions) the header/footer
does not appear on the correct location. Could you please point me in
the right direction?
#Region "Stamp PDF"
Public Function Stamp() As Boolean
Trace.Write("Starting pdf stamping at " + DateTime.Now.ToString)
Stamp = True
Try
Dim PDFStampText As String = Me.m_DocProp.Watermark.Stamp
Dim PDFStampFont As String = Me.m_DocProp.Watermark.Style.Font
Dim PDFStampFontBold As Boolean = Me.m_DocProp.Watermark.Style.Bold
Dim PDFStampFontItalic As Boolean =
Me.m_DocProp.Watermark.Style.Italic
Dim PDFStampFontSize As String =
Me.m_DocProp.Watermark.Style.FontSize
Dim PDFStampTextColor As String =
Me.m_DocProp.Watermark.Style.Color
Dim PDFStampPosition as String =
Me.m_DocProp.Watermark.Style.Position
Dim PDFStampVisibility As String =
Me.m_DocProp.Watermark.Style.Visibility
Dim colorR As Double = CType(PDFStampTextColor.Split(",")(0),
Double)
Dim colorG As Double = CType(PDFStampTextColor.Split(",")(1),
Double)
Dim colorB As Double = CType(PDFStampTextColor.Split(",")(2),
Double)
PDFStampText = SearchReplaceTokens(PDFStampText)
trace.Write("Watermark= " + PDFStampText)
PDFNet.Initialize()
PDFNet.SetResourcesPath(Server.MapPath("resources"))
Using Doc As New PDFDoc(Me.m_DownloadFilePath)
Doc.InitSecurityHandler()
Dim Builder As New ElementBuilder
Dim Writer As New ElementWriter
' Dim pageEnd As PageIterator = Doc.PageEnd()
Dim itr As PageIterator = Doc.GetPageIterator()
Dim element As Element
Dim FStyle As FontStyle = FontStyle.Regular
If PDFStampFontBold Then FStyle = FStyle Or
FontStyle.Bold
If PDFStampFontItalic Then FStyle = FStyle Or
FontStyle.Italic
Dim SysFont As System.Drawing.Font = New
System.Drawing.Font(PDFStampFont, CInt(PDFStampFontSize), FStyle)
Dim font As Font = font.CreateTrueTypeFont(Doc,
SysFont, True, True)
While itr.HasNext()
Writer.Begin(itr.Current())
element = Builder.CreateTextBegin(font,
PDFStampFontSize)
Writer.WriteElement(element)
Dim gs As GState = element.GetGState()
element = Builder.CreateTextRun(PDFStampText)
If PDFStampPosition.Equals("Header",
StringComparison.OrdinalIgnoreCase) Then
element.SetTextMatrix(1, 0, 0, 1, 20, 770)
ElseIf PDFStampPosition.Equals("Footer",
StringComparison.OrdinalIgnoreCase) Then
element.SetTextMatrix(1, 0, 0, 1, 20, 20)
Else
'Assuming diagonal
element.SetTextMatrix(1, 1, 0, 1, 0, 20)
End If
gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB())
If (colorR >1) Then
colorR = colorR/255
End If
If (colorG >1) Then
colorG = colorG/255
End If
If (colorB >1) Then
colorB = colorB/255
End If
gs.SetFillColor(New ColorPt(colorR, colorG,
colorB))
Writer.WriteElement(element)
Writer.WriteElement(Builder.CreateTextEnd())
Writer.End()
itr.Next()
End While
Me.m_StampedFilePath = Me.m_DownloadFolder + "/" +
Me.m_TS + "_" + STAMPED + "." + Me.m_DocType
Trace.Write("Stamped file path = [" +
Me.m_StampedFilePath + "]")
Doc.Save(Me.m_StampedFilePath,
SDF.SDFDoc.SaveOptions.e_linearized)
SysFont.Dispose()
Doc.Close()
End Using
Trace.Write("Ending pdf stamping at " +
DateTime.Now.ToString)
Catch ex As System.Exception
Stamp = False
Trace.Warn(ex.Message + " " + ex.StackTrace)
Throw ex
Exit Function
End Try
End Function
#End Region
-----------
A: The problem is that you are stamping PDF page content at fixed
(hardcoded locations). In PDF format pages can have different
dimensions and as a result the stamp may not be positioned at the
correct location.
In order to account for pages with variable dimensions, you need to
use page.GetPageWidth()/GetPageHeight(). For example:
Dim page as Page = itr.Current()
If PDFStampPosition.Equals("Header",
StringComparison.OrdinalIgnoreCase) Then
' position the text 22 points down from the top of the page
' and 20 points to the right.
element.SetTextMatrix(1, 0, 0, 1, 20, page.GetPageHeight() - 22)
ElseIf
...