Couple of question regarding PDF content editing

Q We have a PDF file, and our objective is read the ovals (which
are part of PDF content) and need to fill them with black color. We
know how to read the form elements but we don’t know exactly how to
read and write the forms which are inside another form. I suspect
these ovals are in the inner form. Also the PDF page is cropped in a
wrong way after page editing. Any ideas what can cause this? Our code
is along the following lines:

using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;

namespace FooBar
{
public static class EditPDFPage
{
public static void ProcessElements(ElementReader pReader, ref
ElementWriter pWriter, int pPageNumber, ArrayList pFillvalue,
ArrayList pPageIndexList)
{
Element pElement;
string m_buf;
string coordinates = “”;
while ((pElement = pReader.Next()) != null)
{
if (pElement.GetType() == Element.Type.e_path)
{
double[] data = pElement.GetPathPoints();
int data_sz = pElement.GetPointCount();

byte[] opr = pElement.GetPathTypes();
int opr_sz = pElement.GetPathTypesCount();

int opr_itr = 0, opr_end = opr_sz;
int data_itr = 0, data_end = data_sz;
double x1, y1, x2, y2, x3, y3;

int sz = pElement.GetPointCount();
//if (sz == 30)
{
coordinates = “”;
for (; opr_itr < opr_end; ++opr_itr)
{
switch ((Element.PathSegmentType)
((int)opr[opr_itr]))
{
case Element.PathSegmentType.e_moveto:
x1 = data[data_itr]; ++data_itr;
y1 = data[data_itr]; ++data_itr;
m_buf = string.Format(“M{0:g5}
{1:g5}”, x1, y1);
coordinates += m_buf;
break;
case Element.PathSegmentType.e_lineto:
x1 = data[data_itr]; ++data_itr;
y1 = data[data_itr]; ++data_itr;
m_buf = string.Format(" L{0:g5}
{1:g5}", x1, y1);
coordinates += m_buf;
break;
case
Element.PathSegmentType.e_cubicto:
x1 = data[data_itr]; ++data_itr;
y1 = data[data_itr]; ++data_itr;
x2 = data[data_itr]; ++data_itr;
y2 = data[data_itr]; ++data_itr;
x3 = data[data_itr]; ++data_itr;
y3 = data[data_itr]; ++data_itr;
m_buf = string.Format(" C{0:g5}
{1:g5} {2:g5} {3:g5} {4:g5} {5:g5}",
new object[] { x1, y1, x2, y2,
x3, y3 });
coordinates += m_buf;
break;
case Element.PathSegmentType.e_rect:
{
x1 = data[data_itr]; +
+data_itr;
y1 = data[data_itr]; +
+data_itr;
double w = data[data_itr]; +
+data_itr;
double h = data[data_itr]; +
+data_itr;
x2 = x1 + w;
y2 = y1;
x3 = x2;
y3 = y1 + h;
double x4 = x1;
double y4 = y3;
m_buf = string.Format(“M{0:g5}
{1:g5} L{2:g5} {3:g5} L{4:g5} {5:g5} L{6:g5} {7:g5} Z”,
new object[] { x1, y1, x2,
y2, x3, y3, x4, x3 });
coordinates += m_buf;
break;
}
case
Element.PathSegmentType.e_closepath:
break;
default:

System.Diagnostics.Debug.Assert(false);
break;
}
for (int i = 0; i < pFillvalue.Count; i++)
{
string ovalCoordinates =
pFillvalue[i].ToString ();
if (coordinates == ovalCoordinates &&
(int)pPageIndexList[i] == pPageNumber)
{
GState gs = pElement.GetGState();

gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
gs.SetFillColor(new ColorPt(0, 0,
0));
}
}
}
}
pWriter.WriteElement(pElement);
}

else if (pElement.GetType() == Element.Type.e_form)
{
Element formElement;
ElementReader formReader = pReader;
formReader.FormBegin();
while ((formElement = formReader.Next()) != null)
{
if (formElement.GetType() ==
Element.Type.e_path)
{

double[] data =
formElement.GetPathPoints();
int data_sz = formElement.GetPointCount();

byte[] opr = formElement.GetPathTypes();
int opr_sz =
formElement.GetPathTypesCount();

int opr_itr = 0, opr_end = opr_sz;
int data_itr = 0, data_end = data_sz;
double x1, y1, x2, y2, x3, y3;

int sz = formElement.GetPointCount();
//if (sz == 30)
{
coordinates = “”;
for (; opr_itr < opr_end; ++opr_itr)
{

switch ((Element.PathSegmentType)
((int)opr[opr_itr]))
{
case
Element.PathSegmentType.e_moveto:
x1 = data[data_itr]; +
+data_itr;
y1 = data[data_itr]; +
+data_itr;
m_buf =
string.Format(“M{0:g5} {1:g5}”, x1, y1);
coordinates += m_buf;
break;
case
Element.PathSegmentType.e_lineto:
x1 = data[data_itr]; +
+data_itr;
y1 = data[data_itr]; +
+data_itr;
m_buf = string.Format("
L{0:g5} {1:g5}", x1, y1);
coordinates += m_buf;
break;
case
Element.PathSegmentType.e_cubicto:
x1 = data[data_itr]; +
+data_itr;
y1 = data[data_itr]; +
+data_itr;
x2 = data[data_itr]; +
+data_itr;
y2 = data[data_itr]; +
+data_itr;
x3 = data[data_itr]; +
+data_itr;
y3 = data[data_itr]; +
+data_itr;
m_buf = string.Format("
C{0:g5} {1:g5} {2:g5} {3:g5} {4:g5} {5:g5}",
new object[] { x1, y1,
x2, y2, x3, y3 });
coordinates += m_buf;
break;
case
Element.PathSegmentType.e_rect:
{
x1 = data[data_itr]; +
+data_itr;
y1 = data[data_itr]; +
+data_itr;
double w =
data[data_itr]; ++data_itr;
double h =
data[data_itr]; ++data_itr;
x2 = x1 + w;
y2 = y1;
x3 = x2;
y3 = y1 + h;
double x4 = x1;
double y4 = y3;
m_buf =
string.Format(“M{0:g5} {1:g5} L{2:g5} {3:g5} L{4:g5} {5:g5} L{6:g5}
{7:g5} Z”,
new object[] { x1,
y1, x2, y2, x3, y3, x4, x3 });
coordinates += m_buf;
break;
}
case
Element.PathSegmentType.e_closepath:
break;
default:

System.Diagnostics.Debug.Assert(false);
break;
}
}
for (int i = 0; i < pFillvalue.Count; i
++)
{
string ovalCoordinates =
pFillvalue[i].ToString ();
if (coordinates == ovalCoordinates
&& (int)pPageIndexList[i] == pPageNumber)
{
GState gs =
formElement.GetGState();

gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
gs.SetFillColor(new ColorPt(0,
0, 0));
}
}
}
}
pWriter.WriteElement(formElement);
}
formReader.End();
}
else
{
pWriter.WriteElement(pElement);
}
}
pWriter.End();
pReader.End();
}

}
}


A: Because form xobjects can be nested, you should recursively
process Form XObjects (as shown in the latest ElementEdit sample -
http://www.pdftron.com/pdfnet/samplecode.html#ElementEdit).

The reason why page is cropped is that you are most likely not copying
the media/crop box from the source page. Using the newer versions of
PDFNet you can edit page content directly (without copy to a temp
page) using ’ writer.Begin(page,
ElementWriter.WriteMode.e_replacement). This is also illustrated in
the above sample.