IPMaster.mesa
Copyright © 1984 Xerox Corporation. All rights reserved.
Doug Wyatt, November 13, 1984 3:16:59 pm PST
Operations for reading and writing Interpress masters.
DIRECTORY
IO USING [STREAM],
IPXerox USING [EncodingValue, SequenceType],
Rope USING [ROPE];
IPMaster: CEDAR DEFINITIONS
~ BEGIN
BYTE: TYPE ~ [0..377B];
CARD: TYPE ~ LONG CARDINAL;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Op: TYPE ~ {nil,
-- Base language primitives
get, makeveclu, makevec, shape, openvec, getprop, getp, mergeprop, -- 2.4.3
frame, fget, fset, poolop, pool, pget, pset, env, -- 2.4.4
makepool, nopool, makeco, makesimpleco, do, dosave, dosaveall, -- 2.4.5
dobody, dosavebody, dosaveallbody, dosavesimplebody, makecompiledimage,
pop, copy, dup, roll, exch, mark, unmark, unmark0, count, nop, error, -- 2.4.6
if, ifelse, ifcopy, loop, -- 2.4.7
eq, eqname, gt, ge, and, or, not, type, -- 2.4.8
add, sub, neg, abs, floor, ceiling, trunc, round, mul, div, mod, rem, -- 2.4.9
max, min, sqrt, exp, log, sin, cos, atan,
-- Imaging primitives
iget, iset, -- 4.2
dround, -- 4.3.5
maket, opent, translate, rotate, scale, scale2, concat, invert, -- 4.4.3
transform, transformvec, roundxy, roundxyvec, -- 4.4.4
concatt, move, trans, -- 4.4.5
show, showandxrel, -- 4.4.6
setxy, setxyrel, setxrel, setyrel, getcp, getcprounded, -- 4.5
makepixelarray, extractpixelarray, joinpixelarrays, -- 4.6
finddecompressor, -- 4.6.1
makegray, findcolor, findcoloroperator, findcolormodeloperator, -- 4.7.1
makesampledcolor, makesampledblack, -- 4.7.2
setgray, -- 4.7.3
moveto, lineto, linetox, linetoy, curveto, conicto, arcto, makeoutline, -- 4.8.1
maskfill, maskfillparity, maskstroke, maskstrokeclosed, maskvector, maskrectangle, -- 4.8.2
startunderline, maskunderline, masktrapezoidx, masktrapezoidy,
maskpixel, -- 4.8.3
clipoutline, excludeoutline, cliprectangle, excluderectangle, -- 4.8.4
findfont, findfontvec, -- 4.9.1
modifyfont, setfont, -- 4.9.2
correctmask, correctspace, correct, -- 4.10
setcorrectmeasure, setcorrecttolerance, space, -- 4.10.2
-- Symbols
beginBody, endBody, beginBlock, endBlock,
pageInstructions, noPages, metricMaster, environmentMaster
};
Primitive: TYPE ~ Op[nil..space];
TypeCode: TYPE ~ MACHINE DEPENDENT {null(0),
number(1), identifier(2), vector(3), operator(4), -- Base types
transformation(5), pixelArray(6), color(7), trajectory(8), outline(9), -- Image types
other(31)
};
ImagerVariable: TYPE ~ MACHINE DEPENDENT {
DCScpx(0), DCScpy(1),
correctMX(2), correctMY(3),
T(4),
priorityImportant(5),
mediumXSize(6), mediumYSize(7),
fieldXMin(8), fieldYMin(9),
fieldXMax(10), fieldYMax(11),
showVec(12),
color(13),
noImage(14),
strokeWidth(15),
strokeStyle(16),
underlineStart(17),
amplifySpace(18),
correctPass(19),
correctShrink(20),
correctTX(21), correctTY(22),
strokeDashes(23)
};
StrokeStyle: TYPE ~ MACHINE DEPENDENT {
square(0), butt(1), round(2), -- standard, all with mitered joints
(7) -- room for expansion (round joints, probably)
};
TokenType: TYPE ~ {nil,
op, number, integer, rational, string, identifier, comment, insertFile,
largeVector, packedPixelVector, compressedPixelVector, adaptivePixelVector
};
Token: TYPE ~ RECORD[
index: INT ← 0, -- stream index of token's first byte
type: TokenType ← nil, -- type of token
op: Op ← nil, -- Op value if type=op, nil otherwise
number: INTEGER ← 0, -- number value if type=number, 0 otherwise
length: INT ← 0 -- number of data bytes following token
];
Body: TYPE ~ REF BodyRep;
BodyRep: TYPE ~ RECORD[index, length: INT];
Node: TYPE ~ REF NodeRep;
NodeRep: TYPE ~ RECORD[
index, length: INT,
pageInstructions: Body, -- may be NIL
content: SELECT tag: * FROM
body => [body: Body],
block => [block: Block],
ENDCASE
];
Block: TYPE ~ REF BlockRep;
BlockRep: TYPE ~ RECORD[
index, length: INT,
noPages: BOOL,
preamble: Node,
nodes: SEQUENCE size: NAT OF Node
];
Skeleton: TYPE ~ REF SkeletonRep;
SkeletonRep: TYPE ~ RECORD[
instructions: Body, -- may be NIL
topBlock: Block
];
Error: ERROR[code: ErrorCode, explanation: ROPE];
ErrorCode: TYPE ~ {
nil,
bug,
unimplemented,
invalidHeader,
invalidSkeleton,
invalidToken,
invalidRational,
invalidIdentifier
};
OpFromEncodingValue: PROC[IPXerox.EncodingValue] RETURNS[Op];
Converts a Xerox encoding value to an Op. Returns nil if undefined.
EncodingValueFromOp: PROC[Op] RETURNS[IPXerox.EncodingValue];
Converts an Op to a Xerox encoding value.
TokenTypeFromSequenceType: PROC[IPXerox.SequenceType] RETURNS[TokenType];
Converts a Xerox sequence type to a TokenType. Returns nil if undefined.
SequenceTypeFromTokenType: PROC[TokenType] RETURNS[IPXerox.SequenceType];
Converts a TokenType to a Xerox sequence type. Returns nil if undefined.
OpFromRope: PROC[ROPE] RETURNS[Op];
Converts a ROPE to an Op. Ignores case. Returns nil if undefined.
RopeFromOp: PROC[Op] RETURNS[ROPE];
Converts an Op to a ROPE. Returns NIL if given nil.
RopeFromImagerVariable: PROC[ImagerVariable] RETURNS[ROPE];
Converts an ImagerVariable to a ROPE.
GetHeader: PROC[stream: STREAM, prefix: ROPENIL] RETURNS[suffix: ROPE];
Reads an Interpress-style header from the stream.
The header must begin with prefix (default "Interpress/Xerox/"). Case must match.
Continues reading up to the first space; leaves the stream positioned after the space.
Returns characters following prefix, not including the final space (typically "2.1").
! Error[invalidHeader] if the header doesn't match the prefix or is too long.
GetSkeleton: PROC[stream: STREAM] RETURNS[Skeleton];
Parses the skeleton structure of the master.
! Error[invalidSkeleton] if the skeleton is malformed.
SkipToEndOfBody: PROC[stream: STREAM];
Skips to the end of the enclosing body.
Leaves the stream positioned at the token following the body.
SetIndex: PROC[stream: STREAM, index: INT];
Same as IO.SetIndex[stream, index]. Here for convenience.
CopyBytes: PROC[to: STREAM, from: STREAM, count: INT] RETURNS[copied: INT];
Copies bytes to an output stream from an input stream.
Returns the actual number of bytes copied.
CopySegment: PROC[to: STREAM, from: STREAM, start, length: INT];
Does SetIndex[from, start], then copies length bytes.
! IO.EndOfStream[from] if too few bytes were copied.
GetToken: PROC[stream: STREAM, flushComments: BOOLTRUE] RETURNS[token: Token];
Reads the next token from the stream. If flushComments, skips over comments.
More data may follow the token: token.length is the number of following bytes, if any.
Hence, after GetToken is called, the next token begins at IO.GetIndex[stream]+token.length.
SkipBytes: PROC[stream: STREAM, length: INT];
For any token, SkipBytes[stream, token.length] will ignore the data part.
GetInteger: PROC[stream: STREAM, length: INT] RETURNS[REAL];
For token.type = integer.
GetRational: PROC[stream: STREAM, length: INT] RETURNS[REAL];
For token.type = rational.
! Error[invalidToken] if length is odd.
! Real.RealException if denominator is too small.
GetRope: PROC[stream: STREAM, length: INT] RETURNS[ROPE];
For token.type = string, identifier, comment, or insertFile.
GetText: PROC[stream: STREAM, length: NAT, scratch: REF TEXTNIL] RETURNS[text: REF TEXT];
For token.type = string, identifier, comment, or insertFile.
Uses scratch if scratch#NIL AND length<=scratch.maxLength, else does a NEW.
Puts the result in text[0..length), sets text.length ← length.
GetByte: PROC[stream: STREAM] RETURNS[BYTE];
Gets one byte.
GetUnsigned: PROC[stream: STREAM, length: [0..4]] RETURNS[CARD];
Gets length bytes as an unsigned value.
GetSigned: PROC[stream: STREAM, length: [0..4]] RETURNS[INT];
Gets length bytes as a signed value.
Can be used for token.type = integer if token.length<=4.
PutOp: PROC[stream: STREAM, op: Op];
Appends a primitive operator or symbol literal.
PutInt: PROC[stream: STREAM, n: INT];
Appends a Number literal.
PutRational: PROC[stream: STREAM, n, d: INT];
Appends a Number literal, n/d.
! Error[invalidRational] if d is zero.
PutReal: PROC[stream: STREAM, val: REAL];
Appends a Number literal. Chooses a rational approximation if necessary.
PutIdentifier: PROC[stream: STREAM, rope: ROPE];
Appends an Identifier literal.
! Error[invalidIdentifier] if the rope is not a legal identifier.
PutString: PROC[stream: STREAM, rope: ROPE];
Appends the encoding notation for a string. Treats '\377 as an escape code.
See the Character Code Standard, chapter 6, and Interpress, section 2.5.3.
! Error[invalidString] if the rope is not a legal string.
PutComment: PROC[stream: STREAM, rope: ROPE];
Appends a comment token.
PutInsertFile: PROC[stream: STREAM, rope: ROPE];
Appends a sequenceInsertFile.
PutName: PROC[stream: STREAM, name: ROPE];
Parses a structured name and appends tokens to build a Vector of Identifiers.
For example, "a/b/c" produces < a b c 3 MAKEVEC >; "foo" produces < foo 1 MAKEVEC >.
See Interpress, section 3.2.1.
! Error[invalidIdentifier] if the name contains an invalid identifier.
PutDescriptor: PROC[stream: STREAM, type: TokenType, length: INT];
Appends a sequence descriptor. Must be followed by length bytes.
PutByte: PROC[stream: STREAM, byte: BYTE];
Appends one byte.
PutUnsigned: PROC[stream: STREAM, length: [0..4], val: CARD];
Appends the low order length bytes of val.
PutSigned: PROC[stream: STREAM, length: [0..4], val: INT];
Appends the low order length bytes of val.
END.