<< --GriffinToJaMImpl.mesa --- Stone December 10, 1982 1:29 pm>> DIRECTORY GFileFormatDefs, GriffinToTA, GriffinToTANodes, GriffinToTAPrivate, GriffinToJaM, IO, PairList, PutGet USING [WriteFilePlain], Rope, SplineDefs, StyleDefs, TextEdit USING [AppendRope, DocFromNode, FromRope], TextNode USING [Ref, RefTextNode], GraphicsBasic USING [Vec], CGPath USING [Generate]; GriffinToJaMImpl: PROGRAM IMPORTS GriffinToTA, GriffinToTAPrivate, IO, PairList, PutGet, Rope, TextEdit, CGPath EXPORTS GriffinToJaM = { OPEN GriffinToTA, GriffinToTAPrivate; 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; PutClusters: PUBLIC PROCEDURE[fileName: ROPE] = { thisCluster: CARDINAL; clusterNumber: CARDINAL _ 0; figureName: ROPE _ Rope.Substr[fileName, 0, Rope.Find[fileName, "."]]; figureRoot: TextNode.Ref; figureNode, clusterNode: TextNode.RefTextNode; clusterX, clusterY: INTEGER _ LAST[INTEGER]; objectBBox: PROC[leftPart, rightPart: REF ANY] = { IF NARROW[leftPart, REF CARDINAL]^=thisCluster THEN { refObjectId: REF CARDINAL _ NARROW[rightPart]; griffinObject: ObjectRef _ NARROW[PairList.Right[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 { IF clusterNode=NIL THEN { clusterNumber _ clusterNumber+1; clusterNode _ PutClusterNode[figureRoot, figureNode, clusterNumber, clusterX, clusterY]}; PutObjectNode[figureRoot, clusterNode, NARROW[rightPart, REF CARDINAL], clusterX, clusterY]}; }; figureNode _ PutFigureNode[figureName]; figureRoot _ TextEdit.DocFromNode[figureNode]; FOR thisCluster IN [firstCluster .. lastCluster] DO clusterNode _ NIL; clusterX _ clusterY _ LAST[INTEGER]; PairList.ForAllPairs[clusterMap, objectBBox]; PairList.ForAllPairs[clusterMap, doObject]; IF clusterNode#NIL THEN PutPopNode[figureRoot, clusterNode]; ENDLOOP; [] _ PutGet.WriteFilePlain[fileName, figureRoot]; }; PutFigureNode: PROCEDURE[figureName: ROPE] RETURNS[node: TextNode.RefTextNode] = { rope: ROPE _ Rope.Cat["% Tioga Artwork figure for ", figureName]; node _ TextEdit.FromRope[rope]; RETURN[node]; }; PutClusterNode: PROCEDURE[figureRoot: TextNode.Ref, figureNode: TextNode.RefTextNode, cluster: CARDINAL, clusterX, clusterY: INTEGER] RETURNS[node: TextNode.RefTextNode] = { node _ InsertNodeAfterChildrenOf[figureNode]; [] _ TextEdit.AppendRope[figureRoot, node, IO.PutFToRope["%% Cluster %d\n.pushdc %d %d .translate", IO.card[cluster], IO.int[clusterX], IO.int[clusterY]]]; RETURN[node]; }; PutPopNode: PROCEDURE[figureRoot: TextNode.Ref, clusterNode: TextNode.RefTextNode] = { popNode: TextNode.RefTextNode _ InsertNodeAfterChildrenOf[clusterNode]; [] _ TextEdit.AppendRope[figureRoot, popNode, ".popdc"]; }; PutObjectNode: PROCEDURE[figureRoot: TextNode.Ref, clusterNode: TextNode.RefTextNode, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = { griffinObject: ObjectRef _ NARROW[PairList.Right[objectMap, EqualCardinals, refObjectId]]; objectNode: TextNode.RefTextNode _ InsertNodeAfterChildrenOf[clusterNode]; [] _ TextEdit.AppendRope[figureRoot, objectNode, IO.PutFToRope["%% Object %d", IO.card[refObjectId^]]]; SELECT griffinObject^.objtype FROM GFileFormatDefs.typeCurveObject, GFileFormatDefs.typeAreaObject => PutPathNode[figureRoot, objectNode, griffinObject, refObjectId, clusterX, clusterY]; GFileFormatDefs.typeCaptionObject => PutCaptionNode[figureRoot, objectNode, griffinObject, refObjectId, clusterX, clusterY]; ENDCASE; }; PutPathNode: PROCEDURE[figureRoot: TextNode.Ref, objectNode: TextNode.RefTextNode, griffinObject: ObjectRef, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = { pathNode: TextNode.RefTextNode _ InsertNodeAfterChildrenOf[objectNode]; refStyleId: REF CARDINAL _ NEW[CARDINAL _ griffinObject^.style]; griffinStyle: StyleRef _ NARROW[PairList.Right[styleMap, EqualCardinals, refStyleId]]; areaColor, outlineColor: ColorRef _ NIL; pathType: ROPE _ NIL; lineWeight: REAL _ 0; pathRef: PathRef; SELECT griffinObject^.objtype FROM GFileFormatDefs.typeAreaObject => { IF griffinStyle^.afilled THEN { areaColor _ FindColor[griffinStyle^.ahue, griffinStyle^.asaturation, griffinStyle^.abrightness]; pathType _ "filled"}; IF griffinStyle^.aoutlined THEN { outlineColor _ FindColor[griffinStyle^.hue, griffinStyle^.saturation, griffinStyle^.brightness]; pathType _ IF griffinStyle^.afilled THEN "filled+outlined" ELSE "outlined"; lineWeight _ GriffinToTAPrivate.ScalePressToScreenCoord[griffinStyle^.thickness]}}; GFileFormatDefs.typeCurveObject => { outlineColor _ FindColor[griffinStyle^.hue, griffinStyle^.saturation, griffinStyle^.brightness]; pathType _ "outlined"; lineWeight _ GriffinToTAPrivate.ScalePressToScreenCoord[griffinStyle^.thickness]}; ENDCASE; [] _ TextEdit.AppendRope[figureRoot, objectNode, IO.PutFToRope["\n.pushdc %d %d .translate", IO.int[griffinObject^.bleft-clusterX], IO.int[topScreenCoord-griffinObject^.bbottom-clusterY]]]; --can't use a NARROW as pathRef is opaque, and that construct is not implemented --this should be pretty safe pathRef _ LOOPHOLE[PairList.Right[pathMap, EqualCardinals, refObjectId]]; [] _ TextEdit.AppendRope[figureRoot, pathNode,PathToRope[pathRef]]; SELECT pathType FROM "filled" => [] _ TextEdit.AppendRope[figureRoot, pathNode, IO.PutFToRope["%g .drawarea", IO.rope[areaColor.name]]]; "outlined" => [] _ TextEdit.AppendRope[figureRoot, pathNode, IO.PutFToRope["%g %g 2 .drawstroke", --2=round ends IO.rope[outlineColor.name], IO.real[lineWeight]]]; "filled+outlined" => { [] _ TextEdit.AppendRope[figureRoot, pathNode, IO.PutFToRope["%g .drawarea\n", IO.rope[areaColor.name]]]; [] _ TextEdit.AppendRope[figureRoot, pathNode,PathToRope[pathRef]]; [] _ TextEdit.AppendRope[figureRoot, pathNode, IO.PutFToRope["%g %g 2 .drawstroke", --2=round ends IO.rope[outlineColor.name], IO.real[lineWeight]]]; }; ENDCASE => ERROR; [] _ TextEdit.AppendRope[figureRoot, pathNode, " .popdc"]; }; PutCaptionNode: PROCEDURE[figureRoot: TextNode.Ref, objectNode: TextNode.RefTextNode, griffinObject: ObjectRef, refObjectId: REF CARDINAL, clusterX, clusterY: INTEGER] = { captionNode: TextNode.RefTextNode _ InsertNodeAfterChildrenOf[objectNode]; caption: CaptionRef _ NARROW[PairList.Right[captionMap, EqualCardinals, refObjectId]]; refStyleId: REF CARDINAL _ NEW[CARDINAL _ griffinObject^.style]; griffinStyle: StyleRef _ NARROW[PairList.Right[styleMap, EqualCardinals, refStyleId]]; refFontId: REF CARDINAL _ NEW[CARDINAL _ griffinStyle^.fontid]; griffinFont: FontRef _ NARROW[PairList.Right[fontMap, EqualCardinals, refFontId]]; family, face, charRotation, lineFormatting: ROPE; fontName: ROPE; size: REAL; textRotation: INTEGER; textColor: ColorRef; i: CARDINAL; bold, italic: BOOLEAN _ FALSE; FOR i IN [1 .. LOOPHOLE[griffinFont^.char[0],CARDINAL]] DO family _ Rope.Cat[family, Rope.FromChar[griffinFont^.char[i]]]; ENDLOOP; size _ griffinFont^.points; SELECT griffinFont^.face FROM Regular => face _ "regular"; Italic => {face _ "italic"; italic _ TRUE}; Bold => {face _ "bold"; bold _ TRUE}; BoldItalic => {face _ "bold+italic"; bold _ TRUE; italic _ TRUE}; ENDCASE=> face _ "regular"; charRotation _ SELECT griffinFont^.rotation FROM Rot0Degrees => "0", Rot90Degrees => "90", Rot180Degrees => "180", Rot270Degrees => "270", ENDCASE => "0"; lineFormatting _ SELECT griffinStyle^.anchor FROM GFileFormatDefs.typeLeftAnchor => "flushLeft", GFileFormatDefs.typeCenterAnchor => "centered", GFileFormatDefs.typeRightAnchor => "flushRight", ENDCASE => "flushLeft"; textRotation _ SELECT griffinStyle^.torient FROM GFileFormatDefs.typeRot0 => 0, GFileFormatDefs.typeRot90 => 90, GFileFormatDefs.typeRot180 => 180, GFileFormatDefs.typeRot270 => 270, ENDCASE => 0; textColor _ FindColor[griffinStyle^.hue, griffinStyle^.saturation, griffinStyle^.brightness]; [] _ TextEdit.AppendRope[figureRoot, objectNode, IO.PutFToRope["\n.pushdc %d %d .translate %d .rotate", IO.real[caption^.position.x-clusterX], IO.real[caption^.position.y-clusterY], IO.int[textRotation]]]; fontName _ IO.PutFToRope["(%g%g",IO.rope[family],IO.real[size]]; fontName _ Rope.Cat[fontName, (SELECT face FROM "italic" => "I", "bold" => "B", "bold+italic" => "BI", ENDCASE=> NIL), ".ks)"]; [] _ TextEdit.AppendRope[figureRoot, captionNode, IO.PutFToRope["%g .setfont topEdge %g (%g) %g 0 0 .setcp .drawtext .popdc", IO.rope[fontName],IO.rope[textColor.name], IO.rope[caption^.text],IO.rope[lineFormatting]]]; }; PathToRope: PROC [path: PathRef] RETURNS [ROPE] = { rope: ROPE; move: SAFE PROC[p: GraphicsBasic.Vec] = CHECKED { rope _ Rope.Cat[rope,IO.PutFToRope["%f %f %s ", IO.real[p.x], IO.real[p.y], IO.rope[" .moveto "]]]; }; line: SAFE PROC[p: GraphicsBasic.Vec] = CHECKED { rope _ Rope.Cat[rope,IO.PutFToRope["%f %f %s ", IO.real[p.x], IO.real[p.y], IO.rope[" .lineto "]]]; }; curve: SAFE PROC[b1,b2,b3: GraphicsBasic.Vec] = CHECKED { rope _ Rope.Cat[rope, IO.PutFToRope["%f %f %f %f ", IO.real[b1.x], IO.real[b1.y], IO.real[b2.x], IO.real[b2.y]]]; rope _ Rope.Cat[rope, IO.PutFToRope["%f %f %s", IO.real[b3.x], IO.real[b3.y], IO.rope[" .curveto "]]]; }; CGPath.Generate[path,move,line,curve]; RETURN[rope]; }; }.