private pdftron.PDF.Annots.RubberStamp CreateAndFillStamp(PDFDoc doc, Page page, Rect selectBBox, ColorPt color)
{
using (ElementBuilder eb = new ElementBuilder())
using (ElementWriter writer = new ElementWriter())
using (ElementReader reader = new ElementReader())
{
// Set the page rotation to zero to ensure any transform data is easier to deal with and store the
// original rotation.
Page.Rotate rotation = page.GetRotation();
page.SetRotation(0);
// Write the page elements into a new Obj added to the doc and color them as desired
XSet visited = new XSet();
visited.Add(page.GetSDFObj().GetObjNum());
reader.Begin(page);
writer.Begin(doc);
ProcessElements(reader, writer, eb, visited, color);
Obj appearanceStream = writer.End();
reader.End();
// Set the BBox on our Obj to effectively crop the elements
appearanceStream.PutRect("BBox", selectBBox.x1, selectBBox.y1, selectBBox.x2, selectBBox.y2);
// Create our stamp annotation and set it to use the XRef Obj we created
pdftron.PDF.Annots.RubberStamp stamp = pdftron.PDF.Annots.RubberStamp.Create(doc, new Rect(selectBBox.x1, selectBBox.y1, selectBBox.x2, selectBBox.y2));
stamp.SetAppearance(appearanceStream);
page.AnnotPushBack(stamp);
// Finally return the page to it's original orientation
page.SetRotation(rotation);
return stamp;
}
}
private void ProcessElements(ElementReader reader, ElementWriter writer, ElementBuilder builder, XSet visited, ColorPt color)
{
ColorSpace RGBSpace = ColorSpace.CreateDeviceRGB();
Element element;
while ((element = reader.Next()) != null)
{
Element.Type elemType = element.GetType();
switch (elemType)
{
case Element.Type.e_image:
case Element.Type.e_inline_image:
{
writer.WriteElement(element);
// Create a rectangle ontop of the image that will allow us to
// change the blend mode. This will effectively colorize the image.
var elem = builder.CreateRect(0.0, 0.0, 1.0, 1.0);
elem.SetPathFill(true);
elem.SetPathStroke(false);
var gs = elem.GetGState();
gs.SetFillColorSpace(RGBSpace);
gs.SetFillColor(color);
gs.SetBlendMode(GState.BlendMode.e_bl_screen);
writer.WritePlacedElement(elem);
break;
}
case Element.Type.e_text:
{
// Set text elements to our desired color.
Rect bbox = new Rect();
element.GetBBox(bbox);
{
GState gs = element.GetGState();
gs.SetFillColorSpace(RGBSpace);
gs.SetFillColor(color);
writer.WriteElement(element);
}
break;
}
case Element.Type.e_path:
{
// Set path elements to our desired color.
Rect bbox = new Rect();
element.GetBBox(bbox);
{
GState gstate = element.GetGState();
gstate.SetStrokeOpacity(1.0);
gstate.SetStrokeColorSpace(RGBSpace);
gstate.SetStrokeColor(color);
gstate.SetFillColorSpace(RGBSpace);
gstate.SetFillColor(color);
writer.WriteElement(element);
}
break;
}
case Element.Type.e_form:
{
// Write the form element
writer.WriteElement(element);
Obj form_obj = element.GetXObject();
// Recurse to children if not already written
if (!visited.Contains(form_obj.GetObjNum()))
{
visited.Add(form_obj.GetObjNum());
ElementWriter new_writer = new ElementWriter();
reader.FormBegin();
new_writer.Begin(form_obj, true);
ProcessElements(reader, writer, builder, visited, color);
new_writer.End();
reader.End();
}
break;
}
default:
writer.WriteElement(element);
break;
}
}
}