PDF: Работа с объектами шаблонами форм (Form XObject) PDF документа
В этом разделе
PDF документ может содержать несколько шаблонов форм для рисования всей PDF страницы или ее области. В PDF спецификации шаблон формы называется "Form XObject". Шаблон формы может включать любую последовательность графических команд и объектов и может быть нарисован на одной или нескольких страницах.
Класс
PdfFormXObjectResource представляет шаблон формы (Form XObject) и позволяет:
- создать пустой шаблон заданного размера с помощью конструктора класса, который принимает прямоугольник, определяющий ограничивающий прямоугольник шаблона
- создать шаблон на основе указанной страницы, используя конструктор класса, который принимает PDF страницу
- получить информацию о размере шаблона с помощью свойства PdfFormXObjectResource.BoundingBox
Рисование на шаблоне формы (Form XObject)
Чтобы выполнить рисование на шаблоне формы (Form XObject), необходимо сделать следующее:
- получить объект PdfGraphics, который позволяет выполнять рисование на шаблоне формы, используя метод PdfGraphics.FromForm
- выполнить рисование на шаблоне формы
Вот C#/VB.NET код, который демонстрирует, как создать пустой шаблон формы (Form XObject), нарисовать на нем текст, а затем нарисовать сам шаблон формы (Form XObject) в правом нижнем углу каждой страницы PDF документа:
/// <summary>
/// Creates an empty Form XObject, draws a text on it
/// and then draws the Form XObject itself in the right lower corner
/// of each page of PDF document.
/// </summary>
/// <param name="pdfFilename">The filename of PDF document.</param>
/// <remarks>
/// This method doesn't consider the rotation of the page.
/// </remarks>
public static void DrawingOnTemplate(string pdfFilename)
{
// open PDF document
using (Vintasoft.Imaging.Pdf.PdfDocument pdfDocument = new Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename))
{
// bounding box of the form
System.Drawing.RectangleF boundingBox = new System.Drawing.RectangleF(0, 0, 100, 50);
// create a form with specified bounding box
Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource form =
new Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource(pdfDocument, boundingBox);
// open PdfGraphics from the form
using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics formGraphics =
Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromForm(form))
{
// text of the string
string text = "Template";
// get standard font
Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont font = pdfDocument.FontManager.GetStandardFont(
Vintasoft.Imaging.Pdf.Tree.Fonts.PdfStandardFontType.TimesRoman);
// rectangle of text string on the form
System.Drawing.RectangleF textRect = new System.Drawing.RectangleF(10, 10, 80, 30);
// get font size for specified rectangle
float fontSize = formGraphics.MeasureFontSize(text, font, textRect.Width, textRect.Height);
// create brush for the text string
Vintasoft.Imaging.Pdf.Drawing.PdfBrush brush = new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(
System.Drawing.Color.Red);
// draw the text string on the form
formGraphics.DrawString(text, font, fontSize, brush, textRect,
Vintasoft.Imaging.Pdf.Drawing.PdfContentAlignment.Center, false);
}
// get original dimensions of the form
float formWidth = form.BoundingBox.Width;
float formHeight = form.BoundingBox.Height;
// for each page of the PDF document
foreach (Vintasoft.Imaging.Pdf.Tree.PdfPage page in pdfDocument.Pages)
{
// open PdfGraphics from the page
using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics pageGraphics =
Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromPage(page))
{
// get the crop box of the page
System.Drawing.RectangleF cropBox = page.CropBox;
// width of form area on the page
float formAreaWidth = cropBox.Width / 3;
// height of form area on the page
float formAreaHeight = cropBox.Height / 3;
// calculate ratios of form area dimensions to form dimensions
float horizontalRatio = formAreaWidth / formWidth;
float verticalRatio = formAreaHeight / formHeight;
// destination rectangle
System.Drawing.RectangleF rect;
// calculate destination rectanle that is fitted into the specified
// form area with the same width-to-height ratio as the form has
if (horizontalRatio > verticalRatio)
{
// calculate actual form area width
float actualFormAreaWidth = formAreaWidth * (verticalRatio / horizontalRatio);
// calculate the destination rectangle in the right lower corner of the page
rect = new System.Drawing.RectangleF(
cropBox.X + cropBox.Width - actualFormAreaWidth,
cropBox.Y,
actualFormAreaWidth,
formAreaHeight);
}
else
{
// calculate actual form area height
float actualFormAreaHeight = formAreaHeight * (horizontalRatio / verticalRatio);
// calculate the destination rectangle in the right lower corner of the page
rect = new System.Drawing.RectangleF(
cropBox.X + 2 * cropBox.Width / 3,
cropBox.Y,
formAreaWidth,
actualFormAreaHeight);
}
// set clip rectangle
pageGraphics.IntersectClip(rect);
// draw the form on the page
pageGraphics.DrawForm(form, rect);
}
}
// save changes to the source
pdfDocument.SaveChanges();
}
}
''' <summary>
''' Creates an empty Form XObject, draws a text on it
''' and then draws the Form XObject itself in the right lower corner
''' of each page of PDF document.
''' </summary>
''' <param name="pdfFilename">The filename of PDF document.</param>
''' <remarks>
''' This method doesn't consider the rotation of the page.
''' </remarks>
Public Shared Sub DrawingOnTemplate(pdfFilename As String)
' open PDF document
Using pdfDocument As New Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename)
' bounding box of the form
Dim boundingBox As New System.Drawing.RectangleF(0, 0, 100, 50)
' create a form with specified bounding box
Dim form As New Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource(pdfDocument, boundingBox)
' open PdfGraphics from the form
Using formGraphics As Vintasoft.Imaging.Pdf.Drawing.PdfGraphics = Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromForm(form)
' text of the string
Dim text As String = "Template"
' get standard font
Dim font As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont = pdfDocument.FontManager.GetStandardFont(Vintasoft.Imaging.Pdf.Tree.Fonts.PdfStandardFontType.TimesRoman)
' rectangle of text string on the form
Dim textRect As New System.Drawing.RectangleF(10, 10, 80, 30)
' get font size for specified rectangle
Dim fontSize As Single = formGraphics.MeasureFontSize(text, font, textRect.Width, textRect.Height)
' create brush for the text string
Dim brush As New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Red)
' draw the text string on the form
formGraphics.DrawString(text, font, fontSize, brush, textRect, Vintasoft.Imaging.Pdf.Drawing.PdfContentAlignment.Center, _
False)
End Using
' get original dimensions of the form
Dim formWidth As Single = form.BoundingBox.Width
Dim formHeight As Single = form.BoundingBox.Height
' for each page of the PDF document
For Each page As Vintasoft.Imaging.Pdf.Tree.PdfPage In pdfDocument.Pages
' open PdfGraphics from the page
Using pageGraphics As Vintasoft.Imaging.Pdf.Drawing.PdfGraphics = Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromPage(page)
' get the crop box of the page
Dim cropBox As System.Drawing.RectangleF = page.CropBox
' width of form area on the page
Dim formAreaWidth As Single = cropBox.Width / 3
' height of form area on the page
Dim formAreaHeight As Single = cropBox.Height / 3
' calculate ratios of form area dimensions to form dimensions
Dim horizontalRatio As Single = formAreaWidth / formWidth
Dim verticalRatio As Single = formAreaHeight / formHeight
' destination rectangle
Dim rect As System.Drawing.RectangleF
' calculate destination rectanle that is fitted into the specified
' form area with the same width-to-height ratio as the form has
If horizontalRatio > verticalRatio Then
' calculate actual form area width
Dim actualFormAreaWidth As Single = formAreaWidth * (verticalRatio / horizontalRatio)
' calculate the destination rectangle in the right lower corner of the page
rect = New System.Drawing.RectangleF(cropBox.X + cropBox.Width - actualFormAreaWidth, cropBox.Y, actualFormAreaWidth, formAreaHeight)
Else
' calculate actual form area height
Dim actualFormAreaHeight As Single = formAreaHeight * (horizontalRatio / verticalRatio)
' calculate the destination rectangle in the right lower corner of the page
rect = New System.Drawing.RectangleF(cropBox.X + 2 * cropBox.Width / 3, cropBox.Y, formAreaWidth, actualFormAreaHeight)
End If
' set clip rectangle
pageGraphics.IntersectClip(rect)
' draw the form on the page
pageGraphics.DrawForm(form, rect)
End Using
Next
' save changes to the source
pdfDocument.SaveChanges()
End Using
End Sub
Рисование шаблона формы (Form XObject) на странице или другом шаблоне формы
Чтобы нарисовать шаблон формы (Form XObject ) на странице или другом шаблоне формы, необходимо сделать следующее:
Вот C#/VB.NET код, который демонстрирует, как нарисовать одну PDF страницу в левом верхнем углу другой PDF страницы:
/// <summary>
/// Draws one PDF page in the left upper corner of another PDF page
/// using Form XObject that represents the page.
/// </summary>
/// <param name="pdfFilename">The filename of PDF document.</param>
/// <remarks>
/// This method doesn't consider the rotation of the page.
/// </remarks>
public static void DrawingTemplateOnAnotherTemplate(string pdfFilename)
{
// open PDF document
using (Vintasoft.Imaging.Pdf.PdfDocument pdfDocument =
new Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename))
{
if (pdfDocument.Pages.Count == 1)
return;
// get first page of the document
Vintasoft.Imaging.Pdf.Tree.PdfPage firstPage = pdfDocument.Pages[0];
// get second page of the document
Vintasoft.Imaging.Pdf.Tree.PdfPage secondPage = pdfDocument.Pages[1];
// create a form that represents the second page
Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource form =
new Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource(pdfDocument, secondPage);
// get original dimensions of the form
float formWidth = form.BoundingBox.Width;
float formHeight = form.BoundingBox.Height;
// open PdfGraphics from the page
using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics pageGraphics =
Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromPage(firstPage))
{
// get the crop box of the page
System.Drawing.RectangleF cropBox = firstPage.CropBox;
// width of form area on the page
float formAreaWidth = cropBox.Width / 3;
// height of form area on the page
float formAreaHeight = cropBox.Height / 3;
// calculate ratios of form area dimensions to form dimensions
float horizontalRatio = formAreaWidth / formWidth;
float verticalRatio = formAreaHeight / formHeight;
// destination rectangle
System.Drawing.RectangleF rect;
// calculate destination rectanle that is fitted into the specified
// form area with the same width-to-height ratio as the form has
if (horizontalRatio > verticalRatio)
{
// calculate actual form area width
float actualFormAreaWidth = formAreaWidth * (verticalRatio / horizontalRatio);
// calculate the destination rectangle in the right lower corner of the page
rect = new System.Drawing.RectangleF(
cropBox.X,
cropBox.Y + 2 * cropBox.Height / 3,
actualFormAreaWidth,
formAreaHeight);
}
else
{
// calculate actual form area height
float actualFormAreaHeight = formAreaHeight * (horizontalRatio / verticalRatio);
// calculate the destination rectangle in the right lower corner of the page
rect = new System.Drawing.RectangleF(
cropBox.X,
cropBox.Y + cropBox.Height - actualFormAreaHeight,
formAreaWidth,
actualFormAreaHeight);
}
// set clip rectangle
pageGraphics.IntersectClip(rect);
// fill a rectangle with white color as a background
pageGraphics.FillRectangle(
new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.White), rect);
// draw red border
pageGraphics.DrawRectangle(
new Vintasoft.Imaging.Pdf.Drawing.PdfPen(System.Drawing.Color.Red, 2), rect);
// draw the form on the page
pageGraphics.DrawForm(form, rect);
}
// save changes to the source
pdfDocument.SaveChanges();
}
}
''' <summary>
''' Draws one PDF page in the left upper corner of another PDF page
''' using Form XObject that represents the page.
''' </summary>
''' <param name="pdfFilename">The filename of PDF document.</param>
''' <remarks>
''' This method doesn't consider the rotation of the page.
''' </remarks>
Public Shared Sub DrawingTemplateOnAnotherTemplate(pdfFilename As String)
' open PDF document
Using pdfDocument As New Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename)
If pdfDocument.Pages.Count = 1 Then
Return
End If
' get first page of the document
Dim firstPage As Vintasoft.Imaging.Pdf.Tree.PdfPage = pdfDocument.Pages(0)
' get second page of the document
Dim secondPage As Vintasoft.Imaging.Pdf.Tree.PdfPage = pdfDocument.Pages(1)
' create a form that represents the second page
Dim form As New Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource(pdfDocument, secondPage)
' get original dimensions of the form
Dim formWidth As Single = form.BoundingBox.Width
Dim formHeight As Single = form.BoundingBox.Height
' open PdfGraphics from the page
Using pageGraphics As Vintasoft.Imaging.Pdf.Drawing.PdfGraphics = Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromPage(firstPage)
' get the crop box of the page
Dim cropBox As System.Drawing.RectangleF = firstPage.CropBox
' width of form area on the page
Dim formAreaWidth As Single = cropBox.Width / 3
' height of form area on the page
Dim formAreaHeight As Single = cropBox.Height / 3
' calculate ratios of form area dimensions to form dimensions
Dim horizontalRatio As Single = formAreaWidth / formWidth
Dim verticalRatio As Single = formAreaHeight / formHeight
' destination rectangle
Dim rect As System.Drawing.RectangleF
' calculate destination rectanle that is fitted into the specified
' form area with the same width-to-height ratio as the form has
If horizontalRatio > verticalRatio Then
' calculate actual form area width
Dim actualFormAreaWidth As Single = formAreaWidth * (verticalRatio / horizontalRatio)
' calculate the destination rectangle in the right lower corner of the page
rect = New System.Drawing.RectangleF(cropBox.X, cropBox.Y + 2 * cropBox.Height / 3, actualFormAreaWidth, formAreaHeight)
Else
' calculate actual form area height
Dim actualFormAreaHeight As Single = formAreaHeight * (horizontalRatio / verticalRatio)
' calculate the destination rectangle in the right lower corner of the page
rect = New System.Drawing.RectangleF(cropBox.X, cropBox.Y + cropBox.Height - actualFormAreaHeight, formAreaWidth, actualFormAreaHeight)
End If
' set clip rectangle
pageGraphics.IntersectClip(rect)
' fill a rectangle with white color as a background
pageGraphics.FillRectangle(New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.White), rect)
' draw red border
pageGraphics.DrawRectangle(New Vintasoft.Imaging.Pdf.Drawing.PdfPen(System.Drawing.Color.Red, 2), rect)
' draw the form on the page
pageGraphics.DrawForm(form, rect)
End Using
' save changes to the source
pdfDocument.SaveChanges()
End Using
End Sub