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