LaTeX for Xenix (11 of 14)

G Geers glenn at extro.ucc.su.oz.au
Fri Feb 16 10:42:31 AEST 1990


---- Cut Here and unpack ----
#!/bin/sh
# this is part 11 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file pack.c continued
#
CurArch=11
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file pack.c"
sed 's/^X//' << 'SHAR_EOF' >> pack.c
X	total_stretch[NORMAL] = 0; \
X	total_shrink[FILLL] = 0; \
X	total_shrink[FILL] = 0; \
X	total_shrink[FIL] = 0; \
X	total_shrink[NORMAL] = 0;}
X
Xptr
Xhpack (p, w, m)
X	ptr		p;
X	scal	w;
X	int		m;
X{
X	int		b;
X	scal	d;
X	fnt		f;
X	ptr		g;
X	scal	h;
X	fourq	i;
X	gord	o;
X	ptr		q;
X	ptr		r;
X	scal	s;
X	scal	x;
X	byte	hd;
X
X	r = get_node(BOX_NODE_SIZE);
X	type(r) = HLIST_NODE;
X	subtype(r) = MIN_QUARTERWORD;
X	shift_amount(r) = 0;
X	q = r + LIST_OFFSET;
X	link(q) = p;
X	h = 0;
X	clr_dimens();
X	while (p != NULL) {
Xreswitch:
X		while (is_char_node(p)) {
X			f = font(p);
X			i = char_info(f, character(p));
X			hd = height_depth(i);
X			x += char_width(f, i);
X			s = char_height(f, hd);
X			if (s > h)
X				h = s;
X			s = char_depth(f, hd);
X			if (s > d)
X				d = s;
X			p = link(p);
X		}
X		if (p != NULL) {
X			switch (type(p))
X			{
X			case HLIST_NODE:
X			case VLIST_NODE:
X			case RULE_NODE:
X			case UNSET_NODE:
X				x += width(p);
X				if (type(p) >= RULE_NODE)
X					s = 0;
X				else s = shift_amount(p);
X				if (height(p) - s > h)
X					h = height(p) - s;
X				if (depth(p) + s > d)
X					d = depth(p) + s;
X				break;
X
X			case INS_NODE:
X			case MARK_NODE:
X			case ADJUST_NODE:
X				if (adjust_tail != NULL) {
X					while (link(q) != p)
X						q = link(q);
X					if (type(p) == ADJUST_NODE) {
X						link(adjust_tail) = adjust_ptr(p);
X						while (link(adjust_tail) != NULL)
X							adjust_tail = link(adjust_tail);
X						p = link(p);
X						free_node(link(q), SMALL_NODE_SIZE);
X					} else {
X						link(adjust_tail) = p;
X						adjust_tail = p;
X						p = link(p);
X					}
X					link(q) = p;
X					p = q;
X				}
X				break;
X
X			case WHATSIT_NODE:
X				break;
X			
X			case GLUE_NODE:
X				g = glue_ptr(p);
X				x += width(g);
X				o = stretch_order(g);
X				total_stretch[o] += stretch(g);
X				o = shrink_order(g);
X				total_shrink[o] += shrink(g);
X				if (subtype(p) >= A_LEADERS) {
X					g = leader_ptr(p);
X					if (height(g) > h)
X						h = height(g);
X					if (depth(g) > d)
X						d = depth(g);
X				}
X				break;
X			
X			case KERN_NODE:
X			case MATH_NODE:
X				x += width(p);
X				break;
X			
X			case LIGATURE_NODE:
X				make_char_from_lig();
X				goto reswitch;
X				break;
X
X			default:
X				break;
X			}
X			p = link(p);
X		}
X	}
X	if (adjust_tail != NULL)
X		link(adjust_tail) = NULL;
X	height(r) = h;
X	depth(r) = d;
X	if (m == ADDITIONAL)
X		w += x;
X	width(r) = w;
X	x = w - x;
X	if (x == 0) {
X		glue_sign(r) = NORMAL;
X		glue_order(r) = NORMAL;
X		glue_set(r) = 0.0;
X		return r;
X	} else if (x > 0) {
X		get_stretch_order(); 
X		glue_order(r) = o;
X		glue_sign(r) = STRETCHING;
X		if (total_stretch[o] != 0)
X			glue_set(r) = (float) x / total_stretch[o];
X		else {
X			glue_sign(r) = NORMAL;
X			glue_set(r) = 0.0;
X		}
X		if (hbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
X			b = badness(x, total_stretch[NORMAL]);
X			if (b > hbadness) {
X				print_ln();
X				if (b > 100)
X					print_nl("Underfull");
X				else print_nl("Loose");
X				print(" \\hbox (badness ");
X				print_int(b);
X				goto common_end;
X			}
X		}
X		return r;
X	} else {
X		get_shrink_order();
X		glue_order(r) = o;
X		glue_sign(r) = SHRINKING;
X		if (total_shrink[o] != 0)
X			glue_set(r) = (float) -x / total_shrink[o];
X		else {
X			glue_sign(r) = NORMAL;
X			glue_set(r) = 0.0;
X		}
X		if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
X			glue_set(r) = 1.0;
X			if (-x - total_shrink[NORMAL] > hfuzz || hbadness < 100) {
X				if (overfull_rule > 0 && -x - total_shrink[NORMAL] > hfuzz) {
X					while (link(q) != NULL)
X						q = link(q);
X					link(q) = new_rule();
X					width(link(q)) = overfull_rule;
X				}
X				print_ln();
X				print_nl("Overfull \\hbox ("); 
X				print_scaled(-x - total_shrink[NORMAL]);
X				print("pt too wide");
X				goto common_end;
X			}
X		} else if (hbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
X			b = badness(-x, total_shrink[NORMAL]);
X			if (b > hbadness) {
X				print_ln();
X				print_nl("Tight \\hbox (badness ");
X				print_int(b);
X				goto common_end;
X			}
X		}
X		return r;
X	}
X
Xcommon_end:
X	if (output_active)
X		print(") has occurred while \\output is active");
X	else {
X		if (pack_begin_line != 0) {
X			if (pack_begin_line > 0)
X				print(") in paragraph at lines ");
X			else print(") in alignment at lines ");
X			print_val(abs(pack_begin_line));
X			print("--");
X		} else print(") detected at line ");
X		print_val(line);
X	}
X	print_ln();
X	font_in_short_display = NULL_FONT;
X	short_display(list_ptr(r));
X	print_ln();
X	begin_diagnostic();
X	show_box(r);
X	end_diagnostic(TRUE);
X	return r;
X}
X
Xptr
Xvpackage (p, h, m, l)
X	ptr		p;
X	scal	h;
X	int		m;
X	scal	l;
X{
X	int		b;
X	scal	d;
X	ptr		g;
X	gord	o;
X	ptr		r;
X	scal	s;
X	scal	w;
X	scal	x;
X
X	r = get_node(BOX_NODE_SIZE);
X	type(r) = VLIST_NODE;
X	subtype(r) = MIN_QUARTERWORD;
X	shift_amount(r) = 0;
X	list_ptr(r) = p;
X	w = 0;
X	clr_dimens();
X	while (p != NULL) {
X		if (is_char_node(p))
X			confusion("vpack");
X		else {
X			switch (type(p))
X			{
X			case HLIST_NODE:
X			case VLIST_NODE:
X			case RULE_NODE:
X			case UNSET_NODE:
X				x += d + height(p);
X				d = depth(p);
X				if (type(p) >= RULE_NODE)
X					s = 0;
X				else s = shift_amount(p);
X				if (width(p) + s > w)
X					w = width(p) + s;
X				break;
X			
X			case WHATSIT_NODE:
X				break;
X			
X			case GLUE_NODE:
X				x += d;
X				d = 0;
X				g = glue_ptr(p);
X				x += width(g);
X				o = stretch_order(g);
X				total_stretch[o] += stretch(g);
X				o = shrink_order(g);
X				total_shrink[o] += shrink(g);
X				if (subtype(p) >= A_LEADERS) {
X					g = leader_ptr(p);
X					if (width(g) > w)
X						w = width(g);
X				}
X				break;
X			
X			case KERN_NODE:
X				x += d + width(p);
X				d = 0;
X				break;
X
X			default:
X				break;
X			}
X			p = link(p);
X		}
X	}
X	width(r) = w;
X	if (d > l) {
X		x += d - l;
X		depth(r) = l;
X	} else depth(r) = d;
X	if (m == ADDITIONAL)
X		h += x;
X	height(r) = h;
X	x = h - x;
X	if (x == 0) {
X		glue_sign(r) = NORMAL;
X		glue_order(r) = NORMAL;
X		glue_set(r) = 0.0;
X		return r;
X	} else if (x > 0) {
X		get_stretch_order();
X		glue_order(r) = o;
X		glue_sign(r) = STRETCHING;
X		if (total_stretch[o] != 0)
X			glue_set(r) = (float) x / total_stretch[o];
X		else {
X			glue_sign(r) = NORMAL;
X			glue_set(r) = 0.0;
X		}
X		if (vbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
X			b = badness(x, total_stretch[NORMAL]);
X			if (b > vbadness) {
X				print_ln();
X				if (b > 100)
X					print_nl("Underfull");
X				else print_nl("Loose");
X				print(" \\vbox (badness ");
X				print_int(b);
X				goto common_end;
X			}
X		}
X		return r;
X	} else {
X		get_shrink_order();
X		glue_order(r) = o;
X		glue_sign(r) = SHRINKING;
X		if (total_shrink[o] != 0)
X			glue_set(r) = (float) -x / total_shrink[o];
X		else {
X			glue_sign(r) = NORMAL;
X			glue_set(r) = 0.0;
X		}
X		if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
X			glue_set(r) = 1.0;
X			if (-x - total_shrink[NORMAL] > vfuzz || vbadness < 100) {
X				print_ln();
X				print_nl("Overfull \\vbox (");
X				print_scaled(-x - total_shrink[NORMAL]);
X				print("pt too high");
X				goto common_end;
X			}
X		} else if (vbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
X			b = badness(-x, total_shrink[NORMAL]);
X			if (b > vbadness) {
X				print_ln();
X				print_nl("Tight \\vbox (badness ");
X				print_int(b);
X				goto common_end;
X			}
X		}
X		return r;
X	}
X
Xcommon_end:
X	if (output_active)
X		print(") has occurred while \\output is active");
X	else {
X		if (pack_begin_line != 0) {
X			print(") in alignment at lines ");
X			print_val(abs(pack_begin_line));
X			print("--");
X		} else print(") detected at line ");
X		print_val(line);
X		print_ln();
X	}
X	begin_diagnostic();
X	show_box(r);
X	end_diagnostic(TRUE);
X	return r;
X}
SHAR_EOF
echo "File pack.c is complete"
chmod 0444 pack.c || echo "restore of pack.c fails"
set `wc -c pack.c`;Sum=$1
if test "$Sum" != "8143"
then echo original size 8143, current size $Sum;fi
echo "x - extracting pack.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > pack.h &&
X
X/*
X *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
X *    Copying of this file is granted according to the provisions 
X *    specified in the file COPYING which must accompany this file.
X */
X
X
X/*
X *		pack.h
X */
X
X#define	EXACTLY				0
X#define	ADDITIONAL			1
X#define	NATURAL				0L, ADDITIONAL
X
Xglobal	ptr		adjust_tail;
Xglobal	scal	total_stretch[];
Xglobal	scal	total_shrink[];
X
Xglobal	long	pack_begin_line;
X
X#define	make_char_from_lig() \
X	{mem[lig_trick] = mem[lig_char(p)]; \
X	link(lig_trick) = link(p); \
X	p = lig_trick;}
X
X#define	get_stretch_order() \
X	{if (total_stretch[FILLL] != 0) o = FILLL; \
X	else if (total_stretch[FILL] != 0) o = FILL; \
X	else if (total_stretch[FIL] != 0) o = FIL; \
X	else o = NORMAL;}
X			
X#define	get_shrink_order() \
X	{if (total_shrink[FILLL] != 0) o = FILLL; \
X	else if (total_shrink[FILL] != 0) o = FILL; \
X	else if (total_shrink[FIL] != 0) o = FIL; \
X	else o = NORMAL;}
X
X#define	vpack(P, H) 		vpackage(P, H, MAX_DIMEN)
Xptr		vpackage();
Xptr		hpack();
SHAR_EOF
chmod 0444 pack.h || echo "restore of pack.h fails"
set `wc -c pack.h`;Sum=$1
if test "$Sum" != "1000"
then echo original size 1000, current size $Sum;fi
echo "x - extracting page.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > page.c &&
X
X/*
X *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
X *    Copying of this file is granted according to the provisions 
X *    specified in the file COPYING which must accompany this file.
X */
X
X
X/*
X *		page.c
X */
X
X#include "tex.h"
X#include "heap.h"
X#include "arith.h"
X#include "str.h"
X#include "token.h"
X#include "tokenstack.h"
X#include "tokenlists.h"
X#include "eq.h"
X#include "eqstack.h"
X#include "evalstack.h"
X#include "scan.h"
X#include "expand.h"
X#include "box.h"
X#include "pack.h"
X#include "par.h"
X#include "math.h"
X#include "dvi.h"
X#include "print.h"
X#include "error.h"
X#include "page.h"
X
Xscal	best_height_plus_depth;
Xptr		best_page_break;
Xscal	best_size;
Xscal	cur_page_depth;
Xval		insert_penalties;
Xptr		last_glue = MAX_HALFWORD;
Xscal	last_kern;
Xval		last_penalty;
Xval		least_page_cost;
Xbool	output_active;
Xint		page_contents;
Xscal	page_max_depth;
Xptr		page_tail;
Xscal	page_so_far[8];
X
X#define	set_page_so_far_zero(P)	(page_so_far[P] = 0)
X#define	set_height_zero(H)		(active_height[H] = 0)
X
Xptr
Xprune_page_top (p)
X	ptr		p;
X{
X	ptr		q;
X	ptr		prev_p;
X
X	prev_p = temp_head;
X	link(temp_head) = p;
X	while (p != NULL) {
X		switch (type(p))
X		{
X		case HLIST_NODE:
X		case VLIST_NODE:
X		case RULE_NODE:
X			q = new_skip_param(SPLIT_TOP_SKIP_CODE);
X			link(prev_p) = q;
X			link(q) = p;
X			if (width(temp_ptr) > height(p))
X				width(temp_ptr) -= height(p);
X			else width(temp_ptr) = 0;
X			p = NULL;
X			break;
X
X		case WHATSIT_NODE:
X		case MARK_NODE:
X		case INS_NODE:
X			prev_p = p;
X			p = link(prev_p);
X			break;
X		
X		case GLUE_NODE:
X		case KERN_NODE:
X		case PENALTY_NODE:
X			q = p;
X			p = link(q);
X			link(q) = NULL;
X			link(prev_p) = p;
X			flush_node_list(q);
X			break;
X
X		default:
X			confusion("pruning");
X			break;
X		}
X	}
X	return (link(temp_head));
X}
X
Xptr
Xvert_break (p, h, d)
X	ptr		p;
X	scal	h;
X	scal	d;
X{
X	val		b;
X	ptr		q;
X	ptr		r;
X	int		t;
X	val		pi;
X	ptr		prev_p;
X	scal	prev_dp;
X	ptr		best_place;
X	val		least_cost;
X
X	prev_p = p;
X	least_cost = AWFUL_BAD;
X	do_all_six(set_height_zero);
X	prev_dp = 0;
X	loop {
X		if (p == NULL)
X			pi = EJECT_PENALTY;
X		else {
X			switch (type(p))
X			{
X			case HLIST_NODE:
X			case VLIST_NODE:
X			case RULE_NODE:
X				cur_height = cur_height + prev_dp + height(p);
X				prev_dp = depth(p);
X				goto not_found;
X				break;
X			
X			case WHATSIT_NODE:
X				goto not_found;
X				break;
X			
X			case GLUE_NODE:
X				if (precedes_break(prev_p))
X					pi = 0;
X				else goto update_heights;
X				break;
X			
X			case KERN_NODE:
X				if (link(p) == NULL)
X					t = PENALTY_NODE;
X				else t = type(link(p));
X				if (t == GLUE_NODE)
X					pi = 0;
X				else goto update_heights;
X				break;
X			
X			case PENALTY_NODE:
X				pi = penalty(p);
X				break;
X			
X			case MARK_NODE:
X			case INS_NODE:
X				goto not_found;
X				break;
X			
X			default:
X				confusion("vertbreak");
X				break;
X			}
X		}
X		if (pi < INF_PENALTY) {
X			if (cur_height < h) {
X				if (active_height[3] != 0 ||
X					active_height[4] != 0 ||
X					active_height[5] != 0)
X					b = 0;
X				else b = badness(h - cur_height, active_height[2]);
X			} else if (cur_height - h > active_height[6])
X				b = AWFUL_BAD;
X			else b = badness(cur_height - h, active_height[6]);
X			if (b < AWFUL_BAD) {
X				if (pi <= EJECT_PENALTY)
X					b = pi;
X				else if (b < INF_BAD)
X					b += pi;
X				else b = DEPLORABLE;
X			}
X			if (b <= least_cost) {
X				best_place = p;
X				least_cost = b;
X				best_height_plus_depth = cur_height + prev_dp;
X			}
X			if (b == AWFUL_BAD || pi <= EJECT_PENALTY)
X				return best_place;
X		}
X		if (type(p) < GLUE_NODE || type(p) > KERN_NODE)
X			goto not_found;
X
X	update_heights:
X		if (type(p) == KERN_NODE)
X			q = p;
X		else {
X			q = glue_ptr(p);
X			active_height[2 + stretch_order(q)] += stretch(q);
X			active_height[6] += shrink(q);
X			if (shrink_order(q) != NORMAL && shrink(q) != 0) {
X				print_err("Infinite glue shrinkage found in box being split");
X				help_inf_shrink_box();
X				error();
X				r = new_spec(q);
X				delete_glue_ref(q);
X				shrink_order(r) = NORMAL;
X				glue_ptr(p) = r;
X			}
X		}
X		cur_height = cur_height + prev_dp + width(q);
X		prev_dp = 0;
X
X	not_found:
X		if (prev_dp > d) {
X			cur_height = cur_height + prev_dp - d;
X			prev_dp = d;
X		}
X		prev_p = p;
X		p = link(prev_p);
X	}
X}
X
Xptr
Xvsplit (n, h)
X	int		n;
X	scal	h;
X{
X	ptr		p;
X	ptr		q;
X	ptr		v;
X
X	v = box(n);
X	if (split_first_mark != NULL) {
X		delete_token_ref(split_first_mark);
X		split_first_mark = NULL;
X		delete_token_ref(split_bot_mark);
X		split_bot_mark = NULL;
X	}
X	if (v == NULL)
X		return NULL;
X	if (type(v) != VLIST_NODE) {
X		print_err("");
X		print_esc("vsplit");
X		print(" needs a ");
X		print_esc("vbox");
X		help_vsplit_vbox();
X		error();
X		return NULL;
X	}
X	q = vert_break(list_ptr(v), h, split_max_depth);
X	p = list_ptr(v);
X	if (p == q)
X		list_ptr(v) = NULL;
X	else {
X		loop {
X			if (type(p) == MARK_NODE) {
X				if (split_first_mark == NULL) {
X					split_first_mark = mark_ptr(p);
X					split_bot_mark = split_first_mark;
X					token_ref_count(split_first_mark) += 2;
X				} else {
X					delete_token_ref(split_bot_mark);
X					split_bot_mark = mark_ptr(p);
X					add_token_ref(split_bot_mark);
X				}
X			}
X			if (link(p) == q) {
X				link(p) = NULL;
X				break;
X			}
X			p = link(p);
X		}
X	}
X	q = prune_page_top(q);
X	p = list_ptr(v);
X	free_node(v, BOX_NODE_SIZE);
X	if (q == NULL)
X		box(n) = NULL;
X	else box(n) = vpack(q, NATURAL);
X	return (vpackage(p, h, EXACTLY, split_max_depth));
X}
X
Xfreeze_page_specs (s)
X	int		s;
X{
X	page_contents = s;
X	page_goal = vsize;
X	page_max_depth = max_depth;
X	page_depth = 0;
X	do_all_six(set_page_so_far_zero);
X	least_page_cost = AWFUL_BAD;
X#ifdef STAT
X	if (tracing_pages > 0) {
X		begin_diagnostic();
X		print_nl("%% goal height=");
X		print_scaled(page_goal);
X		print(", max depth=");
X		print_scaled(page_max_depth);
X		end_diagnostic(FALSE);
X	}
X#endif
X}
X
Xbox_error (n)
X	int		n;
X{
X	error();
X	begin_diagnostic();
X	print_nl("The following box has been deleted:");
X	show_box(box(n));
X	end_diagnostic(TRUE);
X	flush_node_list(box(n));
X	box(n) = NULL;
X}
X
Xensure_vbox (n)
X	int		n;
X{
X	ptr		p;
X
X	p = box(n);
X	if (p != NULL && type(p) == HLIST_NODE) {
X		print_err("Insertions can only be added to a vbox");
X		help_tut();
X		box_error(n);
X	}
X}
X
Xprint_plus (s, o)
X	int		s;
X	char*	o;
X{
X	if (page_so_far[s] != 0) {
X		print(" plus ");
X		print_scaled(page_so_far[s]);
X		print(o);
X	}
X}
X
Xprint_totals ()
X{
X	print_scaled(page_total);
X	print_plus(2, "");
X	print_plus(3, "fil");
X	print_plus(4, "fill");
X	print_plus(5, "filll");
X	if (page_shrink != 0) {
X		print(" minus ");
X		print_scaled(page_shrink);
X	}
X}
X
X#ifdef STAT
Xshow_split(n, w, q)
X	int		n;
X	scal	w;
X	ptr		q;
X{
X	begin_diagnostic();
X	print_nl("% split");
X	print_int(n);
X	print(" to ");
X	print_scaled(w);
X	print_char(',');
X	print_scaled(best_height_plus_depth);
X	print(" p=");
X	if (q == NULL)
X		print_int(EJECT_PENALTY);
X	else if (type(q) == PENALTY_NODE)
X		print_val(penalty(q));
X	else print_char('0');
X	end_diagnostic(FALSE);
X}
X
Xshow_page_stats (b, p, c)
X	val		b;
X	val		p;
X	val		c;
X{
X	if (tracing_pages > 0) {
X		begin_diagnostic();
X		print_nl("%");
X		print(" t=");
X		print_totals();
X		print(" g=");
X		print_scaled(page_goal);
X		print(" b=");
X		if (b == AWFUL_BAD)
X			print_char('*');
X		else print_val(b);
X		print(" p=");
X		print_val(p);
X		print(" c=");
X		if (c == AWFUL_BAD)
X			print_char('*');
X		else print_val(c);
X		if (c <= least_page_cost)
X			print_char('#');
X		end_diagnostic(FALSE);
X	}
X}
X#endif
X
Xbuild_page ()
X{
X	val		b;
X	val		c;
X	scal	h;
X	int		n;
X	ptr		p;
X	ptr		q;
X	ptr		r;
X	scal	w;
X	val		pi;
X	scal	delta;
X	
X	if (link(contrib_head) == NULL || output_active)
X		return;
X	do { 
X		p = link(contrib_head);
X		if (last_glue != MAX_HALFWORD)
X			delete_glue_ref(last_glue);
X		last_penalty = 0;
X		last_kern = 0;
X		if (type(p) == GLUE_NODE) {
X			last_glue = glue_ptr(p);
X			add_glue_ref(last_glue);
X		} else {
X			last_glue = MAX_HALFWORD;
X			if (type(p) == PENALTY_NODE)
X				last_penalty = penalty(p);
X			else if (type(p) == KERN_NODE)
X				last_kern = width(p);
X		}
X		switch (type(p))
X		{
X		case HLIST_NODE:
X		case VLIST_NODE:
X		case RULE_NODE:
X			if (page_contents < BOX_THERE) {
X				if (page_contents == EMPTY)
X					freeze_page_specs(BOX_THERE);
X				else page_contents = BOX_THERE;
X				q = new_skip_param(TOP_SKIP_CODE);
X				link(q) = p;
X				if (width(temp_ptr) > height(p))
X					width(temp_ptr) -= height(p);
X				else width(temp_ptr) = 0;
X				link(q) = p;
X				link(contrib_head) = q;
X				continue;
X			} else {
X				page_total = page_total + page_depth + height(p);
X				page_depth = depth(p);
X				goto contribute;
X			}
X			break;
X		
X		case WHATSIT_NODE:
X			goto contribute;
X			break;
X		
X		case GLUE_NODE:
X			if (page_contents < BOX_THERE)
X				goto done;
X			else if (precedes_break(page_tail))
X				pi = 0;
X			else goto update_heights;
X			break;
X		
X		case KERN_NODE:
X			if (page_contents < BOX_THERE)
X				goto done;
X			else if (link(p) == NULL)
X				return;
X			else if (type(link(p)) == GLUE_NODE)
X				pi = 0;
X			else goto update_heights;
X			break;
X		
X		case PENALTY_NODE:
X			if (page_contents < BOX_THERE)
X				goto done;
X			else pi = penalty(p);
X			break;
X
X		case MARK_NODE:
X			goto contribute;
X			break;
X
X		case INS_NODE:
X			if (page_contents == EMPTY)
X				freeze_page_specs(INSERTS_ONLY);
X			n = subtype(p);
X			r = page_ins_head;
X			while (n >= subtype(link(r)))
X				r = link(r);
X			if (subtype(r) != n) {
X				q = get_node(PAGE_INS_NODE_SIZE);
X				link(q) = link(r);
X				link(r) = q;
X				r = q;
X				subtype(r) = qi(n);
X				type(r) = INSERTING;
X				ensure_vbox(n);
X				if (box(n) == NULL)
X					height(r) = 0;
X				else height(r) = height(box(n)) + depth(box(n));
X				best_ins_ptr(r) = NULL;
X				q = skip(n);
X				if (count(n) == 1000)
X					h = height(r);
X				else h = x_over_n(height(r), 1000L) * count(n);
X				page_goal = page_goal - h - width(q);
X				page_so_far[2 + stretch_order(q)] += stretch(q);
X				page_shrink += shrink(q);
X				if (shrink_order(q) != NORMAL && shrink(q) != 0) {
X					print_err("Infinite glue shrinkage inserted from ");
X					print_esc("skip");
X					print_int(n);
X					help_inf_shrink_ins();
X					error();
X				}
X			}
X			if (type(r) == SPLIT_UP)
X				insert_penalties += float_cost(p);
X			else {
X				last_ins_ptr(r) = p;
X				delta = page_goal - page_total - page_depth + page_shrink;
X				if (count(n) == 1000)
X					h = height(p);
X				else h = x_over_n(height(p), 1000L) * count(n);
X				if ((h <= 0 || h <= delta) &&
X					height(p) + height(r) <= dimen(n)) {
X					page_goal -= h;
X					height(r) += height(p);
X				} else {
X					if (count(n) <= 0)
X						w = MAX_DIMEN;
X					else {
X						w = page_goal - page_total - page_depth;
X						if (count(n) != 1000) 
X							w = x_over_n(w, count(n)) * 1000;
X					}
X					if (w > dimen(n) - height(r))
X						w = dimen(n) - height(r);
X					q = vert_break(ins_ptr(p), w, depth(p));
X					height(r) += best_height_plus_depth;
X#ifdef STAT
X					show_split(n, w, q);
X#endif
X					if (count(n) != 1000)
X						best_height_plus_depth =
X							x_over_n(best_height_plus_depth, 1000L) * count(n);
X					page_goal -= best_height_plus_depth;
X					type(r) = SPLIT_UP;
X					broken_ptr(r) = q;
X					broken_ins(r) = p;
X					if (q == NULL)
X						insert_penalties += EJECT_PENALTY;
X					else if (type(q) == PENALTY_NODE)
X						insert_penalties += penalty(q);
X				}
X			}
X			goto contribute;
X			break;
X		
X		default:
X			confusion("page");
X			break;
X		}
X		if (pi < INF_PENALTY) {
X			if (page_total < page_goal) {
X				if (page_so_far[3] != 0 ||
X					page_so_far[4] != 0 ||
X					page_so_far[5] != 0)
X					b = 0;
X				else b = badness(page_goal - page_total, page_so_far[2]);
X			} else if (page_total - page_goal > page_shrink)
X				b = AWFUL_BAD;
X			else b = badness(page_total - page_goal, page_shrink);
X			if (b < AWFUL_BAD) {
X				if (pi <= EJECT_PENALTY)
X					c = pi;
X				else if (b < INF_BAD)
X					c = b + pi + insert_penalties;
X				else c = DEPLORABLE;
X			} else c = b;
X			if (insert_penalties >= 10000)
X				c = AWFUL_BAD;
X#ifdef STAT
X			show_page_stats(b, pi, c);
X#endif
X			if (c <= least_page_cost) {
X				best_page_break = p;
X				best_size = page_goal;
X				least_page_cost = c;
X				r = link(page_ins_head);
X				while (r != page_ins_head) {
X					best_ins_ptr(r) = last_ins_ptr(r);
X					r = link(r);
X				}
X			}
X			if (c == AWFUL_BAD || pi <= EJECT_PENALTY) {
X				fire_up(p);
X				if (output_active) return;
X				continue;
X			}
X		}
X		if (type(p) < GLUE_NODE || type(p) > KERN_NODE)
X			goto contribute;
X		
X	update_heights:
X		if (type(p) == KERN_NODE)
X			q = p;
X		else {
X			q = glue_ptr(p);
X			page_so_far[2 + stretch_order(q)] += stretch(q);
X			page_shrink += shrink(q);
X			if (shrink_order(q) != NORMAL && shrink(q) != 0) {
X				print_err("Infinite glue shrinkage found on current page");
X				help_inf_shrink_page();
X				error();
X				r = new_spec(q);
X				shrink_order(r) = NORMAL;
X				delete_glue_ref(q);
X				glue_ptr(p) = r;
X			}
X		}
X		page_total = page_total + page_depth + width(q);
X		page_depth = 0;
X
X	contribute:
X		if (page_depth > page_max_depth) {
X			page_total = page_total + page_depth - page_max_depth;
X			page_depth = page_max_depth;
X		}
X		link(page_tail) = p;
X		page_tail = p;
X		link(contrib_head) = link(p);
X		link(p) = NULL;
X		continue;
X
X	done:
X		link(contrib_head) = link(p);
X		link(p) = NULL;
X		flush_node_list(p);
X	} while (link(contrib_head) != NULL);
X	if (nest_ptr == 0)
X		tail = contrib_head;
X	else contrib_tail = contrib_head;
X}
X
Xfire_up (c)
X	ptr		c;
X{
X	int		n;
X	ptr		p;
X	ptr		q;
X	ptr		r;
X	ptr		s;
X	bool	wait;
X	ptr		prev_p;
X	scal	save_vfuzz;
X	val		save_vbadness;
X	ptr		save_split_top_skip;
X
X	if (type(best_page_break) == PENALTY_NODE) {
X		geq_word_define(INT_BASE+OUTPUT_PENALTY_CODE, penalty(best_page_break));
X		penalty(best_page_break) = INF_PENALTY;
X	} else geq_word_define(INT_BASE+OUTPUT_PENALTY_CODE, INF_PENALTY);
X	if (bot_mark != NULL) {
X		if (top_mark != NULL)
X			delete_token_ref(top_mark);
X		top_mark = bot_mark;
X		add_token_ref(top_mark);
X		delete_token_ref(first_mark);
X		first_mark = NULL;
X	}
X	if (c == best_page_break)
X		best_page_break = NULL;
X	if (box(255) != NULL) {
X		print_err("");
X		print_esc("box");
X		print("255 is not void");
X		help_box_255();
X		box_error(255);
X	}
X	insert_penalties = 0;
X	save_split_top_skip = split_top_skip;
X	r = link(page_ins_head);
X	while (r != page_ins_head) {
X		if (best_ins_ptr(r) != NULL) {
X			n = qo(subtype(r));
X			ensure_vbox(n);
X			if (box(n) == NULL)
X				box(n) = new_null_box();
X			p = box(n) + LIST_OFFSET;
X			while (link(p) != NULL)
X				p = link(p);
X			last_ins_ptr(r) = p;
X		}
X		r = link(r);
X	}
X	q = hold_head;
X	link(q) = NULL;
X	prev_p = page_head;
X	p = link(prev_p);
X	while (p != best_page_break) {
X		if (type(p) == INS_NODE) {
X			r = link(page_ins_head);
X			while (subtype(r) != subtype(p))
X				r = link(r);
X			if (best_ins_ptr(r) == NULL)
X				wait = TRUE;
X			else {
X				wait = FALSE;
X				s = ins_ptr(p);
X				link(last_ins_ptr(r)) = s;
X				s = last_ins_ptr(r);
X				if (best_ins_ptr(r) == p) {
X					if (type(r) == SPLIT_UP &&
X						broken_ins(r) == p &&
X						broken_ptr(r) != NULL) {
X						while (link(s) != broken_ptr(r))
X							s = link(s);
X						split_top_skip = split_top_ptr(p);
X						ins_ptr(p) = prune_page_top(broken_ptr(r));
X						if (ins_ptr(p) != NULL) {
X							temp_ptr = vpack(ins_ptr(p), NATURAL);
X							height(p) = height(temp_ptr) + depth(temp_ptr);
X							free_node(temp_ptr, BOX_NODE_SIZE);
X							wait = TRUE;
X						}
X						link(s) = NULL;
X					}
X					best_ins_ptr(r) = NULL;
X					n = qo(subtype(r));
X					temp_ptr = list_ptr(box(n));
X					free_node(box(n), BOX_NODE_SIZE);
X					box(n) = vpack(temp_ptr, NATURAL);
X				} else {
X					while (link(s) != NULL)
X						s = link(s);
X					last_ins_ptr(r) = s;
X				}
X			}
X			link(prev_p) = link(p);
X			link(p) = NULL;
X			if (wait) {
X				link(q) = p;
X				q = p;
X				incr(insert_penalties);
X			} else {
X				delete_glue_ref(split_top_ptr(p));
X				free_node(p, INS_NODE_SIZE);
X			}
X			p = prev_p;
X		} else if (type(p) == MARK_NODE) {
X			if (first_mark == NULL) {
X				first_mark = mark_ptr(p);
X				add_token_ref(first_mark);
X			}
X			if (bot_mark != NULL)
X				delete_token_ref(bot_mark);
X			bot_mark = mark_ptr(p);
X			add_token_ref(bot_mark);
X		}
X		prev_p = p;
X		p = link(prev_p);
X	}
X	split_top_skip = save_split_top_skip;
X	if (p != NULL) {
X		if (link(contrib_head) == NULL) {
X			if (nest_ptr == 0)
X				tail = page_tail;
X			else contrib_tail = page_tail;
X		}
X		link(page_tail) = link(contrib_head);
X		link(contrib_head) = p;
X		link(prev_p) = NULL;
X	}
X	save_vbadness = vbadness;
X	vbadness = INF_BAD;
X	save_vfuzz = vfuzz;
X	vfuzz = MAX_DIMEN;
X	box(255) = vpackage(link(page_head), best_size, EXACTLY, page_max_depth);
X	vbadness = save_vbadness;
X	vfuzz = save_vfuzz;
X	if (last_glue != MAX_HALFWORD)
X		delete_glue_ref(last_glue);
X	start_new_page();
X	if (q != hold_head) {
X		link(page_head) = link(hold_head);
X		page_tail = q;
X	}
X	r = link(page_ins_head);
X	while (r != page_ins_head) {
X		q = link(r);
X		free_node(r, PAGE_INS_NODE_SIZE);
X		r = q;
X	}
X	link(page_ins_head) = page_ins_head;
X	if (top_mark != NULL && first_mark == NULL) {
X		first_mark = top_mark;
X		add_token_ref(top_mark);
X	}
X	if (output_routine != NULL) {
X		if (dead_cycles >= max_dead_cycles) {
X			print_err("Output loop---");
X			print_int(dead_cycles);
X			print(" consecutive dead cycles");
X			help_dead_cycles();
X			error();
X		} else {
X			output_active = TRUE;
X			incr(dead_cycles);
X			push_nest();
X			mode = -VMODE;
X			prev_depth = IGNORE_DEPTH;
X			mode_line = -line;
X			begin_token_list(output_routine, OUTPUT_TEXT);
X			new_save_level(OUTPUT_GROUP);
X			normal_paragraph();
X			scan_left_brace();
X			return;
X		}
X	}
X	if (link(page_head) != NULL) {
X		if (link(contrib_head) == NULL) {
X			if (nest_ptr == 0) tail = page_tail;
X			else contrib_tail = page_tail;
X		} else link(page_tail) = link(contrib_head);
X		link(contrib_head) = link(page_head);
X		link(page_head) = NULL;
X		page_tail = page_head;
X	}
X	ship_out(box(255));
X	box(255) = NULL;
X}
X
X/*
X *	Help text
X */
X
Xhelp_tut ()
X{
X	help3("Tut tut: You're trying to \\insert into a",
X	"\\box register that now contains an \\hbox.",
X	"Proceed, and I'll discard its present contents.");
X}
X
Xhelp_vsplit_vbox ()
X{
X	help2("The box you are trying to split is an \\hbox.",
X	"I can't split such boxes, so I'll leave it alone.");
X}
X
Xhelp_inf_shrink_ins ()
X{
X	help3("The correction glue for page breaking with insertions",
X	"must have finite shrinkability. But you may proceed,",
X	"since the offensive shrinkability has been made finite.");
X}
X
Xhelp_inf_shrink_box ()
X{
X	help4("The box you are \\vsplitting contains some infinitely",
X	"shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
X	"Such glue doesn't belong there; but you can safely proceed,",
X	"since the offensive shrinkability has been made finite.");
X}
X
Xhelp_inf_shrink_page ()
X{
X	help4("The page about to be output contains some infinitely ",
X	"shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
X	"Such glue doesn't belong there; but you can safely proceed,",
X	"since the offensive shrinkability has been made finite.");
X}
X
Xhelp_box_255 ()
X{
X	help2("You shouldn't use \\box255 except in \\output routines.",
X	"Proceed, and I'll discard its present contents.");
X}
X
Xhelp_dead_cycles ()
X{
X	help3("I've concluded that your \\output is awry; it never does a",
X	"\\shipout, so I'm shipping \\box255 out myself. Next time",
X	"increase \\maxdeadcycles if you want me to be more patient!");
X}
SHAR_EOF
chmod 0444 page.c || echo "restore of page.c fails"
set `wc -c page.c`;Sum=$1
if test "$Sum" != "19118"
then echo original size 19118, current size $Sum;fi
echo "x - extracting page.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > page.h &&
X
X/*
X *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
X *    Copying of this file is granted according to the provisions 
X *    specified in the file COPYING which must accompany this file.
X */
X
X
X/*
X *		page.h
X */
X
Xglobal	ptr		last_page_glue;
X
X#define	active_height	active_width
X#define	cur_height		active_height[1]
X
Xptr		prune_page_top();
X
Xglobal	scal	best_height_plus_depth;
X#define	DEPLORABLE		100000
X
Xptr		vert_break();
Xptr		vsplit();
X
Xglobal	ptr		page_tail;
Xglobal	int		page_contents;
X
X#define	INSERTS_ONLY	1
X#define	BOX_THERE		2
X
Xglobal	ptr		best_page_break;
Xglobal	scal	best_size;
Xglobal	scal	page_max_depth;
Xglobal	val		least_page_cost;
X
X#define	INSERTING				0
X#define	SPLIT_UP				1
X#define	broken_ptr(N)			link(N + 1)
X#define	broken_ins(N)			info(N + 1)
X#define	last_ins_ptr(N)			link(N + 2)
X#define	best_ins_ptr(N)			info(N + 2)
X#define	PAGE_INS_NODE_SIZE		4
X
Xglobal	scal	page_so_far[];
X
X#define	page_goal	page_so_far[0]
X#define	page_total	page_so_far[1]
X#define	page_shrink	page_so_far[6]
X#define	page_depth	page_so_far[7]
X
Xglobal	ptr		last_glue;
Xglobal	val		last_penalty;
Xglobal	scal	last_kern;
Xglobal	val		insert_penalties;
X
Xint		print_totals();
X
X#define	start_new_page() \
X	{page_contents = EMPTY; \
X	page_tail = page_head; \
X	link(page_head) = NULL; \
X	last_glue = MAX_HALFWORD; \
X	last_penalty = 0; \
X	last_kern = 0; \
X	page_depth = 0; \
X	page_max_depth = 0;}
X
Xint		freeze_page_specs();
X
Xglobal	bool	output_active;
X
Xint		ensure_vbox();
Xint		box_error();
Xint		build_page();
Xint		fire_up();
X
X#define	contrib_tail			nest[0].tail_field
SHAR_EOF
chmod 0444 page.h || echo "restore of page.h fails"
set `wc -c page.h`;Sum=$1
if test "$Sum" != "1565"
then echo original size 1565, current size $Sum;fi
echo "x - extracting par.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > par.c &&
X
X/*
X *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
X *    Copying of this file is granted according to the provisions 
X *    specified in the file COPYING which must accompany this file.
X */
X
X
X/*
X *		par.c
X */
X
X#include "tex.h"
X#include "heap.h"
X#include "arith.h"
X#include "eq.h"
X#include "tfm.h"
X#include "str.h"
X#include "tokenstack.h"
X#include "evalstack.h"
X#include "box.h"
X#include "pack.h"
X#include "hyph.h"
X#include "print.h"
X#include "error.h"
X#include "par.h"
X
Xscal	active_width[7];
Xval		actual_looseness;
Xscal	background[7];
Xptr		best_bet;
Xhword	best_line;
Xhword	best_pl_line[4];
Xptr		best_place[4];
Xscal	break_width[7];
Xscal	cur_active_width[7];
Xptr		cur_p;
Xscal	disc_width;
Xhword	easy_line;
Xval		fewest_demerits;
Xscal	first_indent;
Xscal	first_width;
Xptr		just_box;
Xhword	last_special_line;
Xint		line_diff;
Xval		minimal_demerits[4];
Xval		minimum_demerits;
Xbool	no_shrink_error_yet;
Xptr		passive;
Xptr		printed_node;
Xptr		pass_number;
Xscal	second_indent;
Xbool	second_pass;
Xscal	second_width;
Xval		threshold;
X
X#define	act_width	active_width[1]
X
X#define	store_background(W) \
X	(active_width[W] = background[W])
X
X#define	store_break_width(W) \
X	(active_width[W] = break_width[W])
X
X#define	update_active(W) \
X	(active_width[W] += mem[r + W].sc)
X
X#define	copy_to_cur_active(W) \
X	(cur_active_width[W] = active_width[W])
X
X#define	downdate_width(W) \
X	(cur_active_width[W] -= mem[prev_r + W].sc)
X
X#define	update_width(W) \
X	(cur_active_width[W] += mem[r + W].sc)
X
X#define	set_break_width_to_background(W) \
X	(break_width[W] = background[W])
X
X#define	combine_two_deltas(W) \
X	(mem[prev_r + W].sc += mem[r + W].sc)
X
X#define	convert_to_break_width(W) \
X	(mem[prev_r + W].sc = mem[prev_r + W].sc + \
X							break_width[W] - cur_active_width[W])
X
X#define	new_delta_to_break_width(W) \
X	(mem[q + W].sc = break_width[W] - cur_active_width[W])
X
X#define	new_delta_from_break_width(W) \
X	(mem[q + W].sc = cur_active_width[W] - break_width[W])
X
X#define	width_lig_char(C) \
X	char_width(font(lig_char(C)), \
X				char_info(font(lig_char(C)), character(lig_char(C))))
X
X#define	width_char(C) \
X	char_width(font(C), char_info(font(C), character(C)))
X		
X#ifdef STAT
Xshow_break_node (q, f, h)
X	ptr		q;
X	int		f;
X	int		h;
X{
X	if (tracing_paragraphs > 0) {
X		print_nl("@@");
X		print_int(serial(passive));
X		print(": line ");
X		print_int(line_number(q) - 1);
X		print_char('.');
X		print_int(f);
X		if (h == HYPHENATED)
X			print_char('-');
X		print(" t=");
X		print_val(total_demerits(q));
X		print(" -> @@");
X		if (prev_break(passive) == NULL)
X			print("0");
X		else print_int(serial(prev_break(passive)));
X	}
X}
X
Xshow_break_status (r, a, b, p, d)
X	ptr		r;
X	bool	a;
X	val		b;
X	val		p;
X	val		d;
X{
X	ptr		save_link;
X
X	if (tracing_paragraphs > 0) {
X		if (printed_node != cur_p) {
X			print_nl("");
X			if (cur_p == NULL)
X				short_display(link(printed_node));
X			else {
X				save_link = link(cur_p);
X				link(cur_p) = NULL;
X				print_nl("");
X				short_display(link(printed_node));
X				link(cur_p) = save_link;
X			}
X			printed_node = cur_p;
X		}
X		print_nl("@");
X		if (cur_p == NULL)
X			print_esc("par");
X		else if (type(cur_p) != GLUE_NODE) {
X			if (type(cur_p) == PENALTY_NODE)
X				print_esc("penalty");
X			else if (type(cur_p) == DISC_NODE)
X				print_esc("discretionary");
X			else if (type(cur_p) == KERN_NODE)
X				print_esc("kern");
X			else print_esc("math");
X		}
X		print(" via @@");
X		if (break_node(r) == NULL)
X			print_char('0');
X		else print_int(serial(break_node(r)));
X		print(" b=");
X		if (a) print_char('*');
X		else print_val(b);
X		print(" p=");
X		print_val(p);
X		print(" d=");
X		print_val(d);
X	}
X}
X
Xupdate_printed_node()
X{
X	qword	t;
X
X	if (cur_p == printed_node &&
X		cur_p != NULL &&
X		type(cur_p) == DISC_NODE)
X		for (t = replace_count(cur_p); t > 0; decr(t))
X			printed_node = link(printed_node);
X}
X#endif
X
Xset_break_width (break_type)
X	int		break_type;
X{
X	ptr		s;
X	int		t;
X	ptr		v;
X
X	do_all_six(set_break_width_to_background);
X	s = cur_p;
X	if (break_type > UNHYPHENATED && cur_p != NULL) {
X		t = replace_count(cur_p);
X		v = cur_p;
X		s = post_break(cur_p);
X		while (t > 0) {
X			decr(t);
X			v = link(v);
X			if (is_char_node(v)) 
X				break_width[1] -= width_char(v);
X			else {
X				switch (type(v))
X				{
X				case LIGATURE_NODE:
X					break_width[1] -= width_lig_char(v);
X					break;
X
X				case HLIST_NODE:
X				case VLIST_NODE:
X				case RULE_NODE:
X				case KERN_NODE:
X					break_width[1] -= width(v);
X					break;
X
X				default:
X					confusion("disc1");
X					break;
X				}
X			}
X		}
X		for (; s != NULL; s = link(s)) {
X			if (is_char_node(s))
X				break_width[1] += width_char(s);
X			else {
X				switch (type(s))
X				{
X				case LIGATURE_NODE:
X					break_width[1] += width_lig_char(s);
X					break;
X
X				case HLIST_NODE:
X				case VLIST_NODE:
X				case RULE_NODE:
X					break_width[1] += width(s);
X					break;
X
X				case KERN_NODE:
X					if (t == 0 && subtype(s) != ACC_KERN)
X						t = -1;	/* discardable */
X					else
X						break_width[1] += width(s);
X					break;
X					
X				default:
X					confusion("disc2");
X					break;
X				}
X			}
X			incr(t);
X		}
X		break_width[1] += disc_width;
X		if (t == 0)
X			s = link(v); /* more nodes may be discardable after
X					the break */
X	}
X	for (; s != NULL; s = link(s)) {
X		if (is_char_node(s))
X			return;
X		switch (type(s)) {
X		      case GLUE_NODE:
X			v = glue_ptr(s);
X			break_width[1] -= width(v);
X			break_width[2 + stretch_order(v)] -= stretch(v);
X			break_width[6] -= shrink(v);
X			break;
X			
X		      case PENALTY_NODE:
X			break;
X			
X		      case MATH_NODE:
X		      case KERN_NODE:
X			if (subtype(s) == ACC_KERN) 
X				return;
X			else break_width[1] -= width(s);
X			break;
X
X		      default:
X			return;
X			break;
X		}
X	}
X}
X
Xtry_break (pi, break_type)
X	val		pi;
X	int		break_type;
X{
X	val		b;
X	val		d;
X	hword	l;
X	ptr		q;
X	ptr		r;
X	hword	old_l;
X	ptr		prev_r;
X	int		fit_class;
X	scal	shortfall;
X	scal	line_width;
X	ptr		prev_prev_r;
X	bool	no_break_yet;
X	bool	artificial_badness;
X	bool	node_r_stays_active;
X	
X	no_break_yet = TRUE;
X	old_l = 0;
X	prev_r = active;
X	if (abs(pi) >= INF_PENALTY) {
X		if (pi > 0) {
X#ifdef STAT
X			update_printed_node();
X#endif
X			return;
X		} else
X			pi = EJECT_PENALTY;
X	}
X	do_all_six(copy_to_cur_active);
X	loop {
X		r = link(prev_r);
X		if (type(r) == DELTA_NODE) {
X			do_all_six(update_width);
X			prev_prev_r = prev_r;
X			prev_r = r;
X			continue;
X		}
X		l = line_number(r);
X		if (l > old_l) {
X			if (minimum_demerits < AWFUL_BAD &&
X				(old_l != easy_line || r == last_active)) {
X				if (no_break_yet) {
X					no_break_yet = FALSE;
X					set_break_width(break_type);
X				}
X				if (type(prev_r) == DELTA_NODE) {
X					do_all_six(convert_to_break_width);
X				} else if (prev_r == active) {
X					do_all_six(store_break_width);
X				} else {
X					q = get_node(DELTA_NODE_SIZE);
X					link(q) = r;
X					type(q) = DELTA_NODE;
X					subtype(q) = 0;
X					do_all_six(new_delta_to_break_width);
X					link(prev_r) = q;
X					prev_prev_r = prev_r;
X					prev_r = q;
X				}
X				minimum_demerits += abs(adj_demerits);
X				fit_class = VERY_LOOSE_FIT;
X				while (fit_class <= TIGHT_FIT) {
X					if (minimal_demerits[fit_class] <= minimum_demerits) {
X						q = get_node(PASSIVE_NODE_SIZE);
X						link(q) = passive;
X						passive = q;
X						cur_break(q) = cur_p;
X#ifdef STAT
X						incr(pass_number);
X						serial(q) = pass_number;
X#endif
X						prev_break(q) = best_place[fit_class];
X						q = get_node(ACTIVE_NODE_SIZE);
X						break_node(q) = passive;
X						line_number(q) = best_pl_line[fit_class] + 1;
X						fitness(q) = fit_class;
X						type(q) = break_type;
X						total_demerits(q) = minimal_demerits[fit_class];
X						link(q) = r;
X						link(prev_r) = q;
X						prev_r = q;
X#ifdef STAT
X						show_break_node(q, fit_class, break_type);
X#endif
X					}
X					minimal_demerits[fit_class] = AWFUL_BAD;
X					incr(fit_class);
X				}
X				minimum_demerits = AWFUL_BAD;
X				if (r != last_active) {
X					q = get_node(DELTA_NODE_SIZE);
X					link(q) = r;
X					type(q) = DELTA_NODE;
X					subtype(q) = 0;
X					do_all_six(new_delta_from_break_width);
X					link(prev_r) = q;
X					prev_prev_r = prev_r;
X					prev_r = q;
X				}
X			}
X			if (r == last_active) {
X#ifdef STAT
X				update_printed_node();
X#endif
X				return;
X			}
X			if (l > easy_line) {
X				line_width = second_width;
X				old_l = MAX_HALFWORD - 1;
X			} else {
X				old_l = l;
X				if (l > last_special_line)
X					line_width = second_width;
X				else if (par_shape_ptr == NULL)
X					line_width = first_width;
X				else line_width = mem[par_shape_ptr + 2 * l].sc;
X			}
X		}
X#ifdef STAT
X		artificial_badness = FALSE;
X#endif
X		shortfall = line_width - cur_active_width[1];
X		if (shortfall > 0) {
X			if (cur_active_width[3] != 0 ||
X				cur_active_width[4] != 0 ||
X				cur_active_width[5] != 0) {
X				b = 0;
X				fit_class = DECENT_FIT;
X			} else {
X				if (shortfall > 7230584 && cur_active_width[2] < 1663497) {
X					b = INF_BAD;
X					fit_class = VERY_LOOSE_FIT;
X					goto done;
X				}
X				b = badness(shortfall, cur_active_width[2]);
X				if (b > 12)
X					if (b > 99)
X						fit_class = VERY_LOOSE_FIT;
X					else fit_class = LOOSE_FIT;
X				else fit_class = DECENT_FIT;
X			}
X		} else {
X			if (-shortfall > cur_active_width[6])
X				b = INF_BAD + 1;
X			else b = badness(-shortfall, cur_active_width[6]);
X			if (b > 12)
X				fit_class = TIGHT_FIT;
X			else fit_class = DECENT_FIT;
X		}
X		
X	done:
X		if (b > INF_BAD || pi == EJECT_PENALTY) {
X			if (second_pass &&
X				minimum_demerits == AWFUL_BAD &&
X				link(r) == last_active &&
X				prev_r == active) {
X				b = 0;
X#ifdef STAT
X				artificial_badness = TRUE;
X#endif
X			} else if (b > threshold)
X				goto deactivate;
X			node_r_stays_active = FALSE;
X		} else {
X			prev_r = r;
X			if (b > threshold) continue;
X			node_r_stays_active = TRUE;
X		}
X		d = line_penalty + b;
X		d = d * d;
X		if (pi != 0) {
X			if (pi > 0)
X				d += pi * pi;
X			else if (pi > EJECT_PENALTY)
X				d -= pi * pi;
X		}
X		if (break_type == HYPHENATED && type(r) == HYPHENATED) {
X			if (cur_p != NULL)
X				d += double_hyphen_demerits;
X			else d += final_hyphen_demerits;
X		}
X		if (abs(fit_class - (int) fitness(r)) > 1)
X			d += adj_demerits;
X#ifdef STAT
X		show_break_status(r, artificial_badness, b, pi, d);
X#endif
X		d += total_demerits(r);
X		if (d <= minimal_demerits[fit_class]) {
X			minimal_demerits[fit_class] = d;
X			best_place[fit_class] = break_node(r);
X			best_pl_line[fit_class] = l;
X			if (d < minimum_demerits)
X				minimum_demerits = d;
X		}
X		if (node_r_stays_active) continue;
X		
X	deactivate:
X		link(prev_r) = link(r);
X		free_node(r, ACTIVE_NODE_SIZE);
X		if (prev_r == active) {
X			r = link(active);
X			if (type(r) == DELTA_NODE) {
X				do_all_six(update_active);
X				do_all_six(copy_to_cur_active);
X				link(active) = link(r);
X				free_node(r, DELTA_NODE_SIZE);
X			}
X		} else if (type(prev_r) == DELTA_NODE) {
X			r = link(prev_r);
X			if (r == last_active) {
X				do_all_six(downdate_width);
X				link(prev_prev_r) = last_active;
X				free_node(prev_r, DELTA_NODE_SIZE);
X				prev_r = prev_prev_r;
X			} else if (type(r) == DELTA_NODE) {
X				do_all_six(update_width);
X				do_all_six(combine_two_deltas);
X				link(prev_r) = link(r);
X				free_node(r, DELTA_NODE_SIZE);
X			}
X		}
X	}
X}
X
X
X#define	kern_break() \
X	{if (!is_char_node(link(cur_p)) && auto_breaking && \
X		type(link(cur_p)) == GLUE_NODE) \
X		try_break(0L, UNHYPHENATED); \
X	act_width += width(cur_p);}
X
X#define	check_shrinkage(S) \
X	{if (shrink_order(S) != NORMAL && shrink(S) != 0) \
X		S = finite_shrink(S);}
X
Xline_break (final_widow_penalty)
X	val		final_widow_penalty;
X{
X	int		c;
X	int		j;
X	ptr		q;
X	ptr		r;
X	ptr		s;
X	ptr		prev_p;
X	bool	auto_breaking;
X
X	pack_begin_line = mode_line;
X	link(temp_head) = link(head);
X	if (is_char_node(tail)) {
X		tail_append(new_penalty(INF_PENALTY));
X	} else if (type(tail) != GLUE_NODE) {
X		tail_append(new_penalty(INF_PENALTY));
X	} else {
X		type(tail) = PENALTY_NODE;
X		delete_glue_ref(glue_ptr(tail));
X		flush_node_list(leader_ptr(tail));
X		penalty(tail) = INF_PENALTY;
X	}
X	link(tail) = new_param_glue(PAR_FILL_SKIP_CODE);
X	pop_nest();
X	no_shrink_error_yet = TRUE;
X	check_shrinkage(left_skip);
X	check_shrinkage(right_skip);
X	q = left_skip;
X	r = right_skip;
X	background[1] = width(q) + width(r);
X	background[2] = 0;
SHAR_EOF
echo "End of part 11"
echo "File par.c is continued in part 12"
echo "12" > s2_seq_.tmp
exit 0



More information about the Comp.unix.xenix mailing list