DIRECTORY ImagerFont USING [Extents], Vector USING [VEC], MathBox; MathBoxImpl: CEDAR PROGRAM EXPORTS MathBox ~ BEGIN VEC: TYPE ~ Vector.VEC; BOX: TYPE ~ MathBox.BOX; BoxType: TYPE ~ MathBox.BoxType; BoxRep: PUBLIC TYPE ~ RECORD [ tag: ATOM, -- named identifier aliases: LIST OF ATOM, -- list of aliases for name type: BoxType, -- units type extents: ImagerFont.Extents _ [0.0, 0.0, 0.0, 0.0], -- bounding box extents offset: VEC _ [0.0, 0.0] -- offset vector to box origin ]; Scale: PUBLIC PROC[b: BOX, v: VEC] RETURNS[BOX] ~ { RETURN[NEW[BoxRep _ [tag: b.tag, aliases: b.aliases, type: b.type, extents: [leftExtent: v.x * b.extents.leftExtent, rightExtent: v.x * b.extents.rightExtent, descent: v.y * b.extents.descent, ascent: v.y * b.extents.ascent], offset: [v.x * b.offset.x, v.y * b.offset.y]]]]; }; Inside: PUBLIC PROC[b: BOX, x, y: REAL] RETURNS[BOOL] ~ { RETURN[(x >= b.offset.x - b.extents.leftExtent) AND (x <= b.offset.x + b.extents.rightExtent) AND (y >= b.offset.y - b.extents.descent) AND (y <= b.offset.y + b.extents.ascent)]; }; AlignHorizontal: PUBLIC PROC[box1: ImagerFont.Extents, offset1: REAL, box2: BOX, offset2: REAL] RETURNS[REAL] ~ { RETURN[box2.offset.x + (offset2 * Width[box2]) - box2.extents.leftExtent + box1.leftExtent - (offset1 * (box1.leftExtent + box1.rightExtent))]; }; AlignVertical: PUBLIC PROC[box1: ImagerFont.Extents, offset1: REAL, box2: BOX, offset2: REAL] RETURNS[REAL] ~ { RETURN[box2.offset.y + (offset2 * Height[box2]) - box2.extents.descent + box1.descent - (offset1 * (box1.descent + box1.ascent))]; }; RelToAbsBox: PUBLIC PROC[relBox, parentBox: BOX] RETURNS[BOX] ~ { IF (relBox.type # relative) OR (parentBox.type # absolute) THEN ERROR wrongBoxType; RETURN[MakeBox[tag: relBox.tag, aliases: relBox.aliases, type: absolute, extents: [leftExtent: Width[parentBox] * relBox.extents.leftExtent, rightExtent: Width[parentBox] * relBox.extents.rightExtent, ascent: Height[parentBox] * relBox.extents.ascent, descent: Height[parentBox] * relBox.extents.descent], offset: [parentBox.offset.x + (Width[parentBox] * relBox.offset.x), parentBox.offset.y + (Height[parentBox] * relBox.offset.y)]]]; }; MakeBox: PUBLIC PROC[tag: ATOM, aliases: LIST OF ATOM, type: BoxType, extents: ImagerFont.Extents _ [0.0, 0.0, 0.0, 0.0], offset: VEC _ [0.0, 0.0]] RETURNS[BOX] ~ { RETURN[NEW[BoxRep _ [tag: tag, aliases: aliases, type: type, extents: extents, offset: offset]]]; }; ChangeOffset: PUBLIC PROC[box: BOX, newOffset: VEC] RETURNS[BOX] ~ { RETURN[NEW[BoxRep _ [tag: box.tag, aliases: box.aliases, type: box.type, extents: box.extents, offset: newOffset]]]; }; ChangeExtents: PUBLIC PROC[box: BOX, newExtents: ImagerFont.Extents] RETURNS[BOX] ~ { RETURN[NEW[BoxRep _ [tag: box.tag, aliases: box.aliases, type: box.type, extents: newExtents, offset: box.offset]]]; }; Width: PUBLIC PROC[b: BOX] RETURNS[REAL] ~ { RETURN[b.extents.leftExtent + b.extents.rightExtent]; }; Height: PUBLIC PROC[b: BOX] RETURNS[REAL] ~ { RETURN[b.extents.ascent + b.extents.descent]; }; Tag: PUBLIC PROC[b: BOX] RETURNS[ATOM] ~ { RETURN[b.tag]; }; Aliases: PUBLIC PROC[b: BOX] RETURNS[LIST OF ATOM] ~ { RETURN[b.aliases]; }; Extents: PUBLIC PROC[b: BOX] RETURNS[ImagerFont.Extents] ~ { RETURN[b.extents]; }; Offset: PUBLIC PROC[b: BOX] RETURNS[VEC] ~ { RETURN[b.offset]; }; Origin: PUBLIC PROC[b: BOX] RETURNS[VEC] ~ { RETURN[[b.extents.leftExtent, b.extents.descent]]; }; Type: PUBLIC PROC[b: BOX] RETURNS[BoxType] ~ { RETURN[b.type]; }; GetBox: PUBLIC PROC[tag: ATOM, boxes: LIST OF BOX, useAliases: BOOL _ TRUE] RETURNS[BOX] ~ { FOR l: LIST OF BOX _ boxes, l.rest UNTIL l = NIL DO IF l.first.tag = tag THEN RETURN[l.first]; ENDLOOP; FOR l: LIST OF BOX _ boxes, l.rest UNTIL l = NIL DO FOR aliases: LIST OF ATOM _ l.first.aliases, aliases.rest UNTIL aliases = NIL DO IF aliases.first = tag THEN RETURN[l.first]; ENDLOOP; ENDLOOP; ERROR boxNotFound; }; MapBoxList: PUBLIC PROC[boxes: LIST OF BOX, proc: PROC[b: BOX] RETURNS[BOX]] RETURNS[LIST OF BOX] ~ { newList: LIST OF BOX _ NIL; FOR l: LIST OF BOX _ boxes, l.rest UNTIL l = NIL DO newList _ CONS[proc[l.first], newList]; ENDLOOP; RETURN[newList]; }; boxNotFound: PUBLIC ERROR = CODE; wrongBoxType: PUBLIC ERROR = CODE; END. MathBoxImpl.mesa Carl Waldspurger, August 11, 1986 1:42:58 pm PDT Type Abbreviations for Imported Types Private Type Rep Operations on BOX effects: Returns the BOX which is b scaled by v. BOX extents and offset are scaled. effects: Returns TRUE if the point [x, y] is enclosed by b. Otherwise returns FALSE. effects: Horizontally aligns box1 with box2 such that the points (offset1 * WIDTH[box1]) and (offset2 * WIDTH[box2]) are aligned. Offsets are measured from the left edge of a box. Returns the x offset for box1. drawing a vector diagram is the best way to understand this effects: Vertically aligns box1 with box2 s.t. the points (offset1 * HEIGHT[box1]) and (offset2 * HEIGHT[box2]) are aligned. Offsets are measured from the bottom edge of a box. Returns the y offset for box1. drawing a vector diagram is the best way to understand this requires: relBox is a relative BOX, parentBox is an absolute BOX effects: Converts relBox (relative units) into an absBox (absolute units) by positioning it relative to parentBox Constructors effects: Constructs and returns a new BOX with the specified parameters. effects: Returns a new BOX which is box with offset newOffset. effects: Returns a new BOX which is box with Extents newExtents. Selectors effects: Returns the width of b. effects: Returns the height of b. effects: Returns the tag associated with b. effects: Returns the aliases assocaited with b effects: Returns the extents of b. effects: Returns the offset vector of b. effects: Returns the origin vector [b.Extents.leftExtent, b.Extents.descent] effects: Returns relative if b is in relative units; Else returns absolute. Box List Operations effects: Returns the BOX in boxes associated with tag. If useAliases = TRUE, then checks for BOX in boxes with alias tag. SIGNALS boxNotFound if no association exists. not a normal tag, so check aliases not found, so signal error effects: Constructs a new LIST OF BOX by applying proc to each BOX in boxes. Element positions in list are not preserved. Signals & Errors Êk˜Jšœ™Jšœ0™0J˜šÏk ˜ Jšœ œ ˜Jšœœœ˜Jšœ˜—J˜J˜šÏn œœ˜Jšœ ˜J˜Jš˜J˜Jšž%™%™Jšœœ œ˜J˜Jšœœ œ˜Jšœ œ˜ J˜—J˜Jšž™˜šœ œ˜codešœ˜KšœœÏc˜Kšœ œœœŸ˜2KšœŸ ˜Kšœ5Ÿ˜LKšœœŸ˜8K˜——J˜—J˜K™Kšž™˜šžœœœœœœœ˜3Kšœ1™1Kšœ,™,Kšœœˆ˜’K˜—K˜šžœœœœœœœ˜9Kšœ<™