Q: I was able to successfully search and highlight words in a PDF file
using PDFNet. The framework currently allows to search words (using
the TextExtractor class) and highlight them in the file.
I can easily achieve highlighting for a group of adiacent words on the
same line by searching adiacent words and by binding together the
bounding rectangles which correspond to those words.
Currently I cannot figure out wether is possible(and if it is
possible, how?) to highlight a scattered paragraph of text which
overlaps on two or more lines and to have ONLY one annotation for the
highlighted region. For this I would need to specify a polygon for the
highlighted text zone and also for the active area(The area on which
the user can click to show the annotation popup).
I tried to use polygon or polyline as annotation type when I create
the annotation, but the parameter which specifies the highlighted area
is still a rectangle.
It might be possible that I’m looking at solving the problem from a
wrong point of view, and maybe you could point me in the right
direction.
-------
A: To create a more complex highlight you could add additional
rectangles to Quads array (in the highlight annotation dictionary) and
extend the appearance generation code by drawing a polyline instead of
a single rectangle.
For example [this is only pseudocode]:
// Create a Highlight Annotation for multiple boxes (e.g. for a
multiline, scattered paragraph).
static Annot CreateHighlightAnnot(PDFDoc doc, List<Rect> bboxes,
ColorPt highlight_color) {
Annot a = Annot.Create(doc, Annot.Type.e_Highlight, RectangleUnion
(bboxes));
a.SetColor(highlight_color);
a.SetAppearance(CreateHighlightAppearance(doc, bboxes,
highlight_color));
Obj quads = a.GetSDFObj().PutArray("QuadPoints");
Rect box;
foreach box in bboxes
{
quads.PushBackNumber(bbox.x1);
quads.PushBackNumber(bbox.y2);
quads.PushBackNumber(bbox.x2);
quads.PushBackNumber(bbox.y2);
quads.PushBackNumber(bbox.x1);
quads.PushBackNumber(bbox.y1);
quads.PushBackNumber(bbox.x2);
quads.PushBackNumber(bbox.y1);
}
return a;
}
// Use PDFNet to generate appearance stream for highlight annotation.
static Obj CreateHighlightAppearance(PDFDoc doc, Rect bboxes, ColorPt
higlight_color) {
ElementBuilder build = new ElementBuilder();
// Construct a polygon...
build.PathBegin();
Rect box;
foreach box in bboxes {
// Add a rectangle to the current path as a complete subpath.
build.Rect(bbox.x1 - 2, bbox.y1, bbox.x2 + 2, bbox.y2);
}
Element element = build.PathEnd();
element.SetPathFill(true);
element.SetPathStroke(false);
GState gs = element.GetGState();
gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
gs.SetFillColor(higlight_color);
gs.SetBlendMode(GState.BlendMode.e_bl_multiply);
ElementWriter writer = new ElementWriter();
writer.Begin(doc);
writer.WriteElement(element);
Obj stm = writer.End();
build.Dispose();
writer.Dispose();
// Set the bounding box
bbox = RectangleUnion(bboxes));
stm.PutRect("BBox", bbox.x1, bbox.y1, bbox.x2, bbox.y2);
stm.PutName("Subtype", "Form");
return stm;
}