plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

page.h (4303B)


      1 extern queue	squeue;			// the three queues on which ranges reside
      2 extern queue	bfqueue;
      3 extern queue	ufqueue;
      4 
      5 extern double minfull;
      6 
      7 extern double coltol;
      8 
      9 int anymore();
     10 
     11 // The following is used in some calls to range::enqueue(int = 0).
     12 #define ANDBLOCK 1
     13 
     14 class page;
     15 
     16 enum { DRAFT = 0, FINAL = 1 };
     17 
     18 // The mergestream currpage->stage serves as a staging area for page makeup:
     19 // when primed, it contains a minimal acceptable chunk of input ranges.
     20 // The page must either take or leave everything that's on stage.
     21 class mergestream : public queue {
     22 	page	*currpage;		// current page that's accepting stuff
     23   public:
     24 	mergestream(page *cp)	{ currpage = cp; unblock(); }
     25 	void	unblock();
     26 	int	prime();		// stage next legal chunk
     27 	void	pend();			// process pending chunk on stage
     28 };
     29 
     30 // The multicol currpage->twocol is the two-column piece of the page to which
     31 // two-column ranges are currently being added.
     32 // The page sets htavail to indicate how tall it is allowed to become.
     33 // All ranges on definite must be placed when the multicol is printed.
     34 // Each of these definite ranges also resides on one of column[0] and [1],
     35 // which represent the current best guess about how to divide definite
     36 // between the two columns.
     37 class multicol : public range {
     38 	page	*currpage;		// current page that's accepting stuff
     39 	stream	definite;		// definitely on page
     40 	stream	scratch;		// for trial compositions
     41 	stream	column[2];		// left (0) and right (1) columns
     42 	int	leftblocked;		// OK to add to left column?
     43 	int	htavail;		// max possible ht, set by page::tryout()
     44 	int	prevhtavail;		// max 2-colht last time we added something
     45 	friend	class page;
     46 public:
     47 	multicol(page *cp)	{ currpage = cp;
     48 				leftblocked = 0;
     49 				htavail = 0;
     50 				prevhtavail = -1;
     51 				setgoal(NOGOAL); }
     52 					// the two-column piece behaves as part
     53 					// of the stream of single-column input.
     54 	int	numcol()	{ return 1; }
     55 	int	nonempty()	{ return definite.more(); }
     56 	void	choosecol(range *, int);// add first arg to one or other column
     57 	void	choosecol(stream*, int);// add *all ranges on first arg*
     58 					// to one or other column
     59 					// NOT the same as a mapcar of the
     60 					// preceding function over the ranges
     61 					// on the first argument!
     62 	void	compose(int);		// divide into two columns
     63 	void	tryout();		// decide which column gets stage contents
     64 	void	stretch(int);		// justify both columns to given height
     65 	int	print(int curv, int col);
     66 	int	height();		// an upper bound on actual height
     67 	int	rawht()		{ return max(column[0].rawht(), column[1].rawht()); }
     68 	void	reheight(int *cv, int *mv)
     69 				{ *cv += height(); *mv = max(*mv, *cv); }
     70 	void	dump();
     71 	int	isvbox()	{ return nonempty(); }	// during trimspace()
     72 };
     73 
     74 // These sentinel ranges are used to separate the ranges on twocol::definite
     75 // into the chunks in which they came from the staging area.
     76 // Thus, they preserve the results of the computation that was done to prime
     77 // page::stage.
     78 class sentrange : public range {
     79   public:
     80 	sentrange()		{ }
     81 	int	numcol()	{ return 2; }
     82 	int	issentinel()	{ return 1; }
     83 };
     84 
     85 class page {
     86 	int	pagesize;		// allowed maximum height
     87 	int	prevncol;		// was last item tried 1- or 2-column?
     88 	int	vsince;			// how many vboxes from "current" BS
     89 					// (to avoid putting a single line on
     90 					// a page with a very large floatable)
     91 	stream	definite;		// definitely on page, in input order
     92 	stream	scratch;		// playground in which to alter page
     93 	void	cmdproc();		// process any of several commands
     94 	void	parmproc();		// process any of several parameters
     95 	void	tryout();		// see whether current stage contents fit
     96 	void	compose(int);		// float and trim current page contents
     97 	void	makescratch(int);	// fill scratch area
     98 	void	commit();		// accept the items on stage
     99 	void	welsh();		// reject the items on stage
    100 	void	adddef(range *r);	// add to one of the definite queues
    101 					// (definite or twocol->definite)
    102   public:
    103 	mergestream *stage;
    104 	friend	class mergestream;
    105 	multicol *twocol;
    106 	friend class multicol;
    107 	page(int p)	{ pagesize = p;
    108 			prevncol = 1;
    109 			vsince = 0;
    110 			stage = new mergestream(this);
    111 			twocol = new multicol(this); }
    112 	~page()	{ definite.freeall(); scratch.freeall(); }
    113 	void	fill();
    114 	int	blank()	{ return !definite.more() && !twocol->definite.more();}
    115 	void	print();
    116 };
    117 
    118 // functions in page.c
    119 int main(int, char **);