GriffinToJaMImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Stone December 10, 1982 1:29 pm
Beach, February 9, 1985 9:51:03 pm PST
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: CEDAR 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: INTEGERLAST[INTEGER];
objectBBox: PROC[leftPart, rightPart: REF ANY] = {
IF NARROW[leftPart, REF CARDINAL]^=thisCluster THEN {
refObjectId: REF CARDINALNARROW[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.PutFR["%% 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.PutFR["%% 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 CARDINALNEW[CARDINAL ← griffinObject^.style];
griffinStyle: StyleRef ← NARROW[PairList.Right[styleMap, EqualCardinals, refStyleId]];
areaColor, outlineColor: ColorRef ← NIL;
pathType: ROPENIL;
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.PutFR["\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
TRUSTED { pathRef ← LOOPHOLE[PairList.Right[pathMap, EqualCardinals, refObjectId]] };
[] ← TextEdit.AppendRope[figureRoot, pathNode,PathToRope[pathRef]];
SELECT pathType FROM
"filled" => [] ← TextEdit.AppendRope[figureRoot, pathNode,
IO.PutFR["%g .drawarea", IO.rope[areaColor.name]]];
"outlined" => [] ← TextEdit.AppendRope[figureRoot, pathNode,
IO.PutFR["%g %g 2 .drawstroke", --2=round ends
IO.rope[outlineColor.name], IO.real[lineWeight]]];
"filled+outlined" => {
[] ← TextEdit.AppendRope[figureRoot, pathNode,
IO.PutFR["%g .drawarea\n", IO.rope[areaColor.name]]];
[] ← TextEdit.AppendRope[figureRoot, pathNode,PathToRope[pathRef]];
[] ← TextEdit.AppendRope[figureRoot, pathNode,
IO.PutFR["%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 CARDINALNEW[CARDINAL ← griffinObject^.style];
griffinStyle: StyleRef ← NARROW[PairList.Right[styleMap, EqualCardinals, refStyleId]];
refFontId: REF CARDINALNEW[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: BOOLEANFALSE;
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.PutFR["\n.pushdc %d %d .translate %d .rotate",
IO.real[caption^.position.x-clusterX],
IO.real[caption^.position.y-clusterY], 
IO.int[textRotation]]];
fontName ← IO.PutFR["(%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.PutFR["%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.PutFR["%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.PutFR["%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.PutFR["%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.PutFR["%f %f %s",
IO.real[b3.x], IO.real[b3.y], IO.rope[" .curveto "]]];
};
CGPath.Generate[path,move,line,curve];
RETURN[rope];
};
}.