DIRECTORY Basics USING [BytePair, CompareCard, Comparison], CubicSplines USING [SplineType, KnotSequence, KnotSequenceRec, MakeSpline, X, Y], CubicPaths USING [Path, EnumeratePath, PathFromCubic], FS USING [ComponentPositions, ExpandName, StreamOpen], GFileFormatDefs, GriffinImageUtils, Imager USING [Context, DoSaveAll, Error, Font, MaskFillTrajectory, MaskStrokeTrajectory, micasPerPoint, Move, RotateT, SetColor, SetFont, SetStrokeWidth, SetXRel, SetXY, SetYRel, ShowRope], ImagerColor USING [ColorFromRGB, RGBFromHSV], ImagerFont USING [Find, RopeWidth, Scale], ImagerPath USING [LineTo, MoveTo, CurveTo, Trajectory, MoveToProc, CurveToProc], IO USING [GetBlock, GetChar, SetIndex, STREAM], MessageWindow USING [Append], PrincOpsUtils USING [LongCopy], RealConvert USING [Mesa5ToIeee], RedBlackTree USING [Create, Insert, Lookup, Table], Rope USING [Cat, Compare, Equal, FromProc, FromRefText, Substr]; GriffinImageUtilsImpl: CEDAR MONITOR IMPORTS Basics, CubicSplines, CubicPaths, FS, IO, Imager, ImagerColor, ImagerFont, ImagerPath, MessageWindow, PrincOpsUtils, RealConvert, RedBlackTree, Rope EXPORTS GriffinImageUtils ~ BEGIN OPEN GriffinImageUtils; SplineType: TYPE ~ CubicSplines.SplineType; ReadGriffinImage: PUBLIC ENTRY PROC [name: ROPE] RETURNS [g: GriffinImage] ~ TRUSTED { ENABLE UNWIND => NULL; Name: UNSAFE PROC [chars: PACKED ARRAY [0 .. GFileFormatDefs.cNameChars] OF CHARACTER] RETURNS [rope: ROPE _ NIL] ~ { GetChar: PROC RETURNS [c: CHAR] ~ CHECKED { index _ index+1; c _ chars[index]; }; len, index: CARDINAL _ 0; len _ LOOPHOLE[chars[0], CARDINAL]; rope _ Rope.FromProc[len, GetChar]; }; diskHandle: IO.STREAM; gHeader: GFileFormatDefs.GFileHeader; name _ FixFileName[name, ".griffin"]; diskHandle _ FS.StreamOpen[name]; gHeader _ ReadHeader[diskHandle]; --Set up header info g _ NEW[GriffinImageRep[gHeader.numfigs]]; --Create top level structure g.header _ NEW[HeaderRep _ [ majorVersion: gHeader.majversion, minorVersion: gHeader.minversion, creatorName: Name[gHeader.creatorname], portfolioName: Name[gHeader.portfolioname], createTime: LOOPHOLE[gHeader.createtime] ]]; FOR figure: CARDINAL IN [1..g.nFigures) DO ReadFigure[g, figure, diskHandle, gHeader]; ENDLOOP; }; ConvertRealFromMesa5: PROC [in: REAL] RETURNS [REAL] ~ { RETURN [RealConvert.Mesa5ToIeee[LOOPHOLE[in]]]; }; ConvertRealFromReal: PROC [in: REAL] RETURNS [REAL] ~ { RETURN [in] }; ConvertReal: PROC [in: REAL] RETURNS [REAL]; ReadFigure: INTERNAL PROC [g: GriffinImage, f: CARDINAL, diskHandle: IO.STREAM, gHeader: GFileFormatDefs.GFileHeader] ~ TRUSTED { figureName: GFileFormatDefs.GFileFigureName; hControl: GFileFormatDefs.GFileHardcopyController; dControl: GFileFormatDefs.GFileDisplayController; ReadFigureInformation: INTERNAL PROC ~ TRUSTED { MoveToSector[diskHandle, gHeader.figure[f]]; ReadStructure[diskHandle, @figureName, GFileFormatDefs.lGFileFigureName]; ReadStructure[diskHandle, @hControl, GFileFormatDefs.lGFileHardcopyController]; ReadStructure[diskHandle, @dControl, GFileFormatDefs.lGFileDisplayController]; }; ConvertDisplayController: INTERNAL PROC [d: GFileFormatDefs.GFileDisplayController] RETURNS [DisplayController] ~ TRUSTED { RETURN [[ centerX: d.centerx, centerY: d.centery, width: d.width, height: d.height, xScale: ConvertReal[d.xscale], yScale: ConvertReal[d.yscale], gridXo: ConvertReal[d.gridxo], gridYo: ConvertReal[d.gridyo], gridSize: d.gridsize, pairs: NIL ]]; }; ConvertHardcopyController: INTERNAL PROC [h: GFileFormatDefs.GFileHardcopyController] RETURNS [GFileFormatDefs.GFileHardcopyController] ~ CHECKED { RETURN [[ centerx: ConvertReal[h.centerx], centery: ConvertReal[h.centery], width: ConvertReal[h.width], height: ConvertReal[h.height], presscenterx: h.presscenterx, presscentery: h.presscentery, scale: ConvertReal[h.scale] ]]; }; Name: INTERNAL PROC [chars: PACKED ARRAY [0 .. GFileFormatDefs.figureNameChars] OF CHARACTER] RETURNS [rope: ROPE _ NIL] ~ CHECKED { GetChar: PROC RETURNS [c: CHAR] ~ CHECKED { index _ index+1; c _ chars[index]; }; len, index: CARDINAL _ 0; len _ LOOPHOLE[chars[0], CARDINAL]; rope _ Rope.FromProc[len, GetChar]; }; font: FontDir; styles: Styles; objects: Objects; g.figures[f] _ NEW[FigureRep]; ReadFigureInformation[]; font _ ReadFontDir[diskHandle]; styles _ ReadStyles[diskHandle]; objects _ ReadObjects[diskHandle]; g.figures[f]^ _ [ font: font, styles: styles, objects: objects, display: ConvertDisplayController[dControl], hardcopy: ConvertHardcopyController[hControl], name: Name[figureName] ]; }; ReadFontDir: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [font: FontDir] ~ UNCHECKED { nFonts: CARDINAL ~ ReadCardinal[diskHandle]; font _ NEW[FontDirRep[nFonts]]; FOR f: CARDINAL IN [0..nFonts) DO font[f] _ ReadFont[diskHandle]; ENDLOOP; }; ReadFont: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [f: Font] ~ UNCHECKED { Name: INTERNAL PROC [chars: PACKED ARRAY [0 .. GFileFormatDefs.fontChars] OF CHARACTER] RETURNS [rope: ROPE _ NIL] ~ CHECKED { GetChar: PROC RETURNS [c: CHAR] ~ CHECKED { index _ index+1; c _ chars[index]; }; len, index: CARDINAL _ 0; len _ LOOPHOLE[chars[0], CARDINAL]; rope _ Rope.FromProc[len, GetChar]; }; font: REF GFileFormatDefs.GFileFont _ NEW[GFileFormatDefs.GFileFont]; ReadStructure[diskHandle, LOOPHOLE[font], GFileFormatDefs.lGFileFont]; f _ [ points: font.points, face: font.face, rotation: font.rotation, name: Name[font.char] ]; }; ReadStyles: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [styles: Styles] ~ UNCHECKED { styleCount: CARDINAL _ ReadCardinal[diskHandle]; styles _ NEW[StylesRep[styleCount]]; FOR style: CARDINAL IN [0..styles.nStyles) DO styles[style] _ ReadStyle[diskHandle]; ENDLOOP; }; ReadStyle: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [style: Style] ~ UNCHECKED { MakeEnd: INTERNAL PROC [endType: CARDINAL, dx, dy, a, b, c: REAL] RETURNS [End] ~ CHECKED { RETURN [[ type: LOOPHOLE[endType], dx: ConvertReal[dx], dy: ConvertReal[dy], a: ConvertReal[a], b: ConvertReal[b], c: ConvertReal[c] ]] }; Name: INTERNAL PROC [chars: PACKED ARRAY [0 .. GFileFormatDefs.sNameChars] OF CHARACTER] RETURNS [rope: ROPE _ NIL] ~ CHECKED { GetChar: PROC RETURNS [c: CHAR] ~ CHECKED { index _ index+1; c _ chars[index]; }; len, index: CARDINAL _ 0; len _ LOOPHOLE[chars[0], CARDINAL]; rope _ Rope.FromProc[len, GetChar]; }; s: REF GFileFormatDefs.GFileStyle _ NEW[GFileFormatDefs.GFileStyle]; ReadStructure[diskHandle, LOOPHOLE[s], GFileFormatDefs.lGFileStyle]; style _ NEW[StyleRep]; style^ _ [ color: [hue: s.hue, saturation: s.saturation, brightness: s.brightness], areaColor: [hue: s.ahue, saturation: s.asaturation, brightness: s.abrightness], textBackgroundColor: [hue: s.bhue, saturation: s.bsaturation, brightness: s.bbrightness], fillArea: s.afilled, outlineArea: s.aoutlined, useTextBackground: s.background, beginning: MakeEnd[s.send, s.bdx, s.bdy, s.ba, s.bb, s.bc], end: MakeEnd[s.eend, s.edx, s.edy, s.ea, s.eb, s.ec], thickness: ConvertReal[s.thickness], font: s.fontid-1, --???? dashedness: s.dashedness, anchor: LOOPHOLE[s.anchor], junction: LOOPHOLE[s.junction], textRotation: LOOPHOLE[s.torient], styleName: Name[s.stylename] ]; }; initialCurvePart: CurvePart ~ [cyclicSpline [[naturalUM, NIL]]]; initialVariant: Variant ~ [curve [initialCurvePart]]; initialObjectRep: ObjectRep ~ [TRUE, inVisible, 0, 0, initialVariant]; ReadObjects: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [objects: Objects] ~ UNCHECKED { ReadObject: INTERNAL UNSAFE PROC RETURNS [object: Object _ NEW[ObjectRep _ initialObjectRep]] ~ UNCHECKED { ReadVariant: INTERNAL UNSAFE PROC RETURNS [variant: Variant _ initialVariant] ~ UNCHECKED { ReadVEC: INTERNAL UNSAFE PROC RETURNS [vec: VEC] ~ UNCHECKED { point: GFileFormatDefs.GFilePoint; ReadStructure[diskHandle, @point, GFileFormatDefs.lGFilePoint]; vec.x _ ConvertReal[point.x]; vec.y _ ConvertReal[point.y]; }; ReadCurvePart: INTERNAL UNSAFE PROC RETURNS [cp: CurvePart _ initialCurvePart] ~ UNCHECKED { ReadLink: INTERNAL UNSAFE PROC RETURNS [link: Link] ~ UNCHECKED { knotWord: GFileFormatDefs.GFileKnotWord; ReadStructure[diskHandle, @knotWord, GFileFormatDefs.lGFileKnotWord]; IF knotWord.knotcount=0 THEN ERROR; --Bad link link _ NEW[LinkRep[knotWord.knotcount]]; link.degree _ LOOPHOLE[knotWord.knottype]; FOR knot: CARDINAL IN [0..link.nKnots) DO link.knots[knot] _ ReadVEC[]; ENDLOOP; }; --ReadLink nLinks: CARDINAL _ ReadCardinal[diskHandle]; SELECT gObject.trajtype FROM GFileFormatDefs.typeLinkedTraj => { linkPart: LinkPart _ NEW[LinkPartRep[nLinks]]; linkPart.splineType _ ConvertSplineType[gObject.splinetype]; FOR link: CARDINAL IN [0..nLinks) DO linkPart.links[link] _ ReadLink[]; ENDLOOP; cp _ [linked [linkPart]]; }; GFileFormatDefs.typeCSTraj => { IF nLinks#1 THEN ERROR --Impossible cyclic spline ELSE { splineType: SplineType _ ConvertSplineType[gObject.splinetype]; SELECT splineType FROM naturalUM => splineType _ cyclicUM; naturalAL => splineType _ cyclicAL; ENDCASE; cp _ [cyclicSpline [[splineType, ReadLink[]]]]; }; }; ENDCASE => ERROR; --Invalid trajectory }; --ReadCurvePart ReadCaptionPart: INTERNAL UNSAFE PROC RETURNS [cp: CaptionPart] ~ UNCHECKED { ReadString: PROCEDURE RETURNS [r: ROPE] ~ TRUSTED { length: CARDINAL _ LOOPHOLE[IO.GetChar[diskHandle], CARDINAL]; t: REF TEXT _ NEW[TEXT[length]]; IF IO.GetBlock[diskHandle,t,0,length] # length THEN ERROR; --Possible disk problem r _ Rope.FromRefText[t]; IF (length+1) MOD 2 # 0 THEN [] _ IO.GetChar[diskHandle]; }; cp.position _ ReadVEC[]; cp.text _ ReadString[]; }; SELECT gObject.objtype FROM GFileFormatDefs.typeCurveObject => { variant _ [curve [ReadCurvePart[]]]; }; GFileFormatDefs.typeAreaObject => { variant _ [area [ReadCurvePart[]]]; }; GFileFormatDefs.typeCaptionObject => { variant _ [caption [ReadCaptionPart[]]]; }; ENDCASE => ERROR; }; --ReadVariant gObject: REF GFileFormatDefs.GFileObject _ NEW[GFileFormatDefs.GFileObject]; ReadStructure[diskHandle, LOOPHOLE[gObject], GFileFormatDefs.lGFileObject]; object^ _ [ hidden: gObject.hidewindow, visibility: LOOPHOLE[gObject.visible], style: gObject.style-1, --Fence-post correction cluster: gObject.cluster, variant: ReadVariant[] ]; }; --ReadObject objectCount: CARDINAL ~ ReadCardinal[diskHandle]; objects _ NEW[ObjectsRep[objectCount]]; FOR index: CARDINAL IN [0..objectCount) DO objects[index] _ ReadObject[]; ENDLOOP; }; --ReadObjects ConvertSplineType: PROC [splineTypeInFile: CARDINAL] RETURNS [SplineType] ~ { RETURN [SELECT splineTypeInFile FROM IN [GFileFormatDefs.typeNUMSpline..GFileFormatDefs.typeCRSpline] => LOOPHOLE[splineTypeInFile], ENDCASE => ERROR --Illegal spline type ]; }; charsPerPage: CARDINAL ~ 512; MoveToSector: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM, si: GFileFormatDefs.SectorIndex] ~ UNCHECKED { IO.SetIndex[diskHandle, INTEGER[si*charsPerPage]]; }; ReadStructure: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM, p: LONG POINTER, l: CARDINAL] ~ UNCHECKED { from: LONG POINTER; b: REF TEXT _ NEW[TEXT[l*2]]; IF IO.GetBlock[diskHandle, b, 0, 2*l] # 2*l THEN ERROR; from _ LOOPHOLE[b,LONG POINTER]+2; --start of bytes PrincOpsUtils.LongCopy[from,l,p]; }; ReadCardinal: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [CARDINAL] ~ UNCHECKED { high, low: CHARACTER; word: Basics.BytePair; high _ IO.GetChar[diskHandle]; low _ IO.GetChar[diskHandle]; word.high _ LOOPHOLE[high]; word.low _ LOOPHOLE[low]; RETURN[LOOPHOLE[word]]; }; ReadHeader: INTERNAL UNSAFE PROC [diskHandle: IO.STREAM] RETURNS [header: GFileFormatDefs.GFileHeader] ~ UNCHECKED { h: POINTER TO GFileFormatDefs.GFileHeader ~ @header; IO.SetIndex[diskHandle,0]; ReadStructure[diskHandle, h, GFileFormatDefs.lGFileHeader]; ConvertReal _ IF (h.majversion=1 AND h.minversion IN [0..3]) THEN ConvertRealFromMesa5 ELSE ConvertRealFromReal; }; FixFileName: INTERNAL PROC [oldname, extension: ROPE] RETURNS [newname:ROPE] ~ { cp: FS.ComponentPositions; dirOmitted: BOOL; [newname, cp, dirOmitted] _ FS.ExpandName[oldname]; newname _ Rope.Cat[Rope.Substr[base: newname, len: cp.base.start+cp.base.length], extension]; IF dirOmitted THEN newname _ Rope.Substr[base: newname, start: cp.base.start]; }; CachedFont: TYPE ~ RECORD [ key: REF GriffinImageUtils.Font, imagerFont: Imager.Font ]; CompareFonts: PROC [k, data: REF] RETURNS [c: Basics.Comparison] ~ { f1: REF GriffinImageUtils.Font ~ NARROW[k]; f2: REF GriffinImageUtils.Font ~ NARROW[data, REF CachedFont].key; SELECT TRUE FROM (c _ Basics.CompareCard[f1.points, f2.points])#equal => RETURN; (c _ Basics.CompareCard[f1.face, f2.face])#equal => RETURN; (c _ Basics.CompareCard[f1.rotation, f2.rotation])#equal => RETURN; ENDCASE => RETURN [Rope.Compare[f1.name, f2.name, FALSE]]; }; GetFontsKey: PROC [data: REF] RETURNS [key: REF] ~ { RETURN [NARROW[data, REF CachedFont].key]; }; fontCache: RedBlackTree.Table ~ RedBlackTree.Create[GetFontsKey, CompareFonts]; FindFont: PROC [font: GriffinImageUtils.Font] RETURNS [imagerFont: Imager.Font _ NIL] ~ { key: REF GriffinImageUtils.Font _ NEW[GriffinImageUtils.Font _ font]; cachedFont: REF CachedFont ~ NARROW[RedBlackTree.Lookup[fontCache, key]]; IF cachedFont#NIL THEN RETURN [cachedFont.imagerFont]; { --Here, it wasn't in the cache FaceToExtension: PROC RETURNS [extension: ROPE] ~ { RETURN [ SELECT font.face FROM 0 => "-mrr", --Plain 1 => "-mir", --Italics 2 => "-brr", --Bold 3 => "-bir", --Italics + Bold ENDCASE => ERROR ] }; msg: ROPE _ NIL; --Complaint about fonts fontName: ROPE _ font.name; fontExtension: ROPE _ FaceToExtension[]; WHILE imagerFont=NIL DO imagerFont _ ImagerFont.Find[Rope.Cat["Xerox/PressFonts/", fontName, fontExtension] ! Imager.Error => { SELECT FALSE FROM --Various recovery techniques. Note that the result order is to (1) try the font as specified, (2) look for a plain-faced version of the font, (3) look for Helvetica, but use the bold and/or italics, (4) use plain Helvetica, (5) give up and die. Rope.Equal["-mrr", fontExtension] => { fontExtension _ "-mrr"; }; Rope.Equal["Helvetica", fontName] => { fontName _ "Helvetica"; fontExtension _ FaceToExtension[]; -- }; ENDCASE => GOTO Fail; --Leave the error uncaught imagerFont _ NIL; msg _ Rope.Cat[error.explanation, " Substituting Xerox/PressFonts/", fontName, fontExtension, "."]; CONTINUE; EXITS Fail => NULL; }]; ENDLOOP; IF msg#NIL THEN MessageWindow.Append[msg, TRUE]; imagerFont _ ImagerFont.Scale[font: imagerFont, s: PointsToFontSize[font.points]]; RedBlackTree.Insert[self: fontCache, dataToInsert: NEW[CachedFont _ [key, imagerFont]], insertKey: key]; }; }; PointsToFontSize: PROC [points: REAL] RETURNS [fontSize: REAL] ~ INLINE { RETURN [points*Imager.micasPerPoint] }; GriffinObjectToImagerCalls: PUBLIC PROC [context: Imager.Context, object: Object, style: Style, fonts: FontDir] ~ CHECKED { SetColor: PROC [color: Color] ~ { Imager.SetColor[context, ImagerColor.ColorFromRGB[ImagerColor.RGBFromHSV[[H: color.hue/255.0, S: color.saturation/255.0, V: color.brightness/255.0]]]]; }; SetThickness: PROC [thickness: REAL] ~ { Imager.SetStrokeWidth[context, thickness]; }; PlayCurvePart: PROC [cp: CurvePart, closed: BOOL] ~ { path: ImagerPath.Trajectory; first: BOOLEAN _ TRUE; moveTo: ImagerPath.MoveToProc _ firstMoveTo; nullMoveTo: ImagerPath.MoveToProc = {}; firstMoveTo: ImagerPath.MoveToProc = TRUSTED { path _ ImagerPath.MoveTo[p]; moveTo _ nullMoveTo}; curveTo: ImagerPath.CurveToProc = {path _ ImagerPath.CurveTo[path, p1, p2, p3]}; linkToCubicPath: PROC [cubicLink: Link, splineType: CubicSplines.SplineType] RETURNS[cubicPath: CubicPaths.Path] = { cyclic: BOOLEAN _ splineType=cyclicAL OR splineType=cyclicUM; nKnots: CARDINAL _ IF cyclic THEN cubicLink.nKnots+1 ELSE cubicLink.nKnots; knots: CubicSplines.KnotSequence _ NEW[CubicSplines.KnotSequenceRec[nKnots]]; FOR i: CARDINAL IN [0..cubicLink.nKnots) DO knots[i][CubicSplines.X] _ cubicLink[i].x; knots[i][CubicSplines.Y] _ cubicLink[i].y; ENDLOOP; IF cyclic THEN { knots[cubicLink.nKnots][CubicSplines.X] _ cubicLink[0].x; knots[cubicLink.nKnots][CubicSplines.Y] _ cubicLink[0].y; }; cubicPath _ CubicPaths.PathFromCubic[CubicSplines.MakeSpline[knots, splineType]]; RETURN[cubicPath]; }; WITH cp SELECT FROM links: linked CurvePart => { --degree=1 for lines, 3 for cubics. splineType: CubicSplines.SplineType _ links.linked.splineType; FOR linkIndex: CARDINAL IN [0..links.linked.nLinks) DO link: Link ~ links.linked.links[linkIndex]; IF link.degree=3 THEN { --cubic cubicPath: CubicPaths.Path _ linkToCubicPath[link, splineType]; CubicPaths.EnumeratePath[cubicPath, moveTo, curveTo]; } ELSE { --assume lines moveTo[link[0]]; FOR knotIndex: CARDINAL IN [1..link.nKnots) DO path _ ImagerPath.LineTo[path, link[knotIndex]]; ENDLOOP; }; ENDLOOP; IF closed THEN path _ ImagerPath.LineTo[path, links.linked.links[0].knots[0]]; }; cyclic: cyclicSpline CurvePart => { cubicPath: CubicPaths.Path _ linkToCubicPath[cyclic.cyclicSpline.link, cyclic.cyclicSpline.splineType]; CubicPaths.EnumeratePath[cubicPath, moveTo, curveTo]; }; ENDCASE => ERROR; IF closed AND style.fillArea THEN { SetColor[style.areaColor]; Imager.MaskFillTrajectory[context, path]; }; IF ~closed OR style.outlineArea THEN { SetColor[style.color]; Imager.SetStrokeWidth[context, style.thickness]; Imager.MaskStrokeTrajectory[context, path]; }; }; WITH object.variant SELECT FROM caption: caption Variant => { imagerFont: Imager.Font ~ FindFont[fonts[style.font]]; length: REAL; SetColor[style.color]; Imager.SetFont[context, imagerFont]; length _ ImagerFont.RopeWidth[imagerFont, caption.caption.text].x; Imager.SetXY[context, caption.caption.position]; Imager.SetYRel[context, -PointsToFontSize[fonts[style.font].points]]; Imager.Move[context]; SELECT style.textRotation FROM d90 => Imager.RotateT[context, 90]; d180 => Imager.RotateT[context, 180]; d270 => Imager.RotateT[context, 270]; ENDCASE; SELECT style.anchor FROM left => NULL; right => Imager.SetXRel[context, -length]; center => Imager.SetXRel[context, -length/2]; ENDCASE => ERROR; Imager.ShowRope[context, caption.caption.text]; }; curve: curve Variant => PlayCurvePart[curve.curve, FALSE]; area: area Variant => PlayCurvePart[area.curve, TRUE]; ENDCASE => ERROR; }; GriffinToImagerCalls: PUBLIC PROC [context: Imager.Context, g: GriffinImage] ~ CHECKED { FOR fIndex: CARDINAL IN [FIRST[ValidFigRange]..g.nFigures) DO figure: Figure ~ g.figures[fIndex]; FOR oIndex: CARDINAL IN [0..figure.objects.nObjects) DO PlayObject: PROC ~ { GriffinObjectToImagerCalls[context, object, style, figure.font]; }; object: Object ~ figure.objects[oIndex]; style: Style ~ figure.styles[object.style]; IF ~object.hidden THEN Imager.DoSaveAll[context, PlayObject]; ENDLOOP; ENDLOOP; }; END. ŒGriffinImageUtilsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Eric Nickell, July 31, 1985 9:43:40 am PDT Stone, August 6, 1985 0:20:31 am PDT Monitors the current definition of ConvertReal Reads the fth figure into the GriffinImage structure. N.B.: Does conversion on the REALs found NOTE: diskHandle must be set up ready to read the object count!!!!!!!!!!!!! Main body of ReadCurvePart Main body of ReadCurvePart always read an even number of bytes: string length + string chars MOD 2 = 0 Main body of ReadVariant Main body of ReadObject Main body of ReadObjects Dependent on definition of SplineType: TYPE ~ {naturalUM,cyclicUM,naturalAL,cyclicAL,bezier,bsplineInterp,bspline,crspline}; Version 1.4 is the first with the Ieee floating point format. We need to set up to convert the reals for older versions. Look up the font Scale and rotate (ignored for now) the font ΚŒ˜™Icodešœ Οmœ1™K˜"K˜?K˜K˜K˜—š   œžœžœžœžœ&ž œ˜\š  œžœžœžœžœž œ˜AKšΟb™K˜(K˜EKšžœžœžœ‘ ˜.Kšœžœ˜(Kšœžœ˜*šžœžœžœž˜)K˜Kšžœ˜—Kšœ‘ ˜ —Kšœžœ˜,Kš£™šžœž˜šœ#˜#Kšœžœ˜.Kšœ<˜<šžœžœžœ ž˜$K˜"Kšžœ˜—K˜Kšœ˜—šœ˜Kšžœ žœžœ‘˜1šžœ˜Kšœ?˜?šžœ ž˜K˜#K˜#Kšžœ˜—K˜/Kšœ˜—Kšœ˜—Kšžœžœ‘˜&—Kšœ‘˜—š  œžœžœžœžœž œ˜Mš   œž œžœžœžœ˜3Kš œžœžœžœžœ˜>Kš œžœžœžœžœ ˜ Kš žœžœ*žœžœ‘˜RK˜KšœK™KKšžœ žœžœžœ˜9K˜K˜—K˜K˜K˜—Kš£™šžœž˜šœ$˜$K˜$Kšœ˜—šœ#˜#Kšœ#˜#Kšœ˜—šœ&˜&K˜(Kšœ˜—Kšžœžœ˜—Kšœ‘ ˜—Kšœ žœžœ˜LKš£™Kšœžœ)˜Kšœ ˜ Kšœ˜Kšœ žœ˜&Kšœ‘˜0Kšœžœ˜Kšœ˜Kšœ˜—Kšœ‘ ˜—Kšœ žœ˜1Kš£™Kšœ žœ˜'šžœžœžœž˜*K˜Kšžœ˜—Kšœ‘ ˜K˜—š œžœžœžœ˜MK™|šžœžœž˜$KšžœBžœ˜_Kšžœžœ‘˜'Kšœ˜—K˜—Kšœžœ˜š  œžœžœžœžœžœ%ž œ˜iKšžœžœ˜2K˜J˜—š  œžœžœžœžœžœžœžœžœž œ˜gKšœžœžœ˜Kš œžœžœžœžœ˜šžœžœ&˜+Kšžœžœ˜ —Kšœžœžœžœ‘˜3K˜!J˜J˜—š  œžœžœžœžœžœžœžœž œ˜[Kšœ ž œ˜K˜Kšœžœ˜Kšœžœ˜Kšœ žœžœ˜5Kšžœžœ˜J˜J˜—š  œžœžœžœžœžœžœ)ž œ˜tKšœžœžœ'˜4Kšžœ˜Kšœ;˜;š œžœžœžœ žœžœ˜pJšœ=™=Jšœ:™:—K˜K˜—š   œžœžœžœžœ žœ˜PJšœžœ˜Jšœ žœ˜Jšœžœ˜3J•StartOfExpansion9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]šœ]˜]K–9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]šžœ žœ<˜NJ˜J˜—šœ žœžœ˜Kšœžœ˜ K˜Kšœ˜—š  œžœ žœžœ˜DKšœžœžœ˜+Kšœžœžœžœ˜Bšžœžœž˜Kšœ8žœ˜?Kšœ4žœ˜;Kšœ<žœ˜CKšžœžœ!žœ˜:—K˜—code2š   œžœžœžœžœ˜4Kšžœžœžœ˜*K˜—L˜Oš œžœ žœžœ˜YKšœžœžœ ˜EKšœ žœžœ&˜IKšžœ žœžœžœ˜6šœ‘˜!š œžœžœ žœ˜3šžœ˜šžœ ž˜Kšœ‘˜Kšœ‘ ˜Kšœ‘˜Kšœ‘˜Kšžœž˜—Kšœ˜—K˜—Kšœžœžœ‘˜)Kšœ žœ ˜Kšœžœ˜(K˜Kš£™šžœ žœž˜šœg˜gšžœžœžœ‘φ˜ˆšœ&˜&K˜Kšœ˜—šœ&˜&K˜K˜%Kšœ˜—Kšžœžœ‘˜1—Kšœ žœ˜Kšœd˜dKšžœ˜ Kšžœ žœ˜Kšœ˜—Kšžœ˜—Kšžœžœžœžœ˜0K˜Kš£+™+KšœR˜RK–b[self: RedBlackTree.Table, dataToInsert: RedBlackTree.UserData, insertKey: RedBlackTree.Key]šœ3žœ2˜hKšœ˜—K˜—š  œžœ žœžœ žœžœ˜IKšžœ˜$K˜—š œžœžœKžœ˜{š œžœ˜!Kšœ—˜—K˜—š  œžœ žœ˜(K˜*K˜—š  œžœžœ˜5K˜Kšœžœžœ˜K˜,K˜'˜.K˜2—KšœP˜Pšœžœ8žœ ˜tKšœžœžœ˜=Kš œžœžœžœžœ˜KKšœ#žœ'˜Mšžœžœžœž˜+Kšœ*˜*Kšœ*˜*Kšžœ˜—˜Kšœ9˜9Kšœ9˜9K˜—KšœQ˜QKšžœ ˜K˜K˜—šžœžœž˜šœ‘$˜AK˜>šžœ žœžœž˜6Kšœ+˜+šžœžœ‘˜Kšœ?˜?K˜5K˜—šžœ‘˜K˜šžœ žœžœž˜.K˜0Kšžœ˜—Kšœ˜—Kšžœ˜—Kšžœžœ@˜NKšœ˜—šœ#˜#šœ˜KšœJ˜J—K˜5Kšœ˜—Kšžœžœ˜—šžœžœžœ˜#K˜K˜)Kšœ˜—šžœ žœžœ˜&K˜K˜0K˜+Kšœ˜—K˜—šžœžœž˜šœ˜Kšœ6˜6Kšœžœ˜ K˜Kšœ$˜$KšœB˜BKšœ0˜0KšœE˜EK˜šžœž˜K˜#K˜%K˜%Kšžœ˜—šžœž˜Kšœžœ˜ K˜*K˜-Kšžœžœ˜—K˜/Kšœ˜—Kšœ3žœ˜:Kšœ0žœ˜6Kšžœžœ˜—K˜—š œžœžœ.žœ˜Xš žœ žœžœžœž˜=K˜#šžœ žœžœž˜7š  œžœ˜K˜@K˜—K˜(K˜+Kšžœžœ'˜=Kšžœ˜—Kšžœ˜—K˜——Kšžœ˜J˜—…—HŒa€