<> <> <> DIRECTORY Basics USING [bitsPerByte, bitsPerWord, HighHalf, LongMult, LongNumber, LowHalf], IO USING [EndOfStream, GetBlock, GetChar, GetIndex, PutBlock, PutChar, RopeFromROS, ROS, SetIndex, STREAM], IPMaster, Real USING [NumberType, RealToPair, RoundLI], RefText USING [ObtainScratch, ReleaseScratch], Rope USING [Fetch, Index, Length, ROPE, Substr], PrincOps USING [BBTableSpace, BitBltTablePtr, zBNDCK, zLINI], PrincOpsUtils USING [AlignedBBTable, BITBLT, ZERO], ShortRational USING [FromReal, Rational], SymTab USING [Create, Fetch, Ref, Store]; IPMasterImpl: CEDAR PROGRAM IMPORTS Basics, IO, PrincOpsUtils, Real, RefText, Rope, ShortRational, SymTab EXPORTS IPMaster ~ BEGIN OPEN IPMaster; NonNeg: PROC[x: INT] RETURNS[INT] ~ TRUSTED MACHINE CODE { PrincOps.zLINI; PrincOps.zBNDCK; }; <> ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Error: PUBLIC ERROR[code: ErrorCode, explanation: ROPE] ~ CODE; evFromOp: REF EvFromOpArray ~ NEW[EvFromOpArray _ [nil: nil, get: get, makeveclu: makeveclu, makevec: makevec, shape: shape, openvec: openvec, getprop: getprop, getp: getp, mergeprop: mergeprop, frame: frame, fget: fget, fset: fset, poolop: poolop, pool: pool, pget: pget, pset: pset, env: env, makepool: makepool, nopool: nopool, makeco: makeco, makesimpleco: makesimpleco, do: do, dosave: dosave, dosaveall: dosaveall, dobody: dobody, dosavebody: dosavebody, dosaveallbody: dosaveallbody, dosavesimplebody: dosavesimplebody, makecompiledimage: makecompiledimage, pop: pop, copy: copy, dup: dup, roll: roll, exch: exch, mark: mark, unmark: unmark, unmark0: unmark0, count: count, nop: nop, error: error, if: if, ifelse: ifelse, ifcopy: ifcopy, loop: loop, eq: eq, eqname: eqname, gt: gt, ge: ge, and: and, or: or, not: not, type: type, add: add, sub: sub, neg: neg, abs: abs, floor: floor, ceiling: ceiling, trunc: trunc, round: round, mul: mul, div: div, mod: mod, rem: rem, max: max, min: min, sqrt: sqrt, exp: exp, log: log, sin: sin, cos: cos, atan: atan, iget: iget, iset: iset, dround: dround, maket: maket, opent: opent, translate: translate, rotate: rotate, scale: scale, scale2: scale2, concat: concat, invert: invert, transform: transform, transformvec: transformvec, roundxy: roundxy, roundxyvec: roundxyvec, concatt: concatt, move: move, trans: trans, show: show, showandxrel: showandxrel, setxy: setxy, setxyrel: setxyrel, setxrel: setxrel, setyrel: setyrel, getcp: getcp, getcprounded: getcprounded, makepixelarray: makepixelarray, extractpixelarray: extractpixelarray, joinpixelarrays: joinpixelarrays, finddecompressor: finddecompressor, makegray: makegray, setgray: setgray, findcolor: findcolor, findcoloroperator: findcoloroperator, findcolormodeloperator: findcolormodeloperator, makesampledcolor: makesampledcolor, makesampledblack: makesampledblack, moveto: moveto, lineto: lineto, linetox: linetox, linetoy: linetoy, curveto: curveto, conicto: conicto, arcto: arcto, makeoutline: makeoutline, maskfill: maskfill, maskfillparity: maskfillparity, maskstroke: maskstroke, maskstrokeclosed: maskstrokeclosed, maskvector: maskvector, maskrectangle: maskrectangle, startunderline: startunderline, maskunderline: maskunderline, masktrapezoidx: masktrapezoidx, masktrapezoidy: masktrapezoidy, maskpixel: maskpixel, clipoutline: clipoutline, excludeoutline: excludeoutline, cliprectangle: cliprectangle, excluderectangle: excluderectangle, findfont: findfont, findfontvec: findfontvec, modifyfont: modifyfont, setfont: setfont, correctmask: correctmask, correctspace: correctspace, space: space, setcorrectmeasure: setcorrectmeasure, setcorrecttolerance: setcorrecttolerance, correct: correct, beginBody: beginBody, endBody: endBody, beginBlock: beginBlock, endBlock: endBlock, pageInstructions: pageInstructions, noPages: noPages, metricMaster: metricMaster, environmentMaster: environmentMaster ]]; opFromEv: REF OpFromEvArray ~ InvertEvFromOp[evFromOp]; InvertEvFromOp: PROC[evFromOp: REF EvFromOpArray] RETURNS[REF OpFromEvArray] ~ { opFromEv: REF OpFromEvArray ~ NEW[OpFromEvArray _ ALL[nil]]; FOR op: Op IN Op DO opFromEv[evFromOp[op]] _ op ENDLOOP; RETURN[opFromEv]; }; GetEvFromOp: PUBLIC PROC RETURNS[REF READONLY EvFromOpArray] ~ { RETURN[evFromOp]; }; GetOpFromEv: PUBLIC PROC RETURNS[REF READONLY OpFromEvArray] ~ { RETURN[opFromEv]; }; EncodingValueFromOp: PUBLIC PROC[op: Op] RETURNS[EncodingValue] ~ { RETURN[evFromOp[op]]; }; OpFromEncodingValue: PUBLIC PROC[ev: EncodingValue] RETURNS[Op] ~ { RETURN[opFromEv[ev]]; }; NonDefaultingRope: TYPE ~ ROPE _; RopeFromOpArray: TYPE ~ ARRAY Op OF NonDefaultingRope; ropeFromOp: REF RopeFromOpArray ~ NEW[RopeFromOpArray _ [nil: NIL, get: "GET", makeveclu: "MAKEVECLU", makevec: "MAKEVEC", shape: "SHAPE", openvec: "OPENVEC", getprop: "GETPROP", getp: "GETP", mergeprop: "MERGEPROP", frame: "FRAME", fget: "FGET", fset: "FSET", poolop: "POOLOP", pool: "POOL", pget: "PGET", pset: "PSET", env: "ENV", makepool: "MAKEPOOL", nopool: "NOPOOL", makeco: "MAKECO", makesimpleco: "MAKESIMPLECO", do: "DO", dosave: "DOSAVE", dosaveall: "DOSAVEALL", dobody: "DOBODY", dosavebody: "DOSAVEBODY", dosaveallbody: "DOSAVEALLBODY", dosavesimplebody: "DOSAVESIMPLEBODY", makecompiledimage: "MAKECOMPILEDIMAGE", pop: "POP", copy: "COPY", dup: "DUP", roll: "ROLL", exch: "EXCH", mark: "MARK", unmark: "UNMARK", unmark0: "UNMARK0", count: "COUNT", nop: "NOP", error: "ERROR", if: "IF", ifelse: "IFELSE", ifcopy: "IFCOPY", loop: "LOOP", eq: "EQ", eqname: "EQNAME", gt: "GT", ge: "GE", and: "AND", or: "OR", not: "NOT", type: "TYPE", add: "ADD", sub: "SUB", neg: "NEG", abs: "ABS", floor: "FLOOR", ceiling: "CEILING", trunc: "TRUNC", round: "ROUND", mul: "MUL", div: "DIV", mod: "MOD", rem: "REM", max: "MAX", min: "MIN", sqrt: "SQRT", exp: "EXP", log: "LOG", sin: "SIN", cos: "COS", atan: "ATAN", iget: "IGET", iset: "ISET", dround: "DROUND", maket: "MAKET", opent: "OPENT", translate: "TRANSLATE", rotate: "ROTATE", scale: "SCALE", scale2: "SCALE2", concat: "CONCAT", invert: "INVERT", transform: "TRANSFORM", transformvec: "TRANSFORMVEC", roundxy: "ROUNDXY", roundxyvec: "ROUNDXYVEC", concatt: "CONCATT", move: "MOVE", trans: "TRANS", show: "SHOW", showandxrel: "SHOWANDXREL", setxy: "SETXY", setxyrel: "SETXYREL", setxrel: "SETXREL", setyrel: "SETYREL", getcp: "GETCP", getcprounded: "GETCPROUNDED", makepixelarray: "MAKEPIXELARRAY", extractpixelarray: "EXTRACTPIXELARRAY", joinpixelarrays: "JOINPIXELARRAYS", finddecompressor: "FINDDECOMPRESSOR", makegray: "MAKEGRAY", setgray: "SETGRAY", findcolor: "FINDCOLOR", findcoloroperator: "FINDCOLOROPERATOR", findcolormodeloperator: "FINDCOLORMODELOPERATOR", makesampledcolor: "MAKESAMPLEDCOLOR", makesampledblack: "MAKESAMPLEDBLACK", moveto: "MOVETO", lineto: "LINETO", linetox: "LINETOX", linetoy: "LINETOY", curveto: "CURVETO", conicto: "CONICTO", arcto: "ARCTO", makeoutline: "MAKEOUTLINE", maskfill: "MASKFILL", maskfillparity: "MASKFILLPARITY", maskstroke: "MASKSTROKE", maskstrokeclosed: "MASKSTROKECLOSED", maskvector: "MASKVECTOR", maskrectangle: "MASKRECTANGLE", startunderline: "STARTUNDERLINE", maskunderline: "MASKUNDERLINE", masktrapezoidx: "MASKTRAPEZOIDX", masktrapezoidy: "MASKTRAPEZOIDY", maskpixel: "MASKPIXEL", clipoutline: "CLIPOUTLINE", excludeoutline: "EXCLUDEOUTLINE", cliprectangle: "CLIPRECTANGLE", excluderectangle: "EXCLUDERECTANGLE", findfont: "FINDFONT", findfontvec: "FINDFONTVEC", modifyfont: "MODIFYFONT", setfont: "SETFONT", correctmask: "CORRECTMASK", correctspace: "CORRECTSPACE", space: "SPACE", setcorrectmeasure: "SETCORRECTMEASURE", setcorrecttolerance: "SETCORRECTTOLERANCE", correct: "CORRECT", beginBody: "{", endBody: "}", beginBlock: "BEGIN", endBlock: "END", pageInstructions: "PAGEINSTRUCTIONS", noPages: "NOPAGES", metricMaster: "METRICMASTER", environmentMaster: "ENVIRONMENTMASTER" ]]; opFromRope: SymTab.Ref ~ InvertRopeFromOp[ropeFromOp]; OpVal: TYPE ~ REF Op; InvertRopeFromOp: PROC[ropeFromOp: REF RopeFromOpArray] RETURNS[opFromRope: SymTab.Ref] ~ { opFromRope _ SymTab.Create[mod: ORD[Op.LAST], case: FALSE]; FOR op: Op IN Op DO key: ROPE ~ ropeFromOp[op]; val: OpVal ~ NEW[Op _ op]; IF SymTab.Store[x: opFromRope, key: key, val: val] THEN NULL ELSE ERROR Error[bug, "duplicate name in ropeFromOp"]; ENDLOOP; }; RopeFromOp: PUBLIC PROC[op: Op] RETURNS[ROPE] ~ { RETURN[ropeFromOp[op]]; }; OpFromRope: PUBLIC PROC[rope: ROPE] RETURNS[Op] ~ { found: BOOL; val: REF; [found, val] _ SymTab.Fetch[x: opFromRope, key: rope]; IF found THEN WITH val SELECT FROM val: OpVal => RETURN[val^]; ENDCASE => ERROR Error[bug, "illegal value in opFromRope"]; RETURN[nil]; }; RopeFromImagerVarArray: TYPE ~ ARRAY ImagerVariable OF NonDefaultingRope; ropeFromImagerVar: REF RopeFromImagerVarArray ~ NEW[RopeFromImagerVarArray _ [ DCScpx: "DCScpx", DCScpy: "DCScpy", correctMX: "correctMX", correctMY: "correctMY", T: "T", priorityImportant: "priorityImportant", mediumXSize: "mediumXSize", mediumYSize: "mediumYSize", fieldXMin: "fieldXMin", fieldYMin: "fieldYMin", fieldXMax: "fieldXMax", fieldYMax: "fieldYMax", showVec: "showVec", color: "color", noImage: "noImage", strokeWidth: "strokeWidth", strokeStyle: "strokeStyle", underlineStart: "underlineStart", amplifySpace: "amplifySpace", correctPass: "correctPass", correctShrink: "correctShrink", correctTX: "correctTX", correctTY: "correctTY", strokeDashes: "strokeDashes" ]]; RopeFromImagerVariable: PUBLIC PROC[var: ImagerVariable] RETURNS[ROPE] ~ { RETURN[ropeFromImagerVar[var]]; }; MapName: PUBLIC PROC[rope: ROPE, start: INT _ 0, len: INT _ INT.LAST, action: PROC[base: ROPE, start, len: INT] RETURNS[quit: BOOL _ FALSE]] RETURNS[BOOL] ~ { size: INT ~ Rope.Length[rope]; rem: INT ~ NonNeg[size-NonNeg[start]]; stop: INT ~ start+MIN[len, rem]; pos: INT _ start; WHILE pos SELECT char FROM IN['0..'9] => state _ major; ENDCASE => RETURN[FALSE]; major => SELECT char FROM IN['0..'9] => NULL; '. => state _ dot; ENDCASE => RETURN[FALSE]; dot => SELECT char FROM IN['0..'9] => state _ minor; ENDCASE => RETURN[FALSE]; minor => SELECT char FROM IN['0..'9] => NULL; ENDCASE => RETURN[FALSE]; ENDCASE => ERROR; ENDLOOP; RETURN[state=minor]; }; VersionFromRope: PUBLIC PROC[rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS[version: Version _ [0, 0]] ~ { InvalidVersion: PROC ~ { ERROR Error[invalidVersion, "invalid version number"] }; size: INT ~ Rope.Length[rope]; rem: INT ~ NonNeg[size-NonNeg[start]]; length: INT ~ MIN[len, rem]; state: {begin, major, dot, minor} _ begin; FOR i: INT IN[start..start+length) DO char: CHAR ~ Rope.Fetch[rope, i]; SELECT state FROM begin => SELECT char FROM IN['0..'9] => { version.major _ (char-'0); state _ major }; ENDCASE => InvalidVersion[]; major => SELECT char FROM IN['0..'9] => version.major _ version.major*10+(char-'0); '. => state _ dot; ENDCASE => InvalidVersion[]; dot => SELECT char FROM IN['0..'9] => { version.minor _ (char-'0); state _ minor }; ENDCASE => InvalidVersion[]; minor => SELECT char FROM IN['0..'9] => version.minor _ version.minor*10+(char-'0); ENDCASE => InvalidVersion[]; ENDCASE => ERROR; ENDLOOP; IF state#minor THEN InvalidVersion[]; }; ValidIdentifier: PUBLIC PROC[rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS[BOOL] ~ { size: INT ~ Rope.Length[rope]; rem: INT ~ NonNeg[size-NonNeg[start]]; length: INT ~ MIN[len, rem]; state: {first, rest} _ first; FOR i: INT IN[start..start+length) DO char: CHAR ~ Rope.Fetch[rope, i]; SELECT state FROM first => SELECT char FROM IN['a..'z], IN['A..'Z] => state _ rest; ENDCASE => RETURN[FALSE]; rest => SELECT char FROM IN['a..'z], IN['A..'Z], IN['0..'9], '- => NULL; ENDCASE => RETURN[FALSE]; ENDCASE => ERROR; ENDLOOP; RETURN[state=rest]; }; ValidName: PUBLIC PROC[rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS[BOOL] ~ { action: PROC[base: ROPE, start, len: INT] RETURNS[quit: BOOL] ~ { RETURN[NOT ValidIdentifier[base, start, len]]; }; RETURN[NOT MapName[rope, start, len, action]]; }; ValidString: PUBLIC PROC[rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS[BOOL] ~ { size: INT ~ Rope.Length[rope]; rem: INT ~ NonNeg[size-NonNeg[start]]; length: INT ~ MIN[len, rem]; state: {run, escape, escape2, extended, extended2} _ run; FOR i: INT IN[start..start+length) DO char: CHAR ~ Rope.Fetch[rope, i]; SELECT state FROM run => IF char='\377 THEN state _ escape; escape => IF char='\377 THEN state _ escape2 ELSE state _ run; escape2 => IF char='\000 THEN state _ extended ELSE RETURN[FALSE]; extended => IF char='\377 THEN state _ escape ELSE state _ extended2; extended2 => IF char='\377 THEN RETURN[FALSE] ELSE state _ extended; ENDCASE => ERROR; ENDLOOP; RETURN[state=run OR state=extended]; }; GetHeader: PUBLIC PROC[stream: STREAM, prefix: ROPE _ NIL, maxLength: INT _ 100] RETURNS[ROPE] ~ { InvalidHeader: PROC ~ { ERROR Error[invalidHeader, "invalid header"] }; prefixLength: INT ~ Rope.Length[prefix]; ros: IO.STREAM ~ IO.ROS[]; FOR i: INT IN[0..MAX[prefixLength, maxLength]) DO char: CHAR ~ IO.GetChar[stream]; IF i> <> <> IF ValidString[rope, start, len] THEN PutRope[stream, sequenceString, rope, start, len] ELSE ERROR Error[invalidString, "invalid string"]; }; PutComment: PUBLIC PROC[stream: STREAM, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] ~ { <> PutRope[stream, sequenceComment, rope, start, len]; }; PutInsertFile: PUBLIC PROC[stream: STREAM, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] ~ { <> PutRope[stream, sequenceInsertFile, rope, start, len]; }; <<>> PutName: PUBLIC PROC[stream: STREAM, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] ~ { <> <; "foo" produces < foo 1 MAKEVEC >.>> <> <> depth: INT _ 0; action: PROC[base: ROPE, start, len: INT] RETURNS[BOOL _ FALSE] ~ { PutIdentifier[stream, base, start, len]; depth _ depth+1; }; [] _ MapName[rope, start, len, action]; PutInt[stream, depth]; PutOp[stream, makevec]; }; PutBits: PUBLIC PROC[stream: STREAM, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT] ~ { scanBytes: NAT ~ 4*((fSize+31)/32); -- bytes per output scan line block: REF TEXT ~ NEW[TEXT[scanBytes]]; -- scan line buffer length: INT ~ LONG[4]+LONG[scanBytes]*LONG[sSize]; -- length of token data bbspace: PrincOps.BBTableSpace; bb: PrincOps.BitBltTablePtr; PutDescriptor[stream, sequencePackedPixelVector, length]; PutSigned[stream, 2, 1]; -- BitsPerSample PutSigned[stream, 2, fSize]; -- ScanLength TRUSTED { bb _ PrincOpsUtils.AlignedBBTable[@bbspace]; bb^ _ [dst: [word: NIL, bit: 0], dstBpl: 0, src: [word: NIL, bit: 0], srcDesc: [srcBpl[0]], width: 0, height: 0, flags: [disjoint: TRUE, gray: FALSE]]; bb.dst.word _ LOOPHOLE[block, LONG POINTER]+SIZE[TEXT[0]]; bb.dstBpl _ scanBytes*Basics.bitsPerByte; bb.src.word _ base+Basics.LongMult[sMin, wordsPerLine]+fMin/Basics.bitsPerWord; bb.src.bit _ fMin MOD Basics.bitsPerWord; bb.srcDesc.srcBpl _ wordsPerLine*Basics.bitsPerWord; bb.width _ fSize; bb.height _ 1; PrincOpsUtils.ZERO[where: bb.dst.word, nwords: scanBytes/2]; }; THROUGH [0..sSize) DO TRUSTED { PrincOpsUtils.BITBLT[bb] }; IO.PutBlock[self: stream, block: block, startIndex: 0, count: scanBytes]; TRUSTED { bb.src.word _ bb.src.word+wordsPerLine }; ENDLOOP; }; END.