<> <> <> 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; <> 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.STREAM _ IO.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.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: INTEGER _ LAST[INTEGER]; objectBBox: PROC[leftPart, rightPart: REF ANY] = { IF NARROW[leftPart, REF CARDINAL]^=thisCluster THEN { refObjectId: REF CARDINAL _ NARROW[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]]; <> }; PutPath: PROCEDURE[master: IPOutput.Master, griffinObject: ReadGriffin.ObjectRef, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = { refStyleId: REF CARDINAL _ NEW[CARDINAL _ griffinObject.style]; griffinStyle: ReadGriffin.StyleRef _ NARROW[PairList.Right[ReadGriffin.styleMap, EqualCardinals, refStyleId]]; areaColor, outlineColor: ReadGriffin.ColorRef _ NIL; pathType: ROPE _ NIL; 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 CARDINAL _ NEW[CARDINAL _ griffinObject^.style]; griffinStyle: ReadGriffin.StyleRef _ NARROW[PairList.Right[ReadGriffin.styleMap, EqualCardinals, refStyleId]]; refFontId: REF CARDINAL _ NEW[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: NAT _ SELECT griffinFont.rotation FROM Rot0Degrees => 0, Rot90Degrees => 90, Rot180Degrees => 180, Rot270Degrees => 270, ENDCASE => 0; textRotation: NAT _ SELECT 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: ROPE _ IO.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: BOOLEAN _ FALSE; 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; <> 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"]; }.