GriffinToInterpressImpl.Mesa
Copyright (C) 1984, Xerox Corporation. All rights reserved.
Last Edited by: Michael Plass, August 23, 1984 1:16:27 pm PDT
DIRECTORY
ColorModels,
Commander,
GFileFormatDefs,
CGPath,
Graphics,
GraphicsBasic,
GriffinToInterpress,
IO,
PairList,
ReadGriffin,
Real,
Rope,
IPOutput,
MessageWindow, RealFns;
GriffinToInterpressImpl: CEDAR PROGRAM
IMPORTS ColorModels, CGPath, Commander, IO, PairList, ReadGriffin, Rope, Real, IPOutput, MessageWindow, RealFns
EXPORTS GriffinToInterpress = {
ROPE: TYPE = Rope.ROPE;
topScreenCoord: INTEGER = 808;
Griffin Font definitions taken from GriffinFontDefs
Regular: CARDINAL = 0;
Italic: CARDINAL = 1;
Bold: CARDINAL = 2;
BoldItalic: CARDINAL = Bold + Italic;
Rot0Degrees: CARDINAL = 0;
Rot90Degrees: CARDINAL = 5400;
Rot180Degrees: CARDINAL = 10800;
Rot270Degrees: CARDINAL = 16200;
ViewType: TYPE = {main, alternate, both};
GriffinToInterpressCommand: Commander.CommandProc ~ {
fileName: ROPE;
ipFileName: ROPE;
stream: IO.STREAMIO.RIS[cmd.commandLine];
FileNameBreakProc: PROC [char: CHAR] RETURNS [IO.CharClass] = {
IF char = ' OR char = '  OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
fullColor ← FALSE;
WHILE NOT IO.EndOf[stream] DO
fileName ← NIL;
fileName ← IO.GetTokenRope[stream, FileNameBreakProc ! IO.EndOfStream => CONTINUE].token;
IF fileName # NIL THEN {
IF fileName.Equal["-c", FALSE] THEN fullColor ← TRUE
ELSE{
cmd.out.PutRope[IO.PutFR["Converting %g to Interpress . . . ", IO.rope[fileName]]];
ReadGriffin.ConvertFile[fileName ! ReadGriffin.GriffinFileError => {msg ← why; GOTO FileProblem}];
ipFileName ← ReadGriffin.FixFileName[fileName, ".interpress"];
PutClustersToFile[ipFileName! Unimplemented => {cmd.out.PutRope[rope]; RESUME}];
cmd.out.PutRope[IO.PutFR["into %g\n", IO.rope[ipFileName]]];
};
};
ENDLOOP;
EXITS
FileProblem => RETURN[$Failure, msg];
};
PutClustersToFile: PUBLIC PROCEDURE [fileName: ROPE] = {
figureName: ROPE ← Rope.Substr[fileName, 0, Rope.Find[fileName, "."]];
master: IPOutput.Master ← IPOutput.BeginMaster[fileName];
IPOutput.BeginPreamble[master];
-- font stuff goes here
IF fullColor THEN {
IPOutput.PutInt[master, 0]; -- swhite
IPOutput.PutInt[master, 3000]; -- sblack
IPOutput.PutInt[master, 0];
IPOutput.PutInt[master, 3];
IPOutput.MakeVec[master, 4];
IPOutput.PutName[master, "standard/ColorDensity"];
IPOutput.PutOp[master, findcolormodeloperator];
IPOutput.Do[master];
IPOutput.FSet[master, 1];
};
IPOutput.EndPreamble[master];
IPOutput.BeginPage[master];
PutClusters[master];
IPOutput.EndPage[master];
IPOutput.EndMaster[master];
};
PutClusters: PUBLIC PROCEDURE [master: IPOutput.Master] ~ {
clusterNumber: CARDINAL ← 0;
IPOutput.BeginDoSaveSimpleBody[master];
-- set up transformation, priorityimportant, strokeends
IPOutput.TranslateT[master, 0, topScreenCoord];
IPOutput.Scale2T[master, 0.0254/72, 0.0254/72];
IPOutput.SetPriorityImportant[master, TRUE];
IPOutput.SetStrokeEnd[master, round];
FOR thisCluster: CARDINAL IN [ReadGriffin.firstCluster..ReadGriffin.lastCluster] DO
clusterX, clusterY: INTEGERLAST[INTEGER];
objectBBox: PROC[leftPart, rightPart: REF ANY] = {
IF NARROW[leftPart, REF CARDINAL]^=thisCluster THEN {
refObjectId: REF CARDINALNARROW[rightPart];
griffinObject: ReadGriffin.ObjectRef ← NARROW[PairList.Right[ReadGriffin.objectMap, EqualCardinals, refObjectId]];
clusterX ← MIN[clusterX, griffinObject.bleft];
clusterY ← MIN[clusterY, topScreenCoord-griffinObject.bbottom];
};
};
doObject: PROC[leftPart, rightPart: REF ANY] = {
IF NARROW[leftPart, REF CARDINAL]^=thisCluster THEN {
PutObjectNode[master, NARROW[rightPart, REF CARDINAL], clusterX, clusterY]
};
};
PairList.ForAllPairs[ReadGriffin.clusterMap, objectBBox];
IPOutput.BeginDoSaveSimpleBody[master];
IPOutput.TranslateT[master, clusterX,clusterY];
PairList.ForAllPairs[ReadGriffin.clusterMap, doObject];
IPOutput.EndDoSaveSimpleBody[master];
ENDLOOP;
IPOutput.EndDoSaveSimpleBody[master];
};
PutObjectNode: PROCEDURE[master: IPOutput.Master, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = {
griffinObject: ReadGriffin.ObjectRef ← NARROW[PairList.Right[ReadGriffin.objectMap, EqualCardinals, refObjectId]];
IPOutput.PutString[master, "Object"];
IPOutput.PutInt[master, refObjectId^];
IPOutput.Pop[master];
IPOutput.Pop[master];
SELECT griffinObject.objtype FROM
GFileFormatDefs.typeCurveObject,
GFileFormatDefs.typeAreaObject =>
PutPath[master, griffinObject, refObjectId, clusterX, clusterY];
GFileFormatDefs.typeCaptionObject =>
PutCaption[master, griffinObject, refObjectId, clusterX, clusterY];
ENDCASE => MessageWindow.Append["Unknown object type . . . ", FALSE];
};
NarrowToPathRef: PROCEDURE [ref: REF] RETURNS [ReadGriffin.PathRef] ~ TRUSTED {
RETURN [LOOPHOLE[ref]];
can't use a NARROW as pathRef is opaque, and that construct is not implemented
};
PutPath: PROCEDURE[master: IPOutput.Master, griffinObject: ReadGriffin.ObjectRef, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = {
refStyleId: REF CARDINALNEW[CARDINAL ← griffinObject.style];
griffinStyle: ReadGriffin.StyleRef ← NARROW[PairList.Right[ReadGriffin.styleMap, EqualCardinals, refStyleId]];
areaColor, outlineColor: ReadGriffin.ColorRef ← NIL;
pathType: ROPENIL;
lineWeight: REAL ← 0;
pathRef: ReadGriffin.PathRef ← NarrowToPathRef[PairList.Right[ReadGriffin.pathMap, EqualCardinals, refObjectId]];
IPOutput.BeginDoSaveSimpleBody[master];
IPOutput.TranslateT[master, griffinObject.bleft-clusterX, topScreenCoord-griffinObject.bbottom-clusterY];
IF griffinStyle.afilled OR griffinStyle.aoutlined OR griffinObject.objtype = GFileFormatDefs.typeAreaObject THEN {
nTrajectories: INT ← PutGriffinTrajectories[master, pathRef];
filled: BOOLEAN ← griffinObject.objtype = GFileFormatDefs.typeAreaObject AND griffinStyle.afilled;
outlined: BOOLEAN ← (griffinObject.objtype = GFileFormatDefs.typeAreaObject AND griffinStyle.aoutlined) OR griffinObject.objtype = GFileFormatDefs.typeCurveObject;
open: BOOLEAN ← griffinObject.objtype = GFileFormatDefs.typeCurveObject;
IF filled AND outlined THEN {
IPOutput.Copy[master, nTrajectories];
};
IF filled THEN {
IPOutput.MakeOutline[master, nTrajectories];
SetColor[master, griffinStyle.ahue, griffinStyle.asaturation, griffinStyle.abrightness];
IPOutput.MaskFill[master];
};
IF outlined THEN {
lineWeight: REAL ← ScalePressToScreenCoord[griffinStyle^.thickness];
SetColor[master, griffinStyle.hue, griffinStyle.saturation, griffinStyle.brightness];
-- should be round stroke ends
IPOutput.SetStrokeWidth[master, lineWeight];
FOR i: INT IN [0..nTrajectories) DO
IF open THEN IPOutput.MaskStroke[master]
ELSE IPOutput.MaskStrokeClosed[master];
ENDLOOP;
};
};
IPOutput.EndDoSaveSimpleBody[master];
};
PutCaption: PROCEDURE [master: IPOutput.Master, griffinObject: ReadGriffin.ObjectRef, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = {
caption: ReadGriffin.CaptionRef ← NARROW[PairList.Right[ReadGriffin.captionMap, EqualCardinals, refObjectId]];
refStyleId: REF CARDINALNEW[CARDINAL ← griffinObject^.style];
griffinStyle: ReadGriffin.StyleRef ← NARROW[PairList.Right[ReadGriffin.styleMap, EqualCardinals, refStyleId]];
refFontId: REF CARDINALNEW[CARDINAL ← griffinStyle^.fontid];
griffinFont: ReadGriffin.FontRef ← NARROW[PairList.Right[ReadGriffin.fontMap, EqualCardinals, refFontId]];
ix: NAT ← 0; FetchChar: PROC RETURNS [CHAR] ~ {RETURN [griffinFont.char[ix ← ix+1]]};
family: ROPE ← Rope.FromProc[ORD[griffinFont.char[0]], FetchChar];
face: ROPE ← SELECT griffinFont.face FROM
Regular => "MRR",
Italic => "MIR",
Bold => "BRR",
BoldItalic => "BIR",
ENDCASE=> "MRR";
charRotation: NATSELECT griffinFont.rotation FROM
Rot0Degrees => 0,
Rot90Degrees => 90,
Rot180Degrees => 180,
Rot270Degrees => 270,
ENDCASE => 0;
textRotation: NATSELECT griffinStyle.torient FROM
GFileFormatDefs.typeRot0 => 0,
GFileFormatDefs.typeRot90 => 90,
GFileFormatDefs.typeRot180 => 180,
GFileFormatDefs.typeRot270 => 270,
ENDCASE => 0;
anchor: {flushLeft, centered, flushRight} ← SELECT griffinStyle.anchor FROM
GFileFormatDefs.typeLeftAnchor => flushLeft,
GFileFormatDefs.typeCenterAnchor => centered,
GFileFormatDefs.typeRightAnchor => flushRight,
ENDCASE => flushLeft;
size: REAL ← griffinFont.points;
fontName: ROPEIO.PutFR["xerox/pressfonts/%g-%g", IO.rope[family], IO.rope[face]];
IPOutput.FindFont[master, fontName];
IPOutput.Scale2[master, size, size];
IPOutput.ModifyFont[master];
IPOutput.FSet[master, 0];
IPOutput.SetFont[master, 0];
SetColor[master, griffinStyle.hue, griffinStyle.saturation, griffinStyle.brightness];
IPOutput.SetXY[master, caption^.position.x-clusterX, caption^.position.y-clusterY];
IF textRotation#charRotation THEN SIGNAL Unimplemented["Warning: Char/text rotation combination not supported "];
IPOutput.BeginDoSaveSimpleBody[master];
IF textRotation#0 THEN {
IPOutput.Rotate[master, textRotation];
IPOutput.ConcatT[master];
};
IF anchor # flushLeft THEN {
IF anchor = centered THEN IPOutput.Scale2[master, -0.5, 0.5]
ELSE IF anchor = flushRight THEN IPOutput.Scale2[master, -1, 1];
IPOutput.ConcatT[master];
IPOutput.IGet[master, noImage];
IPOutput.PutInt[master, 1];
IPOutput.ISet[master, noImage];
IPOutput.Show[master, caption.text];
IPOutput.ISet[master, noImage];
IF anchor = centered THEN IPOutput.Scale2[master, -2, 2]
ELSE IF anchor = flushRight THEN IPOutput.Scale2[master, -1, 1];
IPOutput.ConcatT[master];
};
IPOutput.SetYRel[master, -size];
IPOutput.Show[master, caption.text];
IPOutput.EndDoSaveSimpleBody[master];
};
Unimplemented: PUBLIC SIGNAL [rope: ROPE] ~ CODE;
PutGriffinTrajectories: PROC [master: IPOutput.Master, path: ReadGriffin.PathRef] RETURNS [nTrajectories: INT ← 0] = {
move: SAFE PROC[p: GraphicsBasic.Vec] = CHECKED {
nTrajectories ← nTrajectories + 1;
IPOutput.MoveTo[master, p.x, p.y];
};
line: SAFE PROC[p: GraphicsBasic.Vec] = CHECKED {
IPOutput.LineTo[master, p.x, p.y];
};
curve: SAFE PROC[b1, b2, b3: GraphicsBasic.Vec] = CHECKED {
IPOutput.CurveTo[master, b1.x, b1.y, b2.x, b2.y, b3.x, b3.y];
};
CGPath.Generate[path,move,line,curve];
};
fullColor: BOOLEANFALSE;
calibration: ColorModels.Calibration ← ColorModels.GetPhosphorCalibration[$DefaultLP];
SetColor: PROC [master: IPOutput.Master, hue, saturation, brightness: REAL] ~ {
r, g, b: REAL;
x, y, Y: REAL;
[r, g, b] ← ColorModels.HSVToRGB[hue/255.0, saturation/255.0, brightness/255.0];
[x, y, Y] ← ColorModels.RGBToCIE[r, g, b, calibration];
IF NOT fullColor THEN IPOutput.SetGray[master, 1.0-Y]
ELSE {
redDensity: REAL ← -RealFns.Log[10, MAX[r, 0.001]];
greenDensity: REAL ← -RealFns.Log[10, MAX[g, 0.001]];
blueDensity: REAL ← -RealFns.Log[10, MAX[b, 0.001]];
IPOutput.PutInt[master, Real.RoundLI[redDensity*1000]];
IPOutput.PutInt[master, Real.RoundLI[greenDensity*1000]];
IPOutput.PutInt[master, Real.RoundLI[blueDensity*1000]];
IPOutput.MakeVec[master, 3];
IPOutput.FGet[master, 1];
IPOutput.Do[master];
IPOutput.ISet[master, color]
};
};
EqualCardinals: PairList.EqualProc ~ {
l, r: CARDINAL;
return ← FALSE;
if not a cardinal, will signal out
l ← NARROW[left,REF CARDINAL]^; r ← NARROW[right,REF CARDINAL]^;
IF l=r THEN return ← TRUE;
};
FindColor: PROCEDURE [h, s, b: REAL] RETURNS [ReadGriffin.ColorRef] ~ {
c: ReadGriffin.ColorRef ← ReadGriffin.colors;
MatchColor: PROCEDURE[c: ReadGriffin.ColorRef, h, s, b: REAL] RETURNS[BOOLEAN] = INLINE {
RETURN[c#NIL AND c.h=h AND c.s=s AND c.b=b]};
MakeColorName: PROCEDURE[n: CARDINAL] RETURNS[ROPE] = INLINE {
RETURN[IO.PutFR["Color%d", IO.card[n]]]};
WHILE c#NIL DO
IF MatchColor[c, h, s, b] THEN RETURN[c];
c ← c.next;
ENDLOOP;
ERROR;
};
ScalePressToScreenCoord: PROCEDURE [a: REAL] RETURNS[INTEGER] ~ INLINE {
RETURN[Real.RoundI[a*0.03125]]};
Commander.Register[key: "GriffinToInterpress", proc: GriffinToInterpressCommand, doc: "convert a given Griffin file into equivalent Interpress file"];
}.