summaryrefslogtreecommitdiffstats
path: root/src/cmd/mpm/page.h
diff options
context:
space:
mode:
authorwkj <devnull@localhost>2004-05-16 07:56:41 +0000
committerwkj <devnull@localhost>2004-05-16 07:56:41 +0000
commit5f1cf8e6fb130fd48d6f016d13baf5408b3181f8 (patch)
tree7f77f458df8c8b34db139fb4551df602ab6286be /src/cmd/mpm/page.h
parentc5561c23cf394806cbf6d70a96f2dc0253f93745 (diff)
downloadplan9port-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.h119
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 **);