ImagerInterpressImpl.mesa
Copyright © 1984, Xerox Corporation. All rights reserved.
Doug Wyatt, November 30, 1984 2:50:37 pm PST
DIRECTORY
Basics USING [bytesPerWord],
FS USING [StreamOpen],
Imager USING [Class, ClassRep, Context, ContextRep, Error, IntKey, RealKey],
ImagerColor USING [Color, ColorOperator, ColorOperatorRep, ConstantColor, SampledColor, SampleMap, Separation, SpecialColor],
ImagerFont USING [Char, CharSet, Font],
ImagerPath USING [Clipper, Filter, PathProc],
ImagerPixelArray USING [GetRow, MaxSampleValue, PixelArray, Row, RowRep],
ImagerTransformation USING [Factor, FactoredTransformation, Transformation],
IO USING [Close, PutBlock, PutRope, STREAM, UnsafePutBlock],
IPMaster USING [ImagerVariable, PutByte, PutDescriptor, PutInt, PutName, PutOp, PutReal],
RefText USING [AppendChar],
Rope USING [ROPE],
Vector2 USING [VEC];
ImagerInterpressImpl: CEDAR PROGRAM
IMPORTS FS, Imager, ImagerPath, ImagerPixelArray, ImagerTransformation, IO, IPMaster, RefText
~ BEGIN OPEN IPMaster;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
VEC: TYPE ~ Vector2.VEC;
Transformation: TYPE ~ ImagerTransformation.Transformation;
PathProc: TYPE ~ ImagerPath.PathProc;
PixelArray: TYPE ~ ImagerPixelArray.PixelArray;
Color: TYPE ~ ImagerColor.Color;
ConstantColor: TYPE ~ ImagerColor.ConstantColor;
SampledColor: TYPE ~ ImagerColor.SampledColor;
SpecialColor: TYPE ~ ImagerColor.SpecialColor;
ColorOperator: TYPE ~ ImagerColor.ColorOperator;
ColorOperatorRep: TYPE ~ ImagerColor.ColorOperatorRep;
Clipper: TYPE ~ ImagerPath.Clipper;
Font: TYPE ~ ImagerFont.Font;
Char: TYPE ~ ImagerFont.Char;
CharSet: TYPE ~ ImagerFont.CharSet;
Context: TYPE ~ Imager.Context;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD[
stream: STREAM,
text: REF TEXTNIL,
frame: Frame ← NIL
];
Frame: TYPE ~ LIST OF FrameItem;
FrameItem: TYPE ~ RECORD[ref: REF, index: INT];
Open: PROC[name: ROPE] RETURNS[Context] ~ {
stream: STREAM ~ FS.StreamOpen[name, $create];
IO.PutRope[stream, "Interpress/Xerox/3.0 "];
PutOp[stream, beginBlock];
PutOp[stream, beginBody];
PutOp[stream, endBody];
PutOp[stream, beginBody];
RETURN[CreateFromStream[stream]];
};
Close: PROC[context: Context] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutOp[stream, endBody];
PutOp[stream, endBlock];
IO.Close[stream];
};
CreateFromStream: PROC[stream: STREAM] RETURNS[Context] ~ {
data: Data ~ NEW[DataRep ← [stream: stream]];
data.text ← NEW[TEXT[200]];
RETURN[NEW[Imager.ContextRep ← [class: ipClass, data: data, props: NIL]]];
};
PutVec: PROC[stream: STREAM, v: VEC] ~ {
PutReal[stream, v.x];
PutReal[stream, v.y];
};
PutTransformation: PROC[stream: STREAM, m: Transformation] ~ {
f: ImagerTransformation.FactoredTransformation ~ ImagerTransformation.Factor[m];
depth: NAT ← 0;
IF f.preRotate#0 THEN {
PutReal[stream, f.preRotate]; PutOp[stream, rotate];
depth ← depth+1;
};
IF f.scale.x#f.scale.y THEN {
PutVec[stream, f.scale]; PutOp[stream, scale2];
depth ← depth+1;
}
ELSE IF f.scale.x#1 THEN {
PutReal[stream, f.scale.x]; PutOp[stream, scale];
depth ← depth+1;
};
IF f.postRotate#0 THEN {
PutReal[stream, f.postRotate]; PutOp[stream, rotate];
depth ← depth+1;
};
IF f.translate.x#0 OR f.translate.y#0 THEN {
PutVec[stream, f.translate]; PutOp[stream, translate];
depth ← depth+1;
};
WHILE depth>1 DO PutOp[stream, concat]; depth ← depth-1 ENDLOOP;
IF depth=0 THEN { PutInt[stream, 1]; PutOp[stream, scale] };
};
PutPath: PROC[stream: STREAM, pathProc: PathProc, pathData: REF, action: PROC] ~ {
p0: VEC ← [0, 0];
moveTo: PROC[p: VEC] ~ {
PutVec[stream, p];
PutOp[stream, moveto];
p0 ← p;
};
lineTo: PROC[p1: VEC] ~ {
IF p1.y=p0.y THEN {
PutReal[stream, p1.x];
PutOp[stream, linetox];
}
ELSE IF p1.x=p0.x THEN {
PutReal[stream, p1.y];
PutOp[stream, linetoy];
}
ELSE {
PutVec[stream, p1];
PutOp[stream, lineto];
};
p0 ← p1;
};
curveTo: PROC[p1, p2, p3: VEC] ~ {
PutVec[stream, p1];
PutVec[stream, p2];
PutVec[stream, p3];
PutOp[stream, curveto];
p0 ← p3;
};
conicTo: PROC[p1, p2: VEC, r: REAL] ~ {
PutVec[stream, p1];
PutVec[stream, p2];
PutReal[stream, r];
PutOp[stream, conicto];
p0 ← p2;
};
arcTo: PROC[p1, p2: VEC] ~ {
PutVec[stream, p1];
PutVec[stream, p2];
PutOp[stream, arcto];
p0 ← p2;
};
ImagerPath.Filter[pathProc: pathProc, pathData: pathData,
moveTo: moveTo, lineTo: lineTo, curveTo: curveTo,
conicTo: conicTo, arcTo: arcTo, close: action];
};
PutMakeVec: PROC[stream: STREAM, n: INT] ~ {
PutInt[stream, n];
PutOp[stream, makevec];
};
FGet: PROC[stream: STREAM, index: INT] ~ {
PutInt[stream, index];
PutOp[stream, fget];
};
FSet: PROC[stream: STREAM, index: INT] ~ {
PutInt[stream, index];
PutOp[stream, fset];
};
MakeFont: PROC[data: Data, font: Font] ~ {
stream: STREAM ~ data.stream;
PutName[stream, font.name];
PutOp[stream, findfont];
PutTransformation[stream, font.charToClient];
PutOp[stream, modifyfont];
};
MakePixelArray: PROC[data: Data, pa: PixelArray] ~ {
stream: STREAM ~ data.stream;
max: CARDINAL ← 0;
row: ImagerPixelArray.Row ~ NEW[ImagerPixelArray.RowRep[pa.fSize]];
PutInt[stream, pa.sSize]; -- xPixels
PutInt[stream, pa.fSize]; -- yPixels
PutInt[stream, pa.samplesPerPixel]; -- samplesPerPixel
FOR i: NAT IN[0..pa.samplesPerPixel) DO
m: CARDINAL ~ pa.MaxSampleValue[i];
PutInt[stream, m];
max ← MAX[max, m];
ENDLOOP;
PutMakeVec[stream, pa.samplesPerPixel]; -- maxSampleValue
PutInt[stream, 0]; -- samplesInterleaved
PutTransformation[stream, pa.m]; -- m
IF max>255 THEN ERROR; -- can't handle it yet
PutDescriptor[stream, $largeVector, 1+INT[pa.samplesPerPixel]*INT[pa.sSize]*INT[pa.fSize]];
PutByte[stream, 1]; -- 1 byte per element
FOR i: NAT IN[0..pa.samplesPerPixel) DO
FOR s: NAT IN[0..pa.sSize) DO
pa.GetRow[row, s, 0, i];
TRUSTED { [] ← IO.UnsafePutBlock[stream, [
base: LOOPHOLE[row],
startIndex: Basics.bytesPerWord*SIZE[ImagerPixelArray.RowRep[0]],
count: pa.fSize]] };
ENDLOOP;
ENDLOOP;
PutOp[stream, makepixelarray];
};
MakeColor: PROC[data: Data, color: Color] ~ {
stream: STREAM ~ data.stream;
WITH color SELECT FROM
color: ConstantColor => {
PutReal[stream, color.cie.X];
PutReal[stream, color.cie.Y];
PutReal[stream, color.cie.Z];
PutMakeVec[stream, 3];
GetComposedOp[data, $makecie];
PutOp[stream, do];
};
color: SampledColor => {
GetPixelArray[data, color.pa]; -- pa
PutTransformation[stream, color.um]; -- um
GetColorOperator[data, color.colorOperator]; -- colorOperator
PutOp[stream, makesampledcolor];
};
ENDCASE => ERROR Imager.Error[Unimplemented];
};
MakeColorOperator: PROC[data: Data, colorOperator: ColorOperator] ~ {
stream: STREAM ~ data.stream;
WITH colorOperator SELECT FROM
op: REF ColorOperatorRep.grayLinear => {
PutReal[stream, op.sWhite];
PutReal[stream, op.sBlack];
PutSampleMap[stream, op.map];
PutMakeVec[stream, 3];
PutName[stream, "standard/grayLinear"];
PutOp[stream, findcolormodeloperator];
PutOp[stream, do];
};
op: REF ColorOperatorRep.grayDensity => {
PutReal[stream, op.sWhite];
PutReal[stream, op.sBlack];
PutReal[stream, op.dBlack];
PutSampleMap[stream, op.map];
PutMakeVec[stream, 4];
PutName[stream, "standard/grayDensity"];
PutOp[stream, findcolormodeloperator];
PutOp[stream, do];
};
op: REF ColorOperatorRep.grayVisual => {
PutReal[stream, op.sWhite];
PutReal[stream, op.sBlack];
PutSampleMap[stream, op.map];
PutMakeVec[stream, 3];
PutName[stream, "standard/grayVisual"];
PutOp[stream, findcolormodeloperator];
PutOp[stream, do];
};
op: REF ColorOperatorRep.separations => {
FOR i: NAT IN[0..op.samplesPerPixel) DO
sep: ImagerColor.Separation ~ op[i];
PutReal[stream, sep.cie.X];
PutReal[stream, sep.cie.Y];
PutReal[stream, sep.cie.Z];
PutReal[stream, sep.sMax];
PutReal[stream, sep.sMin];
PutSampleMap[stream, sep.map];
PutMakeVec[stream, 6];
ENDLOOP;
PutMakeVec[stream, op.samplesPerPixel];
PutName[stream, "standard/separations"];
PutOp[stream, findcolormodeloperator];
PutOp[stream, do];
};
ENDCASE => ERROR Imager.Error[Unimplemented];
};
PutSampleMap: PROC[stream: STREAM, map: ImagerColor.SampleMap] ~ {
IF map=NIL THEN PutInt[stream, 0]
ELSE {
FOR i: NAT IN[0..map.size) DO PutReal[stream, map[i]] ENDLOOP;
PutMakeVec[stream, map.size];
};
};
MakeComposedOp: PROC[data: Data, op: REF] ~ {
stream: STREAM ~ data.stream;
SELECT op FROM
$makecie => {
PutName[stream, "standard/CIE"];
PutOp[stream, findcoloroperator];
};
ENDCASE => ERROR Imager.Error[Bug];
};
Fetch: PROC[data: Data, ref: REF] RETURNS[found: BOOL, index: INT] ~ {
FOR each: Frame ← data.frame, each.rest UNTIL each=NIL DO
IF each.first.ref=ref THEN RETURN[TRUE, each.first.index];
ENDLOOP;
RETURN[FALSE, 0];
};
Store: PROC[data: Data, ref: REF] RETURNS[INT] ~ {
frame: Frame ~ data.frame;
index: INT ~ IF frame=NIL THEN 0 ELSE frame.first.index+1;
data.frame ← CONS[[ref, index], data.frame];
RETURN[index];
};
GetFontIndex: PROC[data: Data, font: Font] ~ {
stream: STREAM ~ data.stream;
found: BOOL; index: INT;
[found, index] ← Fetch[data, font];
IF NOT found THEN {
MakeFont[data, font];
index ← Store[data, font];
FSet[stream, index];
};
PutInt[stream, index];
};
GetColor: PROC[data: Data, color: Color] ~ {
stream: STREAM ~ data.stream;
found: BOOL; index: INT;
[found, index] ← Fetch[data, color];
IF found THEN FGet[stream, index]
ELSE {
MakeColor[data, color];
index ← Store[data, color];
PutOp[stream, dup];
FSet[stream, index];
};
};
GetColorOperator: PROC[data: Data, colorOperator: ColorOperator] ~ {
stream: STREAM ~ data.stream;
found: BOOL; index: INT;
[found, index] ← Fetch[data, colorOperator];
IF found THEN FGet[stream, index]
ELSE {
MakeColorOperator[data, colorOperator];
index ← Store[data, colorOperator];
PutOp[stream, dup];
FSet[stream, index];
};
};
GetPixelArray: PROC[data: Data, pa: PixelArray] ~ {
stream: STREAM ~ data.stream;
found: BOOL; index: INT;
[found, index] ← Fetch[data, pa];
IF found THEN FGet[stream, index]
ELSE {
MakePixelArray[data, pa];
index ← Store[data, pa];
PutOp[stream, dup];
FSet[stream, index];
};
};
GetComposedOp: PROC[data: Data, op: REF] ~ {
stream: STREAM ~ data.stream;
found: BOOL; index: INT;
[found, index] ← Fetch[data, op];
IF found THEN FGet[stream, index]
ELSE {
MakeComposedOp[data, op];
index ← Store[data, op];
PutOp[stream, dup];
FSet[stream, index];
};
};
IPDoSave: PROC[context: Context, action: PROC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
frame: Frame ~ data.frame;
PutOp[stream, dosavesimplebody];
PutOp[stream, beginBody];
action[! UNWIND => data.frame ← frame];
PutOp[stream, endBody];
data.frame ← frame;
};
IPDoSaveAll: PROC[context: Context, action: PROC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
frame: Frame ~ data.frame;
PutOp[stream, makesimpleco];
PutOp[stream, beginBody];
action[! UNWIND => data.frame ← frame];
PutOp[stream, endBody];
PutOp[stream, dosaveall];
data.frame ← frame;
};
IPSetT: PROC[context: Context, m: Transformation] ~ {
ERROR Imager.Error[Unimplemented];
};
IPSetFont: PROC[context: Context, font: Font] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
GetFontIndex[data, font];
PutOp[stream, setfont];
};
IPSetColor: PROC[context: Context, color: Color] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
WITH color SELECT FROM
color: ConstantColor => -- IF color.gray THEN -- {
PutReal[stream, 1-color.cie.Y];
PutOp[stream, setgray];
RETURN;
};
ENDCASE;
GetColor[data, color];
PutInt[stream, ORD[ImagerVariable[color]]];
PutOp[stream, iset];
};
IPSetClipper: PROC[context: Context, clipper: Clipper] ~ {
ERROR Imager.Error[Unimplemented];
};
IPSetReal: PROC[context: Context, key: Imager.RealKey, value: REAL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
var: ImagerVariable;
SELECT key FROM
strokeWidth => var ← strokeWidth;
underlineStart => var ← underlineStart;
amplifySpace => var ← amplifySpace;
correctShrink => var ← correctShrink;
ENDCASE => ERROR Imager.Error[Unimplemented];
PutReal[stream, value];
PutInt[stream, ORD[var]];
PutOp[stream, iset];
};
IPSetInt: PROC[context: Context, key: Imager.IntKey, value: INT] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
var: ImagerVariable;
SELECT key FROM
priorityImportant => var ← priorityImportant;
noImage => var ← noImage;
strokeStyle => var ← strokeStyle;
ENDCASE => ERROR Imager.Error[Unimplemented];
PutInt[stream, value];
PutInt[stream, ORD[var]];
PutOp[stream, iset];
};
IPGetT: PROC[context: Context] RETURNS[Transformation] ~ {
ERROR Imager.Error[Unimplemented];
};
IPGetFont: PROC[context: Context] RETURNS[Font] ~ {
ERROR Imager.Error[Unimplemented];
};
IPGetColor: PROC[context: Context] RETURNS[Color] ~ {
ERROR Imager.Error[Unimplemented];
};
IPGetClipper: PROC[context: Context] RETURNS[Clipper] ~ {
ERROR Imager.Error[Unimplemented];
};
IPGetReal: PROC[context: Context, key: Imager.RealKey] RETURNS[REAL] ~ {
ERROR Imager.Error[Unimplemented];
};
IPGetInt: PROC[context: Context, key: Imager.IntKey] RETURNS[INT] ~ {
ERROR Imager.Error[Unimplemented];
};
IPConcatT: PROC[context: Context, m: Transformation] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutTransformation[stream, m];
PutOp[stream, concatt];
};
IPScale2T: PROC[context: Context, s: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
IF s.x=s.y THEN { PutReal[stream, s.x]; PutOp[stream, scale] }
ELSE { PutVec[stream, s]; PutOp[stream, scale2] };
PutOp[stream, concatt];
};
IPRotateT: PROC[context: Context, a: REAL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutReal[stream, a]; PutOp[stream, rotate];
PutOp[stream, concatt];
};
IPTranslateT: PROC[context: Context, t: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutVec[stream, t]; PutOp[stream, translate];
PutOp[stream, concatt];
};
IPMove: PROC[context: Context] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutOp[stream, move];
};
IPTrans: PROC[context: Context] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutOp[stream, trans];
};
IPSetGray: PROC[context: Context, f: REAL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutReal[stream, f];
PutOp[stream, setgray];
};
IPSetSampledColor: PROC[context: Context, pa: PixelArray, m: Transformation, colorOperator: ColorOperator] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
GetPixelArray[data, pa]; -- pa
PutTransformation[stream, m];
PutInt[stream, ORD[ImagerVariable[T]]];
PutOp[stream, iget];
PutOp[stream, concat]; -- um = <m 4 IGET CONCAT>
GetColorOperator[data, colorOperator]; -- colorOperator
PutOp[stream, makesampledcolor];
PutInt[stream, ORD[ImagerVariable[color]]];
PutOp[stream, iset];
};
IPMaskFill: PROC[context: Context, pathProc: PathProc, pathData: REF, parity: BOOL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
depth: INT ← 0; count: PROC ~ { depth ← depth+1 };
PutPath[stream, pathProc, pathData, count];
PutInt[stream, depth];
PutOp[stream, makeoutline];
PutOp[stream, IF parity THEN maskfillparity ELSE maskfill];
};
IPMaskStroke: PROC[context: Context, pathProc: PathProc, pathData: REF, closed: BOOL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
stroke: PROC ~ { PutOp[stream, IF closed THEN maskstrokeclosed ELSE maskstroke] };
PutPath[stream, pathProc, pathData, stroke];
};
IPMaskRectangle: PROC[context: Context, x, y, w, h: REAL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutReal[stream, x];
PutReal[stream, y];
PutReal[stream, w];
PutReal[stream, h];
PutOp[stream, maskrectangle];
};
IPMaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutInt[stream, x];
PutInt[stream, y];
PutInt[stream, w];
PutInt[stream, h];
PutOp[stream, maskrectangle];
};
IPMaskVector: PROC[context: Context, p1, p2: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutVec[stream, p1];
PutVec[stream, p2];
PutOp[stream, maskvector];
};
IPMaskVectorI: PROC[context: Context, x1, y1, x2, y2: INTEGER] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutInt[stream, x1];
PutInt[stream, y1];
PutInt[stream, x2];
PutInt[stream, y2];
PutOp[stream, maskvector];
};
IPStartUnderline: PROC[context: Context] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutOp[stream, startunderline];
};
IPMaskUnderline: PROC[context: Context, dy, h: REAL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutReal[stream, dy];
PutReal[stream, h];
PutOp[stream, maskunderline];
};
IPMaskUnderlineI: PROC[context: Context, dy, h: INTEGER] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutInt[stream, dy];
PutInt[stream, h];
PutOp[stream, maskunderline];
};
IPMaskPixel: PROC[context: Context, pa: PixelArray] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
MakePixelArray[data, pa];
PutOp[stream, maskpixel];
};
IPMaskBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, sOffset, fOffset: INTEGER] ~ {
data: Data ~ NARROW[context.data];
ERROR Imager.Error[NotYetImplemented];
};
IPClipOutline: PROC[context: Context, pathProc: PathProc, pathData: REF, exclude: BOOL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
depth: INT ← 0; count: PROC ~ { depth ← depth+1 };
PutPath[stream, pathProc, pathData, count];
PutInt[stream, depth];
PutOp[stream, makeoutline];
PutOp[stream, IF exclude THEN excludeoutline ELSE clipoutline];
};
IPClipRectangle: PROC[context: Context, x, y, w, h: REAL, exclude: BOOL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutReal[stream, x];
PutReal[stream, y];
PutReal[stream, w];
PutReal[stream, h];
PutOp[stream, IF exclude THEN excluderectangle ELSE cliprectangle];
};
IPClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutInt[stream, x];
PutInt[stream, y];
PutInt[stream, w];
PutInt[stream, h];
PutOp[stream, IF exclude THEN excluderectangle ELSE cliprectangle];
};
IPSetXY: PROC[context: Context, p: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutVec[stream, p];
PutOp[stream, setxy];
};
IPSetXYI: PROC[context: Context, x, y: INTEGER] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutInt[stream, x];
PutInt[stream, y];
PutOp[stream, setxy];
};
IPSetXYRel: PROC[context: Context, v: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
IF v.y=0 THEN { PutReal[stream, v.x]; PutOp[stream, setxrel] }
ELSE IF v.x=0 THEN { PutReal[stream, v.y]; PutOp[stream, setyrel] }
ELSE { PutVec[stream, v]; PutOp[stream, setxyrel] };
};
IPSetXYRelI: PROC[context: Context, x, y: INTEGER] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
IF y=0 THEN { PutInt[stream, x]; PutOp[stream, setxrel] }
ELSE IF x=0 THEN { PutInt[stream, y]; PutOp[stream, setyrel] }
ELSE { PutInt[stream, x]; PutInt[stream, y]; PutOp[stream, setxyrel] };
};
IPGetCP: PROC[context: Context, round: BOOL] RETURNS[VEC] ~ {
ERROR Imager.Error[Unimplemented];
};
IPShow: PROC[context: Context, chars: PROC[PROC[Char]], xrel: BOOL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
text: REF TEXT ← data.text;
set: CharSet ← 0;
char: PROC[code: Char] ~ {
IF (code/256)#set THEN {
text ← RefText.AppendChar[to: text, from: VAL[255]];
text ← RefText.AppendChar[to: text, from: VAL[set ← code/256]];
};
text ← RefText.AppendChar[to: text, from: VAL[code MOD 256]];
};
text.length ← 0;
chars[char];
PutDescriptor[stream, $string, text.length];
IO.PutBlock[self: stream, block: text, startIndex: 0, count: text.length];
PutOp[stream, show];
};
IPCorrectMask: PROC[context: Context] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutOp[stream, correctmask];
};
IPCorrectSpace: PROC[context: Context, v: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutVec[stream, v];
PutOp[stream, correctspace];
};
IPSpace: PROC[context: Context, x: REAL] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutReal[stream, x];
PutOp[stream, space];
};
IPSpaceI: PROC[context: Context, x: INTEGER] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutInt[stream, x];
PutOp[stream, space];
};
IPSetCorrectMeasure: PROC[context: Context, v: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutVec[stream, v];
PutOp[stream, setcorrectmeasure];
};
IPSetCorrectTolerance: PROC[context: Context, v: VEC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
PutVec[stream, v];
PutOp[stream, setcorrecttolerance];
};
IPCorrect: PROC[context: Context, action: PROC] ~ {
data: Data ~ NARROW[context.data];
stream: STREAM ~ data.stream;
frame: Frame ~ data.frame;
PutOp[stream, correct];
PutOp[stream, beginBody];
action[! UNWIND => data.frame ← frame];
PutOp[stream, endBody];
data.frame ← frame;
};
ipClass: Imager.Class ~ NEW[Imager.ClassRep ← [
type: $Interpress,
DoSave: IPDoSave,
DoSaveAll: IPDoSaveAll,
SetT: IPSetT,
SetFont: IPSetFont,
SetColor: IPSetColor,
SetClipper: IPSetClipper,
SetReal: IPSetReal,
SetInt: IPSetInt,
GetT: IPGetT,
GetFont: IPGetFont,
GetColor: IPGetColor,
GetClipper: IPGetClipper,
GetReal: IPGetReal,
GetInt: IPGetInt,
ConcatT: IPConcatT,
Scale2T: IPScale2T,
RotateT: IPRotateT,
TranslateT: IPTranslateT,
Move: IPMove,
Trans: IPTrans,
SetGray: IPSetGray,
SetSampledColor: IPSetSampledColor,
MaskFill: IPMaskFill,
MaskStroke: IPMaskStroke,
MaskRectangle: IPMaskRectangle,
MaskRectangleI: IPMaskRectangleI,
MaskVector: IPMaskVector,
MaskVectorI: IPMaskVectorI,
StartUnderline: IPStartUnderline,
MaskUnderline: IPMaskUnderline,
MaskUnderlineI: IPMaskUnderlineI,
MaskPixel: IPMaskPixel,
MaskBits: IPMaskBits,
ClipOutline: IPClipOutline,
ClipRectangle: IPClipRectangle,
ClipRectangleI: IPClipRectangleI,
SetXY: IPSetXY,
SetXYI: IPSetXYI,
SetXYRel: IPSetXYRel,
SetXYRelI: IPSetXYRelI,
GetCP: IPGetCP,
Show: IPShow,
CorrectMask: IPCorrectMask,
CorrectSpace: IPCorrectSpace,
Space: IPSpace,
SpaceI: IPSpaceI,
SetCorrectMeasure: IPSetCorrectMeasure,
SetCorrectTolerance: IPSetCorrectTolerance,
Correct: IPCorrect,
props: NIL
]];
END.