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:
ROPE ←
NIL]
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:
BOOL ←
TRUE]
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
TEXT ←
NIL]
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.