diff options
| author | wkj <devnull@localhost> | 2004-05-16 07:56:41 +0000 |
|---|---|---|
| committer | wkj <devnull@localhost> | 2004-05-16 07:56:41 +0000 |
| commit | 5f1cf8e6fb130fd48d6f016d13baf5408b3181f8 (patch) | |
| tree | 7f77f458df8c8b34db139fb4551df602ab6286be /src/cmd/mpm/page.h | |
| parent | c5561c23cf394806cbf6d70a96f2dc0253f93745 (diff) | |
| download | plan9port-5f1cf8e6fb130fd48d6f016d13baf5408b3181f8.tar.gz plan9port-5f1cf8e6fb130fd48d6f016d13baf5408b3181f8.zip | |
Checkpoint: pull in mpm; merge pic from Taj's version of the world
Diffstat (limited to 'src/cmd/mpm/page.h')
| -rw-r--r-- | src/cmd/mpm/page.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/cmd/mpm/page.h b/src/cmd/mpm/page.h new file mode 100644 index 00000000..dcccbe0c --- /dev/null +++ b/src/cmd/mpm/page.h @@ -0,0 +1,119 @@ +extern queue squeue; // the three queues on which ranges reside +extern queue bfqueue; +extern queue ufqueue; + +extern double minfull; + +extern double coltol; + +int anymore(); + +// The following is used in some calls to range::enqueue(int = 0). +#define ANDBLOCK 1 + +class page; + +enum { DRAFT = 0, FINAL = 1 }; + +// The mergestream currpage->stage serves as a staging area for page makeup: +// when primed, it contains a minimal acceptable chunk of input ranges. +// The page must either take or leave everything that's on stage. +class mergestream : public queue { + page *currpage; // current page that's accepting stuff + public: + mergestream(page *cp) { currpage = cp; unblock(); } + void unblock(); + int prime(); // stage next legal chunk + void pend(); // process pending chunk on stage +}; + +// The multicol currpage->twocol is the two-column piece of the page to which +// two-column ranges are currently being added. +// The page sets htavail to indicate how tall it is allowed to become. +// All ranges on definite must be placed when the multicol is printed. +// Each of these definite ranges also resides on one of column[0] and [1], +// which represent the current best guess about how to divide definite +// between the two columns. +class multicol : public range { + page *currpage; // current page that's accepting stuff + stream definite; // definitely on page + stream scratch; // for trial compositions + stream column[2]; // left (0) and right (1) columns + int leftblocked; // OK to add to left column? + int htavail; // max possible ht, set by page::tryout() + int prevhtavail; // max 2-colht last time we added something + friend class page; +public: + multicol(page *cp) { currpage = cp; + leftblocked = 0; + htavail = 0; + prevhtavail = -1; + setgoal(NOGOAL); } + // the two-column piece behaves as part + // of the stream of single-column input. + int numcol() { return 1; } + int nonempty() { return definite.more(); } + void choosecol(range *, int);// add first arg to one or other column + void choosecol(stream*, int);// add *all ranges on first arg* + // to one or other column + // NOT the same as a mapcar of the + // preceding function over the ranges + // on the first argument! + void compose(int); // divide into two columns + void tryout(); // decide which column gets stage contents + void stretch(int); // justify both columns to given height + int print(int curv, int col); + int height(); // an upper bound on actual height + int rawht() { return max(column[0].rawht(), column[1].rawht()); } + void reheight(int *cv, int *mv) + { *cv += height(); *mv = max(*mv, *cv); } + void dump(); + int isvbox() { return nonempty(); } // during trimspace() +}; + +// These sentinel ranges are used to separate the ranges on twocol::definite +// into the chunks in which they came from the staging area. +// Thus, they preserve the results of the computation that was done to prime +// page::stage. +class sentrange : public range { + public: + sentrange() { } + int numcol() { return 2; } + int issentinel() { return 1; } +}; + +class page { + int pagesize; // allowed maximum height + int prevncol; // was last item tried 1- or 2-column? + int vsince; // how many vboxes from "current" BS + // (to avoid putting a single line on + // a page with a very large floatable) + stream definite; // definitely on page, in input order + stream scratch; // playground in which to alter page + void cmdproc(); // process any of several commands + void parmproc(); // process any of several parameters + void tryout(); // see whether current stage contents fit + void compose(int); // float and trim current page contents + void makescratch(int); // fill scratch area + void commit(); // accept the items on stage + void welsh(); // reject the items on stage + void adddef(range *r); // add to one of the definite queues + // (definite or twocol->definite) + public: + mergestream *stage; + friend class mergestream; + multicol *twocol; + friend class multicol; + page(int p) { pagesize = p; + prevncol = 1; + vsince = 0; + stage = new mergestream(this); + twocol = new multicol(this); } + ~page() { definite.freeall(); scratch.freeall(); } + void fill(); + int blank() { return !definite.more() && !twocol->definite.more();} + void print(); +}; + +// functions in page.c +int main(int, char **); |
