1 /*@z21.c:Galley Maker:SizeGalley()@*******************************************/
2 /* */
3 /* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.39) */
4 /* COPYRIGHT (C) 1991, 2008 Jeffrey H. Kingston */
5 /* */
6 /* Jeffrey H. Kingston (jeff@it.usyd.edu.au) */
7 /* School of Information Technologies */
8 /* The University of Sydney 2006 */
9 /* AUSTRALIA */
10 /* */
11 /* This program is free software; you can redistribute it and/or modify */
12 /* it under the terms of the GNU General Public License as published by */
13 /* the Free Software Foundation; either Version 3, or (at your option) */
14 /* any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */
24 /* */
25 /* FILE: z21.c */
26 /* MODULE: Galley Maker */
27 /* EXTERNS: SizeGalley() */
28 /* */
29 /*****************************************************************************/
30 #include "externs.h"
31
32 /*****************************************************************************/
33 /* */
34 /* SizeGalley(hd, env, rows, joined, nonblock, trig, style, c, target, */
35 /* dest_index, recs, inners, enclose) */
36 /* */
37 /* Convert unsized galley hd into sized format. The input parameters are: */
38 /* */
39 /* hd the galley to be converted */
40 /* env its environment (needs to be "held" while manifesting) */
41 /* rows TRUE if the resulting galley may have more than one row */
42 /* joined TRUE if the resulting galley must be simply joined */
43 /* nonblock Set the non_blocking() field of RECEPTIVEs to this value */
44 /* trig TRUE if indefinites of hd may trigger external galleys */
45 /* *style The initial style */
46 /* *c the width constraint hd should conform to */
47 /* target if non-nilobj, expand indefinite objects to reveal a */
48 /* @Galley within this symbol */
49 /* enclose If non-nilobj, enclose any @Galley symbol encountered */
50 /* during manifesting by this symbol. */
51 /* */
52 /* The output parameters, in addition to the converted hd, are: */
53 /* */
54 /* dest_index the index of the @Galley found within target, if any */
55 /* recs list of all RECURSIVE indexes found (or nilobj if none) */
56 /* inners list of all UNATTACHED indexes found (or nilobj if none), */
57 /* not including any that come after the target or InputSym. */
58 /* */
59 /*****************************************************************************/
60
SizeGalley(OBJECT hd,OBJECT env,BOOLEAN rows,BOOLEAN joined,BOOLEAN nonblock,BOOLEAN trig,STYLE * style,CONSTRAINT * c,OBJECT target,OBJECT * dest_index,OBJECT * recs,OBJECT * inners,OBJECT enclose)61 void SizeGalley(OBJECT hd, OBJECT env, BOOLEAN rows, BOOLEAN joined,
62 BOOLEAN nonblock, BOOLEAN trig, STYLE *style, CONSTRAINT *c, OBJECT target,
63 OBJECT *dest_index, OBJECT *recs, OBJECT *inners, OBJECT enclose)
64 { OBJECT y, link, z, crs, t, tlink, zlink, tmp, why;
65 OBJECT extras, tmp1, tmp2, bt[2], ft[2], hold_env;
66 BOOLEAN after_target;
67
68 assert( type(hd) == HEAD && Down(hd) != hd, "SizeGalley: precondition!" );
69 assert( !sized(hd), "SizeGalley: already sized!" );
70 debug6(DGM, D, "SizeGalley(%s, -, %s, %s, %s, %s, -, %s, -, -, -), hd =",
71 SymName(actual(hd)), bool(rows), bool(joined), bool(nonblock),
72 bool(trig), EchoConstraint(c));
73 debug1(DGM, DD, " env = %s", EchoObject(env));
74 ifdebug(DGM, D, DebugObject(hd));
75
76 /* manifest the child of hd, making sure it is simply joined if required */
77 Child(y, Down(hd));
78 tmp1 = target;
79 tmp2 = enclose;
80 crs = nilobj;
81 bt[COLM] = ft[COLM] = bt[ROWM] = ft[ROWM] = nilobj;
82 New(hold_env, ACAT); Link(hold_env, env);
83 if( AllowCrossDb && type(y) == CLOSURE && has_optimize(actual(y))
84 && FindOptimize(y, env) )
85 {
86 SetOptimize(hd, style);
87 }
88 debug2(DOM, D, "[ calling Manifest(%s) from SizeGalley(%s)",
89 Image(type(y)), SymName(actual(hd)));
90 debug2(DOB, D, "[ calling Manifest(%s) from SizeGalley(%s)",
91 Image(type(y)), SymName(actual(hd)));
92 if( joined )
93 { New(bt[COLM], THREAD); New(ft[COLM], THREAD);
94 debug0(DGM, DD, "SizeGalley calling Manifest (joined)");
95 y = Manifest(y, env, style, bt, ft, &tmp1, &crs, TRUE, must_expand(hd),
96 &tmp2, FALSE);
97 assert( Down(bt[COLM]) != bt[COLM] && Down(ft[COLM]) != ft[COLM],
98 "SizeGalley: threads!" );
99 Child(tmp1, Down(bt[COLM])); Child(tmp2, Down(ft[COLM]));
100 if( Down(bt[COLM]) != LastDown(bt[COLM]) ||
101 Down(ft[COLM]) != LastDown(ft[COLM]) || tmp1 != tmp2 )
102 Error(21, 1, "galley %s must have just one column mark",
103 FATAL, &fpos(y), SymName(actual(hd)) );
104 DisposeObject(bt[COLM]); DisposeObject(ft[COLM]);
105 }
106 else
107 { debug0(DGM, DD, "SizeGalley calling Manifest (not joined)");
108 y = Manifest(y, env, style, bt, ft, &tmp1, &crs, TRUE, must_expand(hd),
109 &tmp2, FALSE);
110 }
111 debug2(DOM, D, "] returning Manifest(%s) from SizeGalley(%s)",
112 Image(type(y)), SymName(actual(hd)));
113 debug2(DOB, D, "] returning Manifest(%s) from SizeGalley(%s)",
114 Image(type(y)), SymName(actual(hd)));
115 DisposeObject(hold_env);
116 debug0(DGM, DD, "SizeGalley: after manifesting, hd =");
117 ifdebug(DGM, DD, DebugObject(hd));
118
119 /* horizontally size hd */
120 debug0(DGM, DD, "SizeGalley horizontally sizing hd:");
121 New(extras, ACAT);
122 debug2(DSF, D, "[ calling MinSize(%s) from SizeGalley(%s)",
123 Image(type(y)), SymName(actual(hd)));
124 y = MinSize(y, COLM, &extras);
125 debug2(DSF, D, "] returning MinSize(%s) from SizeGalley(%s)",
126 Image(type(y)), SymName(actual(hd)));
127
128 /* break hd if vertical galley */
129 if( gall_dir(hd) == ROWM )
130 {
131 CopyConstraint(constraint(hd), *c);
132 debug0(DGM, DD, "SizeGalley calling BreakObject:");
133 debug2(DOB, D, "[ calling BreakObject(%s) from SizeGalley(%s)",
134 Image(type(y)), SymName(actual(hd)));
135 y = BreakObject(y, c);
136 debug2(DOB, D, "] returning BreakObject(%s) from SizeGalley(%s)",
137 Image(type(y)), SymName(actual(hd)));
138 if( !FitsConstraint(back(y, COLM), fwd(y, COLM), *c) )
139 Error(21, 13, "%s,%s object too wide for available space",
140 FATAL, &fpos(y), EchoLength(back(y, COLM)), EchoLength(fwd(y, COLM)));
141 back(hd, COLM) = back(y, COLM);
142 fwd(hd, COLM) = fwd(y, COLM);
143 assert( FitsConstraint(back(hd, COLM), fwd(hd, COLM), *c),
144 "SizeGalley: BreakObject failed to fit!" );
145 debug2(DSF, D, "MinSize(hd, COLM) = %s,%s",
146 EchoLength(back(hd, COLM)), EchoLength(fwd(hd, COLM)) );
147 }
148
149 /* hyphenate hd if horizontal optimal galley says so */
150 else if( opt_components(hd) != nilobj && opt_hyph(hd) && type(y) == ACAT )
151 { debug0(DOG, D, "SizeGalley calling Hyphenate()");
152 y = Hyphenate(y);
153 }
154
155 /* get the rows of hd to the top level, if required */
156 seen_nojoin(hd) = FALSE;
157 if( rows )
158 { /* OBJECT prev_gap = nilobj; */
159 debug0(DGM, DD, "SizeGalley cleaning up rows of hd:");
160 for( link = hd; NextDown(link) != hd; link = NextDown(link) )
161 { Child(y, NextDown(link));
162 switch( type(y) )
163 {
164 case GAP_OBJ:
165
166 debug2(DGM, DD, " cleaning %s: %s", Image(type(y)), EchoObject(y));
167 /* prev_gap = y; */
168 if( !join(gap(y)) ) seen_nojoin(hd) = TRUE;
169 break;
170
171
172 case VCAT:
173
174 debug1(DGM, DD, " cleaning %s:", Image(type(y)));
175 ifdebug(DGM, DD, DebugObject(y));
176 if( gall_dir(hd) == ROWM )
177 { TransferLinks(Down(y), y, Up(y));
178 DisposeChild(Up(y));
179 link = PrevDown(link);
180 }
181 break;
182
183
184 case ACAT:
185
186 debug2(DGM, DD, " cleaning %s: %s", Image(type(y)), EchoObject(y));
187 if( gall_dir(hd) == COLM )
188 { TransferLinks(Down(y), y, Up(y));
189 DisposeChild(Up(y));
190 link = PrevDown(link);
191 }
192 break;
193
194
195 case SPLIT:
196
197 debug1(DGM, DD, " cleaning %s:", Image(type(y)));
198 ifdebug(DGM, DD, DebugObject(y));
199 assert(Up(y)==LastUp(y), "SizeGalley COL_THR: Up(y)!=LastUp(y)!");
200 Child(z, DownDim(y, ROWM));
201 if( is_indefinite(type(z)) )
202 {
203 debug1(DGT, D, "SizeGalley setting external_ver(%s) to TRUE (a)",
204 EchoObject(z));
205 external_ver(z) = TRUE;
206 }
207 else if( type(z) == VCAT )
208 { OBJECT hor, thor, clink, dlink;
209 Child(hor, DownDim(y, COLM));
210 assert( type(hor) == COL_THR, "SizeGalley: missing COL_THR!" );
211 Parent(thor, UpDim(z, COLM));
212 assert( hor == thor, "SizeGalley/SPLIT: hor != thor!" );
213 clink = DownDim(y, COLM);
214 dlink = UpDim(z, COLM);
215 for( tlink = LastDown(z); tlink != z; tlink = PrevDown(tlink) )
216 { Child(t, tlink);
217 if( type(t) == GAP_OBJ )
218 { Link(NextDown(link), t);
219 }
220 else
221 { New(tmp, SPLIT);
222 back(tmp, COLM) = back(hor, COLM);
223 fwd(tmp, COLM) = fwd(hor, COLM);
224 Link(NextDown(link), tmp);
225 Link(tmp, NextUp(clink));
226 Link(NextDown(dlink), t);
227 Link(tmp, t);
228 }
229 }
230 /* will be done by DisposeChild below DeleteLink(dlink); */
231 assert(Up(y)==LastUp(y), "SizeGalley COL_THR: Up(y) != LastUp(y)!");
232 DisposeChild(Up(y));
233 link = PrevDown(link);
234 }
235 break;
236
237
238 case CLOSURE:
239 case HEAD:
240
241 debug2(DGM, DD, " cleaning %s: %s", Image(type(y)), EchoObject(y));
242 if( gall_dir(hd) == COLM )
243 external_hor(y) = TRUE;
244 else
245 {
246 debug1(DGT, D, "SizeGalley setting external_ver(%s) to TRUE (b)",
247 EchoObject(y));
248 external_ver(y) = TRUE;
249 }
250 break;
251
252
253 default:
254
255 debug2(DGM, DD, " cleaning %s: %s", Image(type(y)), EchoObject(y));
256 break;
257 }
258 }
259 }
260
261 /* determine a scale factor for {} @Scale objects */
262 /* NB AdjustSize cannot be done correctly until after seen_nojoin is set */
263 for( link = Down(extras); link != extras; link = NextDown(link) )
264 { Child(y, link);
265 if( type(y) == SCALE_IND )
266 {
267 /* check that all is in order */
268 CONSTRAINT zc; OBJECT t; FULL_LENGTH b, f;
269 z = actual(y);
270 assert( type(z) == SCALE, "SizeObject: type(z) != SCALE!" );
271 assert( bc(constraint(z)) == 0, "SizeObject: bc(constraint(z)) != 0" );
272 assert( Down(z) != z, "SizeObject SCALE: Down(z) == z!" );
273 Child(t, Down(z));
274
275 /* use @Scale COLM size constraint to determine a suitable scale factor */
276 /* check that @Scale is not in a horizontal galley */
277 if( gall_dir(hd) == COLM )
278 { Error(21, 2, "%s with unspecified scale factor in horizontal galley",
279 FATAL, &fpos(z), KW_SCALE);
280 }
281
282 Constrained(z, &zc, COLM, &why);
283 debug2(DGM, DD, "Constrained(%s, -, COLM) = %s", EchoObject(z),
284 EchoConstraint(&zc));
285 if( !constrained(zc) )
286 { Error(21, 3, "replacing infinite scale factor (unconstrained width) by 1.0",
287 WARN, &fpos(z));
288 bc(constraint(z)) = fc(constraint(z)) = 1 * SF;
289 }
290 else if( size(t, COLM) == 0 )
291 { Error(21, 4, "replacing infinite scale factor (zero width object) by 1.0",
292 WARN, &fpos(z));
293 bc(constraint(z)) = fc(constraint(z)) = 1 * SF;
294 }
295 else if( (float) bfc(zc) / size(t, COLM) > 100.0 )
296 { Error(21, 5, "replacing very large scale factor (over 100) by 1.0",
297 WARN, &fpos(z));
298 bc(constraint(z)) = fc(constraint(z)) = 1 * SF;
299 }
300 else if( (float) bfc(zc) / size(t, COLM) < 0.01 )
301 { if( bfc(zc) == 0 )
302 Error(21, 6, "object deleted (scale factor is zero)",
303 WARN, &fpos(z));
304 else
305 Error(21, 7, "object deleted (scale factor is smaller than 0.01)",
306 WARN, &fpos(z));
307 bc(constraint(z)) = fc(constraint(z)) = 1 * SF;
308 tmp = MakeWord(WORD, STR_EMPTY, &fpos(t));
309 back(tmp, COLM) = fwd(tmp, COLM) = 0;
310 back(tmp, ROWM) = fwd(tmp, ROWM) = 0;
311 word_font(tmp) = word_colour(tmp) = word_language(tmp) = 0;
312 word_underline_colour(tmp) = 0;
313 word_texture(tmp) = 1;
314 word_baselinemark(tmp) = FALSE;
315 word_strut(tmp) = FALSE;
316 word_ligatures(tmp) = TRUE;
317 word_outline(tmp) = FALSE;
318 word_hyph(tmp) = FALSE;
319 ReplaceNode(tmp, t);
320 DisposeObject(t);
321 t = tmp;
322 }
323 else if( bfc(constraint(z)) == -1 )
324 {
325 /* we want to scale down but not up */
326 if( size(t, COLM) > bfc(zc) )
327 bc(constraint(z)) = fc(constraint(z)) = (bfc(zc) * SF)/size(t, COLM);
328 else
329 bc(constraint(z)) = fc(constraint(z)) = 1 * SF;
330 }
331 else bc(constraint(z)) = fc(constraint(z)) = (bfc(zc) * SF)/size(t, COLM);
332
333 /* calculate scaled size and adjust */
334 b = (back(t, COLM) * fc(constraint(z))) / SF;
335 f = (fwd(t, COLM) * fc(constraint(z))) / SF;
336 debug3(DGM, DD, "AdjustSize(%s, %s, %s, COLM)", EchoObject(z),
337 EchoLength(b), EchoLength(f));
338 AdjustSize(z, b, f, COLM);
339
340 /* if already vertically sized (because inside @Rotate) adjust that */
341 if( vert_sized(z) )
342 { b = (back(t, ROWM) * fc(constraint(z))) / SF;
343 f = (fwd(t, ROWM) * fc(constraint(z))) / SF;
344 debug4(DGM, DD, "AdjustSize(%s, %s, %s, %s)", EchoObject(z),
345 EchoLength(b), EchoLength(f), dimen(ROWM));
346 AdjustSize(z, b, f, ROWM);
347 }
348 }
349 }
350 DisposeObject(extras);
351
352 /* size the rows of hd and attach indices where needed */
353 debug0(DGM, DD, " SizeGalley calling MinSize(ROWM):");
354 debug0(DGM, DD, "SizeGalley sizing rows of hd =");
355 ifdebug(DGM, DD, DebugObject(hd));
356 *recs = *inners = *dest_index = nilobj;
357 after_target = FALSE;
358 for( link = Down(hd); link != hd; link = NextDown(link) )
359 { Child(y, link);
360
361 if( type(y) == GAP_OBJ || is_index(type(y)) ) continue;
362 debug0(DGM, DDD, " ROWM sizing:");
363 ifdebug(DGM, DDD, DebugObject(y));
364 New(extras, ACAT);
365 y = MinSize(y, ROWM, &extras);
366 debug3(DSF, DD, "MinSize( %s , ROWM ) = %s,%s", EchoObject(y),
367 EchoLength(back(y, ROWM)), EchoLength(fwd(y, ROWM)) );
368 debug0(DGM, DDD, " ROWM result:");
369 ifdebug(DGM, DDD, DebugObject(y));
370
371 /* now attach indexes in front of y */
372 for( zlink = Down(extras); zlink != extras; zlink = NextDown(zlink) )
373 { Child(z, zlink);
374 blocked(z) = FALSE;
375 /* debug1(DCR, DD, " extra: %s", EchoObject(z)); */
376 debug2(DGM, DD, " extra%s: %s",
377 after_target ? " after_target" : "", EchoObject(z));
378 switch( type(z) )
379 {
380 case RECEPTIVE:
381
382 /* debug2(DCR, DD, " ... uses_ext = %s, trig = %s",
383 bool(uses_extern_target(actual(actual(z)))), bool(trig)); */
384 trigger_externs(z) = uses_extern_target(actual(actual(z))) && trig;
385 non_blocking(z) = nonblock;
386 if( actual(actual(z)) == GalleySym || actual(actual(z)) == ForceGalleySym )
387 *dest_index = z;
388 if( actual(actual(z)) == GalleySym || actual(actual(z)) == ForceGalleySym
389 || actual(actual(z)) == InputSym )
390 after_target = TRUE;
391 break;
392
393
394 case RECURSIVE:
395
396 if( *recs == nilobj ) New(*recs, ACAT);
397 Link(*recs, z);
398 break;
399
400
401 case UNATTACHED:
402
403 if( !after_target ) /* *** new semantics *** */
404 { if( *inners == nilobj ) New(*inners, ACAT);
405 Link(*inners, z);
406 }
407 Child(tmp, Down(z));
408 debug2(DGA, D, "SizeGalley %s%s", actual(tmp) == NULL ? "null" :
409 SymName(actual(tmp)), after_target ? " (after_target)" : "");
410 break;
411
412
413 case SCALE_IND:
414 case EXPAND_IND:
415 case GALL_PREC:
416 case GALL_FOLL:
417 case GALL_FOLL_OR_PREC:
418 case GALL_TARG:
419 case CROSS_PREC:
420 case CROSS_FOLL:
421 case CROSS_FOLL_OR_PREC:
422 case CROSS_TARG:
423 case PAGE_LABEL_IND:
424
425 debug1(DCR, DD, " SizeGalley: %s", EchoObject(z));
426 break;
427
428
429 case COVER_IND:
430
431 /* adjust size of the COVER object, change it to @Scale etc. */
432 { OBJECT cover, prnt, chld; int dirn, thr_type, ok1, ok2, sf,subst, esubst;
433 float sf1, sf2; CONSTRAINT c; FULL_LENGTH b, f;
434 cover = actual(z);
435 if( type(cover) == HCOVER )
436 { dirn = COLM;
437 thr_type = COL_THR;
438 ok1 = VCAT;
439 ok2 = VCAT;
440 subst = HSCALE;
441 esubst = ONE_COL;
442 }
443 else
444 { dirn = ROWM;
445 thr_type = ROW_THR;
446 ok1 = ACAT;
447 ok2 = HCAT;
448 subst = VSCALE;
449 esubst = ONE_ROW;
450 }
451 Parent(prnt, UpDim(cover, dirn));
452 while( type(prnt) == SPLIT || type(prnt) == thr_type )
453 Parent(prnt, UpDim(prnt, dirn));
454 Child(chld, Down(cover));
455 if( type(prnt) != ok1 && type(prnt) != ok2 )
456 {
457 Error(21, 8, "%s replaced by %s (mark not shared)",
458 WARN, &fpos(cover), Image(type(cover)), Image(subst));
459 debug2(DGM, DDD, " cover = %s %s", Image(type(cover)),
460 EchoObject(cover));
461 debug1(DGM, DDD, " prnt = %s:", Image(type(prnt)));
462 ifdebug(DGM, DDD, DebugObject(prnt));
463 type(cover) = subst;
464 }
465 else if( back(chld, dirn) == 0 && fwd(chld, dirn) == 0 )
466 {
467 /* empty object, this is treated as a no-op */
468 type(cover) = esubst;
469 }
470 else if( back(chld, dirn) == 0 || fwd(chld, dirn) == 0 )
471 { Error(21, 9, "%s replaced by %s (infinite scale factor)",
472 WARN, &fpos(cover), Image(type(cover)), Image(subst));
473 type(cover) = subst;
474 }
475 else if( size(prnt, dirn) == 0 )
476 { Error(21, 10, "%s replaced by %s (zero scale factor)",
477 WARN, &fpos(cover), Image(type(cover)), Image(subst));
478 type(cover) = subst;
479 }
480 else /* sensible scale factor exists */
481 {
482 /* work out proposed scale factor and sizes for cover */
483 sf1 = (float) back(prnt, dirn) / back(chld, dirn);
484 sf2 = (float) fwd(prnt, dirn) / fwd(chld, dirn);
485 sf = find_max(sf1, sf2) * SF;
486 b = (back(chld, dirn) * sf) / SF;
487 f = (fwd(chld, dirn) * sf) / SF;
488
489 /* check whether new object fits */
490 Constrained(cover, &c, dirn, &why);
491 if( FitsConstraint(b, f, c) )
492 {
493 /* it fits, so make cover a SCALE object with this size */
494 type(cover) = SCALE;
495 if( dirn == COLM )
496 { bc(constraint(cover)) = sf;
497 fc(constraint(cover)) = SF;
498 }
499 else
500 { bc(constraint(cover)) = SF;
501 fc(constraint(cover)) = sf;
502 }
503 AdjustSize(cover, b, f, dirn);
504 }
505 else
506 { Error(21, 11, "%s replaced by %s (insufficient space)",
507 WARN, &fpos(cover), Image(type(cover)), Image(subst));
508 type(cover) = subst;
509 }
510 }
511 }
512 break;
513
514
515 default:
516
517 assert1(FALSE, "SizeGalley:", Image(type(z)));
518 break;
519
520 }
521 }
522 TransferLinks(Down(extras), extras, link);
523 assert( Down(extras) == extras && Up(extras) == extras, "SizeG: extras!");
524 Dispose(extras);
525 }
526
527 /* insinuate cross references */
528 if( crs != nilobj )
529 {
530 debug1(DCR, DD, "SizeGalley insinuating %s", EchoObject(crs));
531 TransferLinks(Down(crs), crs, Down(hd));
532 DisposeObject(crs);
533 }
534
535 /* check that *dest_index was found if it was required, and exit */
536 if( target != nilobj && *dest_index == nilobj )
537 Error(21, 12, "unexpected absence of %s from the body of %s",
538 FATAL, &fpos(hd), SymName(target), SymName(actual(hd)));
539 debug3(DGM, D, "SizeGalley returning %s,%s %s; hd =",
540 EchoLength(back(hd, COLM)), EchoLength(fwd(hd, COLM)),
541 EchoConstraint(&constraint(hd)));
542 ifdebug(DGM, D, DebugGalley(hd, nilobj, 4));
543 sized(hd) = TRUE;
544
545 } /* end SizeGalley */
546