home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
lout2.lzh
/
LOUT2
/
z21.c
< prev
next >
Wrap
Text File
|
1994-01-23
|
11KB
|
271 lines
/*@z21.c:Galley Maker:SizeGalley()@*******************************************/
/* */
/* LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05) */
/* COPYRIGHT (C) 1993 Jeffrey H. Kingston */
/* */
/* Jeffrey H. Kingston (jeff@cs.su.oz.au) */
/* Basser Department of Computer Science */
/* The University of Sydney 2006 */
/* AUSTRALIA */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 1, or (at your option) */
/* any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* FILE: z21.c */
/* MODULE: Galley Maker */
/* EXTERNS: SizeGalley() */
/* */
/*****************************************************************************/
#include "externs"
/*****************************************************************************/
/* */
/* SizeGalley(hd, env, rows, joined, nonblock, trig, style, c, target, */
/* dest_index, recs, inners) */
/* */
/* Convert unsized galley hd into sized format. The input parameters are: */
/* */
/* hd the galley to be converted */
/* env its environment */
/* rows TRUE if the resulting galley may have more than one row */
/* joined TRUE if the resulting galley must be simply joined */
/* nonblock Set the non_blocking() field of RECEPTIVEs to this value */
/* trig TRUE if indefinites of hd may trigger external galleys */
/* *style The initial style */
/* *c the width constraint hd should conform to */
/* target if non-nil, expand indefinite objects to reveal a */
/* @Galley within this symbol */
/* */
/* The output parameters, in addition to the converted hd, are: */
/* */
/* dest_index the index of the @Galley found within target, if any */
/* recs list of all RECURSIVE indexes found (or nil if none) */
/* inners list of all UNATTACHED indexes found (or nil if none) */
/* */
/*****************************************************************************/
SizeGalley(hd, env, rows, joined, nonblock, trig, style, c, target,
dest_index, recs, inners)
OBJECT hd, env; BOOLEAN rows, joined, nonblock, trig; STYLE *style;
CONSTRAINT *c; OBJECT target, *dest_index, *recs, *inners;
{ OBJECT y, link, z, crs, t, tlink, zlink, tmp;
OBJECT extras, tmp1, tmp2, bt[2], ft[2];
assert( type(hd) == HEAD && Down(hd) != hd, "SizeGalley: precondition!" );
assert( !sized(hd), "SizeGalley: already sized!" );
debug6(DGM, D, "SizeGalley(hd, -, %s, %s, %s, %s, %s, %s, -, -, -), hd =",
bool(joined), bool(nonblock), bool(trig), EchoStyle(style),
EchoConstraint(c), SymName(target));
ifdebug(DGM, DD, DebugObject(hd));
/* manifest the child of hd, making sure it is simply joined if required */
tmp1 = target;
Child(y, Down(hd));
crs = nil;
bt[COL] = ft[COL] = bt[ROW] = ft[ROW] = nil;
if( joined )
{ bt[COL] = New(THREAD); ft[COL] = New(THREAD);
y = Manifest(y, env, style, bt, ft, &tmp1, &crs, TRUE, must_expand(hd));
assert( Down(bt[COL]) != bt[COL] && Down(ft[COL]) != ft[COL],
"SizeGalley: threads!" );
Child(tmp1, Down(bt[COL])); Child(tmp2, Down(ft[COL]));
if( Down(bt[COL]) != LastDown(bt[COL]) ||
Down(ft[COL]) != LastDown(ft[COL]) || tmp1 != tmp2 )
Error(FATAL, &fpos(y), "galley %s must have just one column mark",
SymName(actual(hd)) );
DisposeObject(bt[COL]); DisposeObject(ft[COL]);
}
else y = Manifest(y, env, style, bt, ft, &tmp1, &crs, TRUE, must_expand(hd));
/* horizontally size and break hd */
debug0(DGM, DD, "SizeGalley: after manifesting, hd =");
ifdebug(DGM, DD, DebugObject(hd));
debug0(DGM, DD, "SizeGalley horizontally sizing and breaking hd:");
CopyConstraint(constraint(hd), *c);
y = MinSize(y, COL, &extras);
debug0(DOB, DD, " calling BreakObject from SizeGalley");
y = BreakObject(y, c);
back(hd, COL) = back(y, COL);
fwd(hd, COL) = fwd(y, COL);
assert( FitsConstraint(back(hd, COL), fwd(hd, COL), *c),
"SizeGalley: BreakObject failed to fit!" );
debug2(DSF, D, "MinSize(hd, COL) = %s,%s",
EchoLength(back(hd, COL)), EchoLength(fwd(hd, COL)) );
/* get the rows of hd to the top level, if required */
seen_nojoin(hd) = FALSE;
if( rows )
{ /* OBJECT prev_gap = nil; */
debug0(DGM, DD, "SizeGalley cleaning up rows of hd:");
for( link = hd; NextDown(link) != hd; link = NextDown(link) )
{ Child(y, NextDown(link));
debug2(DGM, DD, " cleaning %s: %s", Image(type(y)), EchoObject(y));
switch( type(y) )
{
case GAP_OBJ:
/* prev_gap = y; */
if( !join(gap(y)) ) seen_nojoin(hd) = TRUE;
break;
case VCAT:
TransferLinks(Down(y), y, Up(y));
DisposeChild(Up(y));
link = PrevDown(link);
break;
case SPLIT:
assert(Up(y)==LastUp(y), "SizeGalley COL_THR: Up(y)!=LastUp(y)!");
Child(z, DownDim(y, ROW));
if( is_indefinite(type(z)) ) external(z) = TRUE;
else if( type(z) == VCAT )
{ OBJECT hor, thor, clink, dlink;
Child(hor, DownDim(y, COL));
assert( type(hor) == COL_THR, "SizeGalley: missing COL_THR!" );
Parent(thor, UpDim(z, COL));
assert( hor == thor, "SizeGalley/SPLIT: hor != thor!" );
clink = DownDim(y, COL);
dlink = UpDim(z, COL);
for( tlink = LastDown(z); tlink != z; tlink = PrevDown(tlink) )
{ Child(t, tlink);
if( type(t) == GAP_OBJ ) Link(NextDown(link), t);
else
{ tmp = New(SPLIT);
back(tmp, COL) = back(hor, COL);
fwd(tmp, COL) = fwd(hor, COL);
Link(NextDown(link), tmp);
Link(tmp, NextUp(clink));
Link(NextDown(dlink), t);
Link(tmp, t);
}
}
DeleteLink(dlink);
assert(Up(y)==LastUp(y), "SizeGalley COL_THR: Up(y) != LastUp(y)!");
DisposeChild(Up(y));
link = PrevDown(link);
}
break;
case CLOSURE:
case HEAD:
external(y) = TRUE;
break;
default:
break;
}
}
}
/* size the rows of hd and attach indices where needed */
debug0(DGM, DD, "SizeGalley sizing rows of hd =");
ifdebug(DGM, DD, DebugObject(hd));
*recs = *inners = *dest_index = nil;
for( link = Down(hd); link != hd; link = NextDown(link) )
{ Child(y, link);
if( type(y) == GAP_OBJ || is_index(type(y)) ) continue;
debug0(DGM, DDD, " ROW sizing:");
ifdebug(DGM, DDD, DebugObject(y));
extras = New(ACAT);
y = MinSize(y, ROW, &extras);
debug3(DSF, D, "MinSize( %s , ROW ) = %s,%s", EchoObject(y),
EchoLength(back(y, ROW)), EchoLength(fwd(y, ROW)) );
debug0(DGM, DDD, " ROW result:");
ifdebug(DGM, DDD, DebugObject(y));
/* now attach indexes in front of y */
for( zlink = Down(extras); zlink != extras; zlink = NextDown(zlink) )
{ Child(z, zlink);
blocked(z) = FALSE;
/* debug1(DCR, D, " extra: %s", EchoObject(z)); */
debug1(DGM, DD, " extra: %s", EchoObject(z));
switch( type(z) )
{
case RECEPTIVE:
/* debug2(DCR, D, " ... uses_ext = %s, trig = %s",
bool(uses_extern_target(actual(actual(z)))), bool(trig)); */
trigger_externs(z) = uses_extern_target(actual(actual(z))) && trig;
non_blocking(z) = nonblock;
if( actual(actual(z)) == GalleySym ) *dest_index = z;
break;
case RECURSIVE:
if( *recs == nil ) *recs = New(ACAT);
Link(*recs, z);
break;
case UNATTACHED:
if( *inners == nil ) *inners = New(ACAT);
Link(*inners, z);
break;
case EXPAND_IND:
case GALL_PREC:
case GALL_FOLL:
case GALL_TARG:
case CROSS_PREC:
case CROSS_FOLL:
case CROSS_TARG:
debug1(DCR, DD, " SizeGalley: %s", EchoObject(z));
break;
default:
Error(INTERN, no_fpos, "SizeGalley: %s", Image(type(z)) );
break;
}
}
TransferLinks(Down(extras), extras, link);
assert( Down(extras) == extras && Up(extras) == extras, "SizeG: extras!");
Dispose(extras);
}
/* insinuate cross references */
if( crs != nil )
{
debug1(DCR, D, "SizeGalley insinuating %s", crs);
TransferLinks(Down(crs), crs, Down(hd));
DisposeObject(crs);
}
/* check that *dest_index was found if it was required, and exit */
if( target != nil && *dest_index == nil )
Error(FATAL, &fpos(hd), "Unexpected absence of %s from the body of %s",
SymName(target), SymName(actual(hd)));
debug3(DGM, D, "SizeGalley returning %s,%s %s; hd =",
EchoLength(back(hd, COL)), EchoLength(fwd(hd, COL)),
EchoConstraint(&constraint(hd)));
ifdebug(DGM, DD, DebugObject(hd));
sized(hd) = TRUE;
} /* end SizeGalley */