The purpose of this README is to document the various bits of the page code
in the PLplot core that interacts with devices (such as ps, xwin) where
pages are included in the standard and devices that have no paging (such as
png, svg, pngcairo, svgcairo) where PLplot logical pages must be handled as
separate (familied) files.

plsc->page_status keeps track of page status which is one of AT_BOP,
DRAWING, or AT_EOP.

plP_line, plP_polyline, plP_fill, and plP_image set

plsc->page_status = DRAWING

plP_tidy sets no page_status, but that is only called from plend1 (see below)
so it transcends page_status.

QUESTION TO BE ANSWERED LATER: should page_status be set to DRAWING for
plP_state, and plP_esc?

Page and family related code fragments:

* plinit ==> plP_init initializes page_status
    plsc->page_status = AT_EOP;

* plinit ==> plP_bop

* plP_bop

    plP_subpInit();

* plP_subpInit initializes number of subpages (if not done already using
  plssub, plstar, or plstart) and current subpage.

    if (plsc->nsubx <= 0)
        plsc->nsubx = 1;
    if (plsc->nsuby <= 0)
        plsc->nsuby = 1;

    plsc->cursub = 0;

* plP_bop (continued) does nothing after above plP_subpInit call
  if already at beginning of page (as set by plP_init above)

    if (plsc->page_status == AT_BOP)
        return;

    plsc->page_status = AT_BOP;

* plP_eop is a no-op if already at eop.

    if (plsc->page_status == AT_EOP)
        return;

    plsc->page_status = AT_EOP;

* plbop
    plP_bop();
    plsc->cursub = 1;

* pleop

    plsc->cursub = plsc->nsubx * plsc->nsuby;
    plP_eop();


* pladv(0) calls plP_eop and plP_bop IF the subpages on the current page
  have been completed as indicated by plsc->cursub.  Note, because of
  the above initialization by plP_subpInit, this does NOT occur if you
  call pladv(0) right after plinit.

        if (plsc->cursub >= plsc->nsubx * plsc->nsuby) {
            plP_eop();
            plP_bop();
            plsc->cursub = 1;
        }

* plend calls plend1 for each stream.

* plend1
    if (plsc->level > 0) {
        plP_eop();
        plP_tidy();
        plsc->level = 0;
    }


* plGetFam calls plP_tidy and plP_init to start next familied file.  It also
restores the initial page status (in all cases so far this internal function
is called by device drivers from their plD_bop-* function so this initial
page status is necessarily AT_BOP in the use so far) that otherwise is
changed to AT_EOP by the plP_init call.  This restoration is necessary to
have valid empty pages for some devices (e.g., svg).

In sum, plP_bop is called from plinit, plbop, and pladv.  The dispatch table
part of it is never done if already at bop.  plP_eop is called from pleop,
pladv, and plend1 and is a noop if already at eop.  plP_tidy is called from
both plGetFam (used internally by drivers to handle familying) and plend1.

The usual patterns of using the public api functions plbop and pleop on the
one hand, or pladv(0) or plenv (which calls pladv(0))
on the other is as follows:

Single page:

plinit, plend (example 5)
plinit, pladv(0), plend (example 10 where I don't think that pladv(0) is
                         actually required.)
plinit, plenv, plend    (the plenv here does lots of other essential stuff
               	         beside the pladv(0) which is not really necessary)

Multiple pages:

plinit, plbop, pleop, plbop, pleop, ..., plend (example 2 which also uses
pladv(0) for each page in context of advancing the subpage set up by plssub)

plinit, pladv(0), pladv(0),..., plend (example 7)
plinit, plenv, plenv,..., plend (example 22)

Note, mixing the plbop/pleop method and the pladv(0) (or plenv) method of
handling _pages_ is not recommended.  Of course, pladv(0) can be used to
advance _subpages_ within the plbop/pleop method (see example 2) and
presumably also the pladv(0) (or plenv) method of handling pages.
