InterpressComposeCommandImpl.mesa
Copyright Ó 1984, 1985, 1986, 1987 by Xerox Corporation. All rights reserved.
Michael Plass, March 27, 1987 7:25:01 pm PST
Bloomenthal, August 22, 1987 0:13:42 am PDT
gbb February 26, 1988 11:00:55 am PST
DIRECTORY
Commander, CommandTool, Convert, FileNames, FS, Imager, ImagerColorFns, ImagerInterpress, ImagerTransformation, Interpress, IO, ProcessProps, Rope;
InterpressComposeCommandImpl: CEDAR PROGRAM
IMPORTS Commander, CommandTool, Convert, FileNames, FS, Imager, ImagerColorFns, ImagerInterpress, ImagerTransformation, Interpress, IO, ProcessProps, Rope
~ BEGIN
ROPE:    TYPE ~ Rope.ROPE;
Transformation:  TYPE ~ ImagerTransformation.Transformation;
Master:   TYPE ~ Interpress.Master;
Input:    TYPE ~ RECORD [name: ROPENIL, xform: Transformation, master: Master];
InterpressCompose: PROC [output: ROPE, inputs: LIST OF Input] ~ {
prevMsg: ROPENIL;
matchCount: INT ← 0;
Log: Interpress.LogProc ~ {
WITH ProcessProps.GetProp[$ErrOut] SELECT FROM
errOut: IO.STREAM => {
IF Rope.Equal[explanation, prevMsg]
THEN {matchCount ← matchCount + 1}
ELSE {
IF matchCount > 0
THEN IO.PutF[errOut, " (and %g more)\n", IO.int[matchCount]];
IO.PutRope[errOut, explanation];
IF explanation # NIL THEN IO.PutChar[errOut, '\n];
prevMsg ← explanation;
matchCount ← 0;
};
};
ENDCASE => NULL;
};
nPages: NAT ← 0;
outRef: ImagerInterpress.Ref ~ ImagerInterpress.Create[output];
FOR l: LIST OF Input ← inputs, l.rest WHILE l # NIL DO
m: Transformation ← l.first.xform;
l.first.master ← Interpress.Open[l.first.name, NIL];
IF l.first.master.pages > nPages THEN nPages ← l.first.master.pages;
ENDLOOP;
FOR page: INT IN [1..nPages] DO
WriteAction: PROC [context: Imager.Context] ~ {
m: Transformation ← ImagerBackdoor.GetT[context];
context.SetColor [ImagerColorFns.ColorFromCMYK [[0.0, 0.0, 0.0, 1.0]]];
FOR l: LIST OF Input ← inputs, l.rest WHILE l # NIL DO
p: INT ~ ((page-1) MOD l.first.master.pages)+1; -- Cycle through master as needed
ImagerBackdoor.SetT[context, ImagerTransformation.Concat[l.first.xform, m]];
Imager.ConcatT[context, l.first.xform];
Interpress.DoPage[l.first.master, p, context, NIL];
Imager.ConcatT[context, ImagerTransformation.Invert[l.first.xform]]; -- a crock!
ENDLOOP
};
ImagerInterpress.DoPage[outRef, WriteAction];
ENDLOOP;
Log[-1, NIL, NIL];
ImagerInterpress.Close[outRef];
};
isItError: ERROR = CODE;
InterpressComposeCommand: Commander.CommandProc ~ {
ENABLE {
isItError => GOTO BadSyntax;
FS.Error => {
msg ← error.explanation;
GOTO Failure;
};
Convert.Error => {
msg ← "Conversion error";
GOTO Failure;
};
};
IsIt: PROC [rope: ROPE, argsNeeded: INT] RETURNS [b: BOOL] ~ {
IF argIndex >= args.argc THEN RETURN[FALSE];
b ← Rope.Equal[rope, args[argIndex], FALSE];
IF b AND args.argc <= argIndex+argsNeeded THEN ERROR isItError;
};
SkipArgs: PROC [nSkip: INT] ~ {argIndex ← argIndex+nSkip};
Real: PROC [index: INT] RETURNS [r: REAL] ~ {r ← Convert.RealFromRope[args[index]]};
argIndex: INT ← 3;
inputs: LIST OF Input;
m: Transformation ← NIL;
args: CommandTool.ArgumentVector ~ CommandTool.Parse[cmd];
IF args.argc < 3 OR NOT Rope.Equal["←", args[2]] THEN GOTO BadSyntax;
WHILE argIndex < args.argc DO
SELECT TRUE FROM
IsIt["translate", 2] => {
s: REAL ← 1.0;
x: REAL ← Real[argIndex+1];
y: REAL ← Real[argIndex+2];
SkipArgs[3];
SELECT TRUE FROM
IsIt["in", 0] => s ← Imager.metersPerInch;
IsIt["cm", 0] => s ← 0.01;
IsIt["mm", 0] => s ← 0.001;
IsIt["pt", 0] => s ← Imager.metersPerPoint;
ENDCASE;
IF s # 1.0 THEN SkipArgs[1];
m^ ← ImagerTransformation.PreTranslate[m, [s*x, s*y]]^;
};
IsIt["rotate", 1] => {
angle: REAL ← Real[argIndex+1];
SkipArgs[2];
IF IsIt["radians", 1] THEN {
angle ← 180.0*angle/3.1415926535;
SkipArgs[1];
};
m^ ← ImagerTransformation.PreRotate[m, angle]^;
};
IsIt["scale", 1] => {
m^ ← ImagerTransformation.PreScale[m, Real[argIndex+1]]^;
SkipArgs[2];
};
IsIt["scale2", 2] => {
m^ ← ImagerTransformation.PreScale2[m, [Real[argIndex+1], Real[argIndex+2]]]^;
SkipArgs[3];
};
ENDCASE => {
m ← ImagerTransformation.Scale[1];
inputs ← CONS[[FileNames.ResolveRelativePath[args[argIndex]], m], inputs];
SkipArgs[1];
};
ENDLOOP;
InterpressCompose[args[1], inputs];
EXITS
BadSyntax => RETURN[$Failure, interpressComposeUsage];
Failure => result ← $Failure;
};
interpressComposeUsage: ROPE ~ "
InterpressCompose <output> ← <input1> [xfrm1] ... <inputN> [xfrmN]
Combine input interpress masters, each with an optional transform.
A transform is a combination of:
  translate <x> <y> [in | m | cm | mm | pt]
 | rotate <angle> [radians]
 | scale <scale>
 | scale2 <xScale> <yScale>.";
Commander.Register["InterpressCompose", InterpressComposeCommand, interpressComposeUsage];
Commander.Register["IPCompose", InterpressComposeCommand, interpressComposeUsage];
END.