<> <> <<>> <> <<>> DIRECTORY BoxTree, InternalExpr, ImagerFont; BoxTreeImpl: CEDAR PROGRAM ~ BEGIN <> <<>> EXPR: TYPE ~ InternalExpr.EXPR; BoxTreeRep: TYPE ~ RECORD [ boundBox: ImagerBox.Box _ [0,0,0,0], -- size of bounding box offset: Vector.VEC _[0,0], -- offset from origin of parent box subBoxes: LIST OF BoxTree.BOXTREE _ NIL, -- list of boxes bound by this box parentBox: BoxTree.BOXTREE _ NIL, -- parent bounding box style: BoxTree.STYLE, value: EXPR, -- value of this box expression: EXPR -- pointer to expression bound by this box ]; <> Format: PUBLIC PROC[box: BoxTree] ~ { <<>> <> subExprBoxes: LIST OF BOX; myBox, tempBox: BOX; WITH box.value SELECT FROM atm: atomic => { AtomicFormat[atm, size] }; fn: function => { box.subBoxes _ GetFormat[fn]; -- get format rule -- recursively format subexpressions FOR l: LIST OF BoxTreeRep.subBoxes _ box.subBoxes, l.rest DO Format[l.first] ENDLOOP; -- size boxes box.boundBox _ BoundingBox[box.subBoxes]; -- compose layout LayOutBoxes[box.subBoxes]; }; ENDCASE => ERROR; <<>> }; GetFormat: PROC [expr: function EXPR] RETURNS [LIST OF BoxTree.BOXTREE] ~ { <> <> boxlist : BOX.subBoxes; xi : INT _ 1; boxlist _ MakeBox[expr.name, [0,0]]; FOR l: LIST OF EXPR _ expr.subExprs, l.next DO { xi _ xi + 1; boxlist _ CONS[MakeBox[l.first, [xi,0]], boxlist] }; ENDLOOP; }; MakeBox: PROC [exp: EXPR, offset: Vector.VEC RETURNS [BoxTree.BOXTREE] ~ { NEW[BoxTreeRep _ [offset: offset, value: exp, expression: exp]] }; BoundingBox: PROC [boxes: LIST OF BoxTree.BOXTREE] RETURNS [ImagerBox.Box] ~ { <> biggestBox: ImagerBox.Box _ [0, 0, 0, 0]; FOR l: LIST OF BoxTree.BOXTREE _ boxes, l.next DO biggestBox _ ImagerBox.BoundingBox[BiggestBox, l.first] ENDLOOP; RETURN [biggestBox] }; LayOutBoxes: PROC [boxes: LIST OF BoxTree.BOXTREE] ~ { -- compose layout of list of boxes using the relative offsets }; Paint: PUBLIC PROC [boxTree: BOXTREE, context: Imager.Context, selections: LIST OF Selection]; <> END.