// convert PDFNet Matrix to raw PDF operators
static string Mtx2String(Matrix2D mtx)
{
return String.Format("{0} {1} {2} {3} {4} {5} cm", mtx.m_a, mtx.m_b, mtx.m_c, mtx.m_d, mtx.m_h, mtx.m_v);
}
static void ProcessElements(ElementReader reader, ElementWriter writer, ElementBuilder builder, XSet visited, Matrix2D page_shift_mtx)
{
Element element;
while ((element = reader.Next()) != null)
{
Element.Type type = element.GetType();
Matrix2D trans = element.GetGState().GetTransform();
switch (type)
{
case Element.Type.e_path:
--skip;
bool shift = skip == 0;
if(shift)
{
skip = 3;
Matrix2D ctm = element.GetCTM().Inverse();
writer.WriteString(Mtx2String(element.GetGState().GetTransform()) + "\n");
// figure out shift taking into account current transformation matrix
Matrix2D mtx = ctm * page_shift_mtx;
mtx.m_a = mtx.m_d = 1.0;
mtx.m_b = mtx.m_c = 0.0;
element.GetGState().SetTransform(mtx);
writer.WritePlacedElement(element);
}
else
{
writer.WriteElement(element);
}
break;
case Element.Type.e_form:
{
writer.WriteElement(element); // write Form XObject reference to current stream
Obj form_obj = element.GetXObject();
if (!visited.Contains(form_obj.GetObjNum())) // if this XObject has not been processed
{
// recursively process the Form XObject
visited.Add(form_obj.GetObjNum());
ElementWriter new_writer = new ElementWriter();
reader.FormBegin();
new_writer.Begin(form_obj, true);
ProcessElements(reader, new_writer, builder, visited, page_shift_mtx);
new_writer.End();
reader.End();
}
break;
}
default:
writer.WriteElement(element);
break;
}
}
}
void ProcessDoc(PDFDoc doc)
{
ElementWriter writer = new ElementWriter();
ElementReader reader = new ElementReader();
ElementBuilder builder = new ElementBuilder();
XSet visited = new XSet();
PageIterator itr = doc.GetPageIterator();
// dx,dy are the desired shift/displacement, where up is +y and right is +x
double dx = 0;
double dy = -360; // shift down 5 inches (5 * 72)
while (itr.HasNext())
{
Page page = itr.Current();
Matrix2D pg_mtx = page.GetDefaultMatrix().Inverse();
pg_mtx.m_h = pg_mtx.m_v = 0.0; // remove page translation
pg_mtx.Mult(ref dx, ref dy);
Matrix2D page_shift_mtx = new Matrix2D(1, 0, 0, 1, dx, dy);
visited.Add(page.GetSDFObj().GetObjNum());
reader.Begin(page);
writer.Begin(page, ElementWriter.WriteMode.e_replacement, false);
ProcessElements(reader, writer, builder, visited, page_shift_mtx);
writer.End();
reader.End();
itr.Next();
}
}