CDInterpressPlotImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Jacobi, July 12, 1985 8:50:32 am PST
Last Edited by: Jacobi, August 30, 1985 4:59:16 pm PDT
DIRECTORY
Atom,
CD,
CDBasics,
CDCommandOps,
CDExtras,
CDIO,
CDMenus,
CDOps,
CDProperties,
CDSequencer,
CDTexts,
FS,
Imager,
ImagerInterpress,
IO,
Real,
RefTab,
Rope,
SymTab,
TerminalIO;
CDInterpressPlotImpl: CEDAR PROGRAM
IMPORTS Atom, CD, CDBasics, CDCommandOps, CDExtras, CDIO, CDMenus, CDOps, CDProperties, CDSequencer, CDTexts, FS, Imager, ImagerInterpress, IO, Real, RefTab, Rope, SymTab, TerminalIO =
BEGIN
--constant sizes and scales
usPageX: REAL = 0.216; --(72*8.5-2; points) United States standard page with....
usPageY: REAL = 0.277; --(72*11.0; points)
versatecDeviceX: REAL = 0.97; --of the very special versatec plotter sitting close to my office... I really do not store in this constant the with of any other versatec plotter available...
--default sizes and scales
defaultPageX: REAL ← usPageX;
defaultPageY: REAL ← usPageY;
defaultStripeX: REAL ← versatecDeviceX;
defaultBorder: REAL ← Imager.metersPerInch;
defaultScale: REAL ← Imager.metersPerPoint/CD.lambda;
--others
abortFlag: REF BOOL = NEW[BOOLFALSE];
fileNameDefault: Rope.ROPE ← "///temp/temp.IP";
normalsetUp: BOOLFALSE;
--set ups for this very plot which will be created right now
pageX: REAL;
pageY: REAL;
contextFilter: REF CD.ContextFilter = NEW[CD.ContextFilter←ALL[[
doit: TRUE,
color: Imager.black
]]];
RectToRectangle: PROC [r: CD.Rect] RETURNS [Imager.Rectangle] =
BEGIN
RETURN [[x: r.x1, y: r.y1, w: r.x2-r.x1, h: r.y2-r.y1]]
END;
ResetContextFilter: PROC [ignoreProperties: BOOLTRUE] =
BEGIN
normalsetUp ← ignoreProperties;
FOR layer: CD.Layer IN CD.Layer DO
contextFilter[layer].doit ← ignoreProperties;
CDProperties.PutPropOnLayer[layer, $CDxInterpressPlot, NIL];
ENDLOOP;
contextFilter[CD.backGround].doit ← FALSE;
END;
SetUpContextFilter: PROC [] =
BEGIN
normalsetUp ← FALSE;
FOR layer: CD.Layer IN CD.Layer DO
contextFilter[layer].doit ← (CDProperties.GetPropFromLayer[layer, $CDxInterpressPlot]=$doit)
ENDLOOP;
contextFilter[CD.backGround].doit ← FALSE;
END;
HardCopyCommand: PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["HardCopy\n"];
abortFlag^ ← FALSE;
[] ← CDCommandOps.CallWithResource[
proc: ProtectedHardCopy,
comm: comm,
resource: $CDSimplePlotImpl,
abortFlag: abortFlag
];
END;
ProtectedHardCopy: PROC [comm: CDSequencer.Command] =
--not re-entrant: using a global abort flag (abortFlag)
BEGIN
fileName: Rope.ROPE ← fileNameDefault;
pageNumX: INT ← 1; --number of vertical stripes
pageNumY: INT ← 1; --number of horizontal stripes
nX, nY: INT; --number of current page
borderX, borderY: REAL; --border of page
ref: ImagerInterpress.Ref;
dr: CD.DrawRef;
clip: CD.Rect;
start: CD.Position;
sizePerPage: CD.Position;
scale: REAL;
substituteFonts: BOOL ← FALSE;
deviceTranslation: Imager.VEC ← [0, 0];
PlotPage: PROC [context: Imager.Context] =
--the real stuff
BEGIN
r: CD.Rect ← CDBasics.RectAt[start, sizePerPage];
r ← CDBasics.Intersection[r, clip];
IF ~CDBasics.NonEmpty[r] THEN RETURN;
IF abortFlag^ THEN RETURN;
Imager.TranslateT[context, deviceTranslation];
Imager.ScaleT[context, scale];
Imager.TranslateT[context, [-r.x1, -r.y1]];
Imager.ClipRectangle[context, RectToRectangle[r]];
dr ← CD.CreateDrawRef[comm.design, context];
dr.minimalSize ← 0;
dr.stopFlag ← abortFlag;
dr.contextFilter ← contextFilter;
dr.interestClip ← r;
IF substituteFonts THEN {
dr.b2 ← FALSE;
dr.properties ← Atom.PutPropOnList[dr.properties, $FontExchange, fontReplace];
};
CDOps.DrawDesign[comm.design, dr];
END;
PreAmble: PROC [ref: ImagerInterpress.Ref, contextFilter: REF CD.ContextFilter] =
BEGIN
declared: RefTab.Ref ← RefTab.Create[];
FOR layer: CD.Layer IN CD.Layer DO
IF contextFilter[layer].doit THEN
IF RefTab.Insert[declared, contextFilter[layer].color, contextFilter[layer].color] THEN
ImagerInterpress.DeclareColor[ref, contextFilter[layer].color]
ENDLOOP;
declared ← NIL;
END;
SetUp: PROC [] =
BEGIN
RequestBorder: PROC [anyWay: BOOLFALSE] =
BEGIN
borderY ← borderX ← 0;
IF (anyWay AND ~special) OR TerminalIO.UserSaysYes["border ?"] THEN
borderY ← borderX ← defaultBorder;
END;
SetUpVaryingScaling: PROC [clip: CD.Rect] =
BEGIN
insidePageX, insidePageY: REAL; --what fits in a page without border
IF special AND TerminalIO.UserSaysYes["multiple pages ?"] THEN {
pageNumX ← TerminalIO.RequestInt["Number of pages in x direction? >"];
IF pageNumX<1 OR pageNumX>20 THEN {
TerminalIO.WriteRope[" to bad\n"];
ERROR ABORTED
};
}
ELSE {
pageNumX ← 0;
};
RequestBorder[anyWay: pageNumX=0];
insidePageX ← pageX-2*borderX;
insidePageY ← pageY-2*borderY;
IF pageNumX=0 THEN {
--single page
pageNumY ← 1;
pageNumX ← 1;
sizePerPage ← CDBasics.SizeOfRect[clip];
scale ← MIN[insidePageX/sizePerPage.x, insidePageY/sizePerPage.y];
}
ELSE {
--multiple pages
sizePerPage.x ← (clip.x2-clip.x1)/pageNumX+1;
sizePerPage.y ← Real.Fix[insidePageY*((sizePerPage.x-1.0)/insidePageX)];
scale ← insidePageX/sizePerPage.x;
pageNumY ← ( (clip.y2-clip.y1)+(sizePerPage.y-1) )/sizePerPage.y;
}
END;
SetUpStriped: PROC [clip: CD.Rect] =
BEGIN
borderY ← defaultBorder;
borderX ← 0;
pageNumY ← 1;
IF special AND TerminalIO.UserSaysYes["multiple stripes ?"] THEN {
pageNumX ← TerminalIO.RequestInt["How many stripes? >"];
IF pageNumX<1 OR pageNumX>20 THEN {
TerminalIO.WriteRope[" to bad\n"];
ERROR ABORTED
}
}
ELSE {
pageNumX ← 1;
};
sizePerPage.x ← (clip.x2-clip.x1)/pageNumX;
sizePerPage.y ← clip.y2-clip.y1;
scale ← pageX/sizePerPage.x;
pageY ← scale*sizePerPage.y+2*borderY;
END;
SetUpFixedScaling: PROC [clip: CD.Rect] =
BEGIN
borderAnyway: BOOL;
borderAnyway ←
( (clip.x2-clip.x1)*scale < (pageX - 0.05) ) AND
( (clip.y2-clip.y1)*scale < (pageY - 0.05) );
RequestBorder[borderAnyway];
scale ← defaultScale;
sizePerPage.x ← Real.Round[(pageX-2*borderX)/scale];
sizePerPage.y ← Real.Round[(pageY-2*borderY)/scale];
pageNumX ← (clip.x2-clip.x1+sizePerPage.x-1)/sizePerPage.x;
pageNumY ← (clip.y2-clip.y1+sizePerPage.y-1)/sizePerPage.y;
END;
AdjustPosition: PROC [] =
BEGIN
IF pageNumX=1 THEN {
borderX ← MIN[(pageX - (clip.x2-clip.x1)*scale)/2, defaultBorder];
};
IF pageNumY=1 THEN {
pictureHeight: REAL ← (clip.y2-clip.y1)*scale;
borderY ← MAX[pageY-defaultBorder-pictureHeight, (pageY-pictureHeight)/2];
};
END;
SubstituteFonts: PROC =
BEGIN
SELECT TerminalIO.RequestSelection["substitute fonts ?", LIST["no substitution", "standard substitution file", "user substitution file"]] FROM
2=> {
substituteFonts ← TRUE;
TerminalIO.WriteRope["use standard font substitution file\n"];
fontTab ← InitFontTab[];
};
3 => {
r: Rope.ROPE;
r ← TerminalIO.RequestRope["fullpath name for font substitution file > "];
substituteFonts ← TRUE;
fontTab ← InitFontTab[r];
};
ENDCASE => {
TerminalIO.WriteRope["don't substitute fonts\n"];
substituteFonts ← FALSE;
};
END;
GetClipRect: PROC [comm: CDSequencer.Command] =
BEGIN
clip ← CDBasics.ToRect[comm.pos, comm.sPos];
IF ~CDBasics.NonEmpty[clip] OR ~TerminalIO.UserSaysYes["clip to rectangle ?"] THEN
clip ← CDExtras.BoundingBox[comm.design];
IF clipRect THEN TerminalIO.WriteRope["clip to rectangle\n"]
ELSE TerminalIO.WriteRope["plot complete design\n"];
IF ~CDBasics.NonEmpty[clip] THEN {
TerminalIO.WriteRope["clip rectangle is empty\n"];
ERROR ABORTED
};
END;
GetMedium: PROC [] =
BEGIN
special ← FALSE;
fixedScale ← FALSE;
striped ← FALSE;
SELECT TerminalIO.RequestSelection["Plot", LIST["standard scale", "fill page", "fill versatec stripe", "other"]] FROM
1 => {
fixedScale ← TRUE;
TerminalIO.WriteRope["standard scale\n"];
};
3 => {
striped ← TRUE;
pageX ← defaultStripeX;
TerminalIO.WriteRope["fill versatec stripe\n"];
};
4 => {
TerminalIO.WriteRope["special:\n"];
special ← TRUE;
SELECT TerminalIO.RequestSelection["Plot", LIST["pages", "versatec stripes", "standard scale"]] FROM
1 => {
TerminalIO.WriteRope["standard pages\n"];
};
2 => {
striped ← TRUE;
pageX ← defaultStripeX;
TerminalIO.WriteRope["versatec stripes\n"];
};
3 => {
fixedScale ← TRUE;
TerminalIO.WriteRope["standard scale\n"];
};
ENDCASE => ERROR ABORTED;
};
--2,-- ENDCASE => {
TerminalIO.WriteRope["fill page\n"];
};
END;
special: BOOLFALSE;
clipRect: BOOLFALSE;
fixedScale: BOOLFALSE;
striped: BOOLFALSE;
IF ~normalsetUp THEN {
TerminalIO.WriteRope["** SPECIAL COLORS\n"];
SetUpContextFilter[]
};
pageX ← defaultPageX;
pageY ← defaultPageY;
fontTab ← NIL;
SubstituteFonts[];
GetClipRect[comm];
GetMedium[];
sizePerPage ← CDBasics.SizeOfRect[clip];
IF striped THEN SetUpStriped[clip]
ELSE IF fixedScale THEN SetUpFixedScaling[clip]
ELSE SetUpVaryingScaling[clip];
AdjustPosition[];
TerminalIO.WriteRope[IO.PutFR[" printing %01g rows and %01g columns\n", IO.int[pageNumX], IO.int[pageNumY]]];
END;
SetUp[];
ref ← ImagerInterpress.Create[fileName];
PreAmble[ref, contextFilter];
deviceTranslation ← [borderX, borderY];
FOR nX IN [0..pageNumX) DO
FOR nY IN [0..pageNumY) DO
IF abortFlag^ THEN EXIT;
start.x ← clip.x1+nX*sizePerPage.x;
start.y ← clip.y1+nY*sizePerPage.y;
ImagerInterpress.DoPage[ref, PlotPage];
ENDLOOP;
ENDLOOP;
ImagerInterpress.Close[ref];
TerminalIO.WriteRope[IO.PutFR[" ""%01g"" created\n", IO.rope[fileName]]];
IF ~abortFlag^ THEN TerminalIO.WriteRope[" done\n"];
END;
--************************************************
--Font replacement stuff
fontTab: SymTab.Ref;
wDir: Rope.ROPE;
fontReplace: REF PROC [CDTexts.CDFont] RETURNS [CDTexts.CDFont]
NEW[PROC [CDTexts.CDFont] RETURNS [CDTexts.CDFont] ← FontReplace];
FontReplace: PROC [cdFont: CDTexts.CDFont] RETURNS [CDTexts.CDFont] =
BEGIN
newFont: CDTexts.CDFont ← NIL;
IF cdFont.scaleI=CD.lambda THEN {
x: REF ← SymTab.Fetch[fontTab, cdFont.supposedName].val;
WITH x SELECT FROM
l: LIST OF REF ANY => {
IF l.first#NIL AND l.rest#NIL AND l.rest.rest=NIL THEN {
scale: INT ← 0;
name: Rope.ROPE ← CDExtras.ToRope[l.first];
WITH l.rest.first SELECT FROM
ri: REF INT => scale ← ri^
ENDCASE => NULL;
IF scale>0 AND ~Rope.IsEmpty[name] THEN {
newFont ← CDTexts.MakeFont1[name, scale];
IF newFont#NIL THEN {
x: REF CDTexts.FontRec;
TRUSTED {x ← LOOPHOLE[newFont]};
[] ← SymTab.Store[fontTab, cdFont.supposedName, x];
}
};
}
};
f: CDTexts.CDFont => newFont ← f;
f: REF CDTexts.FontRec => newFont ← f;
ENDCASE => NULL;
};
IF newFont=NIL THEN newFont�ont;
RETURN [newFont]
END;
InitFontTab: PROC [fileName: Rope.ROPENIL] RETURNS [fontTab: SymTab.Ref] =
BEGIN
OneLine: PROC [line: Rope.ROPE] =
BEGIN
stream: IO.STREAMIO.RIS[line];
scale: INT;
subst, by: Rope.ROPE;
subst ← IO.GetRopeLiteral[stream];
by ← IO.GetRopeLiteral[stream];
scale ← IO.GetInt[stream];
[] ← fontTab.Store[subst, LIST[by, NEW[INT←scale]]];
END;
file: IO.STREAMNIL;
fontTab ← SymTab.Create[];
IF Rope.IsEmpty[fileName] THEN fileName ← "CDSubstituteFonts";
fileName ← CDIO.MakeName[base: fileName, ext: "SubstituteFonts", wDir: wDir];
file ← FS.StreamOpen[fileName ! FS.Error => {
TerminalIO.WriteRope["no font substitution: "];
TerminalIO.WriteRope[error.explanation];
TerminalIO.WriteLn[];
GOTO thatsIt
}];
DO
line: Rope.ROPE;
line ← IO.GetLineRope[file ! IO.EndOfStream => GOTO thatsIt];
IF ~Rope.IsEmpty[line] THEN
OneLine[line !
IO.EndOfStream => GOTO thatsIt;
IO.Error => {
TerminalIO.WriteRope["**error reading font substitution: "];
TerminalIO.WriteRope[line];
TerminalIO.WriteLn[];
CONTINUE
};
];
ENDLOOP;
EXITS thatsIt => NULL;
END;
--************************************************
Init: PROC =
BEGIN
wDir ← FileNames.CurrentWorkingDirectory[];
wDir ← CDIO.GetWorkingDirectory[NIL];
ResetContextFilter[ignoreProperties: TRUE];
CDSequencer.ImplementCommand[a: $InterpressPlot, p: HardCopyCommand, queue: doQueue];
CDMenus.CreateEntry[menu: $HardCopyMenu, entry: "b&w interpress", key: $InterpressPlot];
TerminalIO.WriteRope["BW Interpress plot loaded\n"];
END;
Init[];
END.