How are clipping paths handled by PDFNet SDK?

Q:

I am not sure if I understand the way clipping paths are being parsed
by PDFTron. According to the PDF spec, a clipping path operator can
appear before a painting operator, but is affects the subsequent
painting operators. Since the painting operators, with the exception
of shading, are parsed into a Path element is this taken into
consideration when the path elements are placed into PDFDoc?

Also, according to the documentation I have read, the save state and
restore state operators correspond directly with the group_begin and
group_end elements. Is this correct?

So then what is the scoping of the clipping paths in PDFTron? If I get
a group_begin, a clipping path, and a group_end, does the group_end
end the scope and effect of that clipping path? What if I have the
following:(printed from an actual document)
   Processing e_group_begin
    Processing e_path
     isClippingPath (A)
    Processing e_path
     isClippingPath (B)
    Processing e_path
     isClippingPath (C)
    Processing e_group_begin
(POINT 1)
    Processing e_group_end
(POINT 2)
   Processing e_group_end

1) Assume that there is no clipping path at POINT 1, then are clipping
paths A, B, and C are in scope at POINT 1? According to the PDFSpec,
these should be pushed off with the graphics state when the q operator
is issued (ie a group_begin).
2) What if the inner e_group_begin element contained a clipping path,
would that clipping path be in scope and not the others?
3) At point 2, are clipping paths A, B, and C in scope?
-----

A:
The description of how clipping paths are handled in PDF can be found
in Section 4.4.3 'Clipping Path Operators' of PDF Reference Manual
(www.pdftron.com/downloads/PDFReference16.pdf).

The graphics state contains a current clipping path that limits the
regions of the page affected by painting operators. The initial
clipping path includes the entire page. Clipping Path Operators can be
used to reset the clipping path in the graphics state to the
intersection of the current clipping path and the newly constructed
path.

There is no way to enlarge the current clipping path or to set a new
clipping path without reference to the current one. However, since the
clipping path is part of the graphics state, its effect can be
localized to specific graphics objects by enclosing the modification
of the clipping path and the painting of those objects between a pair
of e_group_begin / e_group_end elements (q and Q operators).

the save state and restore state operators correspond directly
with the group_begin and group_end elements. Is this correct?

Correct, e_group_begin element corresponds to 'q' operator and
e_group_end element corresponds to 'Q' operator.

Please keep in mind that ElementReader does not maintain the current
clip stack (for efficiency reasons). This does not prevent an
application from keeping its own clip stack that reflects the current
graphics state.

In your example:

1 Processing e_group_begin
2 Processing e_path
3 isClippingPath (A)
4 Processing e_path
5 isClippingPath (B)
6 Processing e_path
7 isClippingPath (C)
8 Processing e_group_begin
9 (POINT 1)
10 Processing e_group_end
11 (POINT 2)
12 Processing e_group_end
13 (POINT 3)

Assuming that your application needs to maintain the current clipping
stack, you can declare a List variable that contains a list of paths.
When page processing starts, push a list with a page bounding box on
the stack.

When the first e_group_begin element is encountered, you need to clone
the topmost element on the clip stack (this means that the clip stack
would contain two list elements each containing a page crop box).

When the first clipping path is encountered it is added to the current
clip path (i.e. the last list of paths on the clip stack). This means
that the current clip path is the intersection of the page media box
and the new clip path.

When the second and third clipping paths are encountered they are
similarly added to the topmost list of clipping paths. The current
clip path is the intersection of all three paths and the page media
box.

When the second e_group_begin element is encountered, you need to
clone the topmost element on the clip stack (this means that the clip
stack would now contain three list elements: the first containing a
page crop box, and the second and third containing four identical
paths).

When Point1 is drawn the application needs to check if this point is
located in the current clip path (the intersection of 4 paths).

When the first e_group_end element is encountered the last list of
path elements on the clip stack is deleted, and the current clip path
is the previous list of path elements (in this case it contains
identical information)

When Point2 is drawn the application needs to check if this point is
located in the current clip path (still a list of four paths).

When the second e_group_end element is encountered the last list of
path elements on the clip stack is deleted, and the current clip path
becomes again the page media box.

When Point3 is drawn the application needs to check if this point is
located in the current clip path (which is now the page media box).