DIRECTORY Basics, Convert, FileNames, GGBasicTypes, GGFromImager, GGModelTypes, GGObjects, GGOutline, GGParseIn, GGSegment, GGSegmentTypes, GGSlice, GGTraj, GGUtility, GGVector, Imager, ImagerBackdoor, ImagerColor, ImagerFont, ImagerFontPrivate, ImagerInterpress, ImagerPath, ImagerPrivate, ImagerRasterPrivate, ImagerState, ImagerTransformation, Interpress, IO, RefText, Rope, ViewerClasses; GGFromImagerImpl: CEDAR PROGRAM IMPORTS Convert, FileNames, GGParseIn, GGObjects, GGOutline, GGSegment, GGSlice, GGTraj, GGUtility, GGVector, Imager, ImagerBackdoor, ImagerFont, ImagerInterpress, ImagerPath, ImagerRasterPrivate, ImagerState, ImagerTransformation, Interpress, IO, RefText, Rope EXPORTS GGFromImager, Imager, ImagerFont = BEGIN BYTE: TYPE ~ Basics.BYTE; ROPE: TYPE ~ Rope.ROPE; Class: TYPE ~ REF ClassRep; ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager.ClassRep Context: TYPE ~ Imager.Context; Color: TYPE ~ Imager.Color; ColorOperator: TYPE ~ Imager.ColorOperator; Clipper: TYPE ~ ImagerBackdoor.Clipper; Font: TYPE ~ ImagerFont.Font; PathProc: TYPE ~ ImagerPath.PathProc; PixelArray: TYPE ~ Imager.PixelArray; Point: TYPE ~ GGBasicTypes.Point; Rectangle: TYPE ~ ImagerTransformation.Rectangle; Slice: TYPE ~ GGModelTypes.Slice; State: TYPE ~ REF StateRep; StateRep: PUBLIC TYPE ~ ImagerState.StateRep; Transformation: TYPE ~ ImagerTransformation.Transformation; VEC: TYPE ~ Imager.VEC; Viewer: TYPE ~ ViewerClasses.Viewer; XChar: TYPE ~ ImagerFont.XChar; XStringProc: TYPE ~ ImagerFont.XStringProc; FontImpl: TYPE ~ ImagerFontPrivate.FontImpl; FontImplRep: PUBLIC TYPE ~ ImagerFontPrivate.FontImplRep; -- export to to ImagerFont Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ scene: GGModelTypes.Scene, feedback: Viewer ]; Warning: PUBLIC SIGNAL [context: Context, code: ATOM, message: ROPE] ~ CODE; Create: PROC [feedback: Viewer] RETURNS [Context] ~ { data: Data ~ NEW[DataRep _ [scene: GGObjects.CreateScene[], feedback: feedback]]; state: State ~ NEW[StateRep _ []]; state.T _ ImagerTransformation.Scale[1.0]; -- allocate storage for a transformation and initialize to the identity state.color _ Imager.black; RETURN[NEW[Imager.ContextRep _ [class: gargoyleClass, state: state, data: data]]]; }; Capture: PUBLIC PROC [action: PROC [Context], feedback: Viewer _ NIL] RETURNS [GGModelTypes.Scene] ~ { context: Context ~ Create[feedback]; action[context]; WITH context.data SELECT FROM data: Data => RETURN [data.scene]; ENDCASE => ERROR; }; ProcessStateChanges: PUBLIC PROC [context: Context] ~ { state: State ~ context.state; changed: ImagerState.ChangeFlags ~ state.changed; state.changed _ ImagerState.notChanged; IF changed.clipper AND state.clipper # NIL THEN SIGNAL Warning[context, $Clipping, "NotImplemented: Clipping"]; }; RopeFromXStringProc: PROC [string: XStringProc] RETURNS [rope: ROPE _ NIL] ~ { text: REF TEXT _ RefText.ObtainScratch[256]; set: BYTE _ 0; action: PROC [char: XChar] ~ { IF char.set#set THEN { text _ RefText.AppendChar[to: text, from: VAL[255]]; text _ RefText.AppendChar[to: text, from: VAL[set _ char.set]]; }; text _ RefText.AppendChar[to: text, from: VAL[char.code]]; }; text.length _ 0; string[action]; rope _ Rope.FromRefText[text]; RefText.ReleaseScratch[text]; RETURN [rope]; }; UnpackComplexFontName: PROC [fontName: Rope.ROPE] RETURNS [prefix, family, face: Rope.ROPE, fontSize: REAL] = { DigitProc: IO.BreakProc = { SELECT char FROM IO.TAB, IO.CR, IO.SP => RETURN [break]; '0, '1, '2, '3, '4, '5, '6, '7, '8, '9 => RETURN [break]; ENDCASE => RETURN [other]; }; AlphaProc: IO.BreakProc = { SELECT char FROM IO.TAB, IO.CR, IO.SP => RETURN [break]; IN ['a .. 'z], IN ['A .. 'Z] => RETURN [break]; ENDCASE => RETURN [other]; }; new, sizeRope: Rope.ROPE; prefix _ FileNames.Directory[path: fontName]; -- "xerox/*fonts/" new _ FileNames.GetShortName[fontName]; -- get family "name" face _ FileNames.Tail[new, '-]; -- get face component (MIR, BRR, ...) IF Rope.Equal[face, new] THEN { -- have a name like Helvetica10I OR TERMINAL endOfName: BOOL; nameStream: IO.STREAM _ IO.RIS[new]; family _ IO.GetTokenRope[nameStream, DigitProc].token; -- get the leading alpha characters sizeRope _ IO.GetTokenRope[nameStream, AlphaProc ! IO.EndOfStream, IO.Error => {endOfName _ TRUE; CONTINUE;};].token; -- get any digit characters fontSize _ Convert.RealFromRope[sizeRope]; IF endOfName THEN face _ "" -- because face = new ELSE face _ Rope.Concat["-", GGParseIn.ReadBlankAndWord[nameStream]]; } ELSE { -- have a name like Helvetica-MIR family _ Rope.Substr[base: new, start: 0, len: Rope.SkipTo[s: new, pos: 0, skip: "-"]]; -- throw away "-XXX" face _ SELECT TRUE FROM Rope.Equal[face, "MRR", FALSE] => "", Rope.Equal[face, "BRR", FALSE] => "-B", Rope.Equal[face, "Bold", FALSE] => "-B", Rope.Equal[face, "MIR", FALSE] => "-I", Rope.Equal[face, "Italic", FALSE] => "-I", Rope.Equal[face, "BIR", FALSE] => "-BI", ENDCASE => ERROR; fontSize _ 1.0; }; }; SetSegColor: PROC [context: Context, seg: GGSegmentTypes.Segment] = { seg.color _ IF ISTYPE[context.state.color, ImagerColor.ConstantColor] THEN context.state.color ELSE Imager.black; }; OutlineFromPath: PROC[context: Context, path: PathProc, m: Transformation, closed: BOOL] RETURNS [GGModelTypes.Outline] ~ { curOutline: GGModelTypes.Outline _ NIL; curTraj: GGModelTypes.Traj _ NIL; curSeg: GGSegmentTypes.Segment _ NIL; lp: VEC _ [0,0]; firstPoint: VEC _ [0,0]; Finish: PROC ~ { IF curTraj # NIL THEN { IF curSeg # NIL THEN { IF closed THEN { IF curSeg.hi = firstPoint THEN { [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; GGTraj.CloseByDistorting[curTraj, hi]; } ELSE { [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; curSeg _ GGSegment.MakeLine[curSeg.hi, firstPoint, NIL]; curSeg.strokeWidth _ GGVector.Magnitude[ImagerTransformation.TransformVec[m, [context.state.np.strokeWidth, 0.0] ] ]; SetSegColor[context, curSeg]; GGTraj.CloseWithSegment[curTraj, curSeg, lo]; }; } ELSE [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; } ELSE { -- unlikely but legal case: Traj with a single point, no segment [] _ GGTraj.AddSegment[curTraj, lo, GGSegment.MakeLine[[lp.x, lp.y], [lp.x, lp.y], NIL], lo]; }; curSeg _ NIL; IF curOutline = NIL THEN curOutline _ GGOutline.CreateOutline[curTraj] ELSE curOutline _ GGOutline.AddHole[curOutline, curTraj]; curTraj _ NIL; }; }; Move: PROC [p: VEC] ~ { Finish[]; curTraj _ GGTraj.CreateTraj[[p.x, p.y]]; firstPoint _ lp _ p; }; Line: PROC [p1: VEC] ~ { IF curSeg # NIL THEN [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; curSeg _ GGSegment.MakeLine[[lp.x, lp.y], [p1.x, p1.y], NIL]; curSeg.strokeWidth _ GGVector.Magnitude[ImagerTransformation.TransformVec[m, [context.state.np.strokeWidth, 0.0] ] ]; SetSegColor[context, curSeg]; lp _ p1; }; Curve: PROC [p1, p2, p3: VEC] ~ { IF curSeg # NIL THEN [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; curSeg _ GGSegment.MakeBezier[[lp.x, lp.y], [p1.x, p1.y], [p2.x, p2.y], [p3.x, p3.y], NIL]; curSeg.strokeWidth _ GGVector.Magnitude[ImagerTransformation.TransformVec[m, [context.state.np.strokeWidth, 0.0] ] ]; SetSegColor[context, curSeg]; lp _ p3; }; Conic: PROC [p1, p2: VEC, r: REAL] ~ { IF curSeg # NIL THEN [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; curSeg _ GGSegment.MakeConic[[lp.x, lp.y], [p1.x, p1.y], [p2.x, p2.y], r, NIL]; curSeg.strokeWidth _ GGVector.Magnitude[ImagerTransformation.TransformVec[m, [context.state.np.strokeWidth, 0.0] ] ]; SetSegColor[context, curSeg]; lp _ p2; }; Arc: PROC [p1, p2: VEC] ~ { IF curSeg # NIL THEN [] _ GGTraj.AddSegment[curTraj, hi, curSeg, lo]; curSeg _ GGSegment.MakeArc[[lp.x, lp.y], [p1.x, p1.y], [p2.x, p2.y], NIL]; curSeg.strokeWidth _ GGVector.Magnitude[ImagerTransformation.TransformVec[m, [context.state.np.strokeWidth, 0.0] ] ]; SetSegColor[context, curSeg]; lp _ p2; }; ImagerPath.Transform[path, m, Move, Line, Curve, Conic, Arc]; Finish[]; RETURN [curOutline]; }; MyShow: PROC[context: Context, string: XStringProc, xrel: BOOL] ~ { OPEN ImagerTransformation; textSlice: GGModelTypes.Slice; data: Data _ NARROW[context.data]; font: ImagerFont.Font _ context.class.GetFont[context]; rope: ROPE _ RopeFromXStringProc[string]; escapement: VEC _ ImagerFont.RopeWidth[font, rope]; IF context.state.np.noImage=0 THEN { color: Imager.Color _ context.class.GetColor[context]; currentT: Transformation _ context.class.GetT[context]; currentPoint: Point _ context.class.GetCP[context, FALSE]; charToClientScale: VEC _ Factor[font.charToClient].s; totalTransform: Transformation; fontSize: REAL _ 1.0; amplifySpace: REAL; correctMeasureX: REAL; prefix, family, face, fontName, problem: Rope.ROPE; amplifySpace _ ImagerBackdoor.GetReal[context, $amplifySpace]; correctMeasureX _ ImagerBackdoor.GetReal[context, $correctMX]; [prefix, family, face, fontSize] _ UnpackComplexFontName[font.name]; totalTransform _ Cat[Scale[fontSize], font.charToClient, Translate[currentPoint], currentT]; [fontName, ----, ----, problem] _ GGUtility.FontDataFromUserData[prefix, family, face, 1.0, fontSize]; IF problem#NIL THEN ERROR; textSlice _ GGSlice.MakeTextSlice[rope, color, amplifySpace]; [] _ GGSlice.SetTextFont[slice: textSlice, prefix: prefix, family: family, face: face, fontName: fontName, scale: 1.0, fontScale: fontSize, transform: totalTransform, feedback: NIL]; GGObjects.AddSlice[data.scene, textSlice, -1]; }; ImagerState.StateSetXYRel[context, escapement]; }; MyMaskFill: PROC[context: Context, path: PathProc, oddWrap: BOOL] ~ { data: Data ~ NARROW[context.data]; state: State ~ context.state; IF state.changed#ImagerState.notChanged THEN ProcessStateChanges[context]; IF oddWrap THEN SIGNAL Warning[context, $ParityFill, "NotImplemented: ParityFill"]; IF context.state.np.noImage=0 THEN --CHECKED-- { outline: GGModelTypes.Outline _ OutlineFromPath[context, path, state.T, TRUE]; outline.class.setFillColor[outline, state.color]; GGObjects.AddOutline[data.scene, outline, -1]; }; }; MyMaskStroke: PROC[context: Context, path: PathProc, closed: BOOL] ~ { outline: GGModelTypes.Outline; data: Data ~ NARROW[context.data]; state: State ~ context.state; IF state.changed#ImagerState.notChanged THEN ProcessStateChanges[context]; IF context.state.np.noImage=0 THEN { outline _ OutlineFromPath[context, path, state.T, closed]; outline.class.setFillColor[outline, NIL]; -- no fill color GGObjects.AddOutline[data.scene, outline, -1]; }; }; MyMaskDashedStroke: PROC[context: Context, path: PathProc, patternLen: NAT, pattern: PROC [NAT] RETURNS [REAL], offset, length: REAL] ~ { MyMaskStroke[context, path, FALSE]; }; MyMaskRectangle: PROC[context: Context, r: Rectangle] ~ { path: PathProc ~ { moveTo[[r.x, r.y]]; lineTo[[r.x+r.w, r.y]]; lineTo[[r.x+r.w, r.y+r.h]]; lineTo[[r.x, r.y+r.h]] }; MyMaskFill[context, path, FALSE]; }; MyMaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER] ~ { MyMaskRectangle[context, [x, y, w, h]]; }; MyMaskVector: PROC[context: Context, p1, p2: VEC] ~ { path: PathProc ~ {moveTo[p1]; lineTo[p2]}; MyMaskStroke[context, path, FALSE]; }; MyMaskPixel: PROC[context: Context, pa: PixelArray] ~ { DoMyMaskPixel: PROC [dc: Imager.Context] = { Imager.MaskPixel[dc, pa]; }; data: Data _ NARROW[context.data]; ipSlice: Slice; currentColor: Color; currentT: ImagerTransformation.Transformation; currentColor _ context.state.color; currentT _ ImagerTransformation.Copy[context.state.T]; ipSlice _ GGSlice.MakeIPSliceFromMaskPixel[pa, currentColor, NIL, currentT]; GGObjects.AddSlice[data.scene, ipSlice, -1]; }; MyMaskBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ { DoMyMaskBits: PROC [dc: Imager.Context] = { Imager.MaskBits[dc, base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty]; }; masterStream, outStream: IO.STREAM; masterRope: Rope.ROPE; data: Data _ NARROW[context.data]; ipRef: ImagerInterpress.Ref; ipMaster: Interpress.Master; ipSlice: Slice; SIGNAL Warning[context, $MaskBits, "NotImplemented: MaskBits"]; outStream _ IO.ROS[]; ipRef _ ImagerInterpress.CreateFromStream[outStream, "Interpress/Xerox/3.0 "]; ImagerInterpress.DoPage[ipRef, DoMyMaskBits]; ImagerInterpress.Finish[ipRef]; masterRope _ IO.RopeFromROS[outStream]; masterStream _ IO.RIS[masterRope]; ipMaster _ Interpress.FromStream[masterStream, NIL]; GGObjects.AddSlice[data.scene, ipSlice, -1]; }; MyDrawBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ { DoMyDrawBits: PROC [dc: Imager.Context] = { Imager.MaskBits[dc, base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty]; }; masterStream, outStream: IO.STREAM; masterRope: Rope.ROPE; data: Data _ NARROW[context.data]; ipRef: ImagerInterpress.Ref; ipMaster: Interpress.Master; ipSlice: Slice; SIGNAL Warning[context, $DrawBits, "NotImplemented: DrawBits"]; outStream _ IO.ROS[]; ipRef _ ImagerInterpress.CreateFromStream[outStream, "Interpress/Xerox/3.0 "]; ImagerInterpress.DoPage[ipRef, DoMyDrawBits]; ImagerInterpress.Finish[ipRef]; masterRope _ IO.RopeFromROS[outStream]; masterStream _ IO.RIS[masterRope]; ipMaster _ Interpress.FromStream[masterStream, NIL]; GGObjects.AddSlice[data.scene, ipSlice, -1]; }; MyGetBounds: PROC[context: Context] RETURNS[Rectangle] ~ { ERROR Imager.Error[[$NotImplemented, "NotImplemented: GetBounds"]] }; gargoyleClass: Class ~ NEW[ClassRep _ [ type: $Gargoyle, DoSave: ImagerState.StateDoSave, SetInt: ImagerState.StateSetInt, SetReal: ImagerState.StateSetReal, SetT: ImagerState.StateSetT, SetFont: ImagerState.StateSetFont, SetColor: ImagerState.StateSetColor, SetClipper: ImagerState.StateSetClipper, GetInt: ImagerState.StateGetInt, GetReal: ImagerState.StateGetReal, GetT: ImagerState.StateGetT, GetFont: ImagerState.StateGetFont, GetColor: ImagerState.StateGetColor, GetClipper: ImagerState.StateGetClipper, ConcatT: ImagerState.StateConcatT, Scale2T: ImagerState.StateScale2T, RotateT: ImagerState.StateRotateT, TranslateT: ImagerState.StateTranslateT, Move: ImagerState.StateMove, SetXY: ImagerState.StateSetXY, SetXYRel: ImagerState.StateSetXYRel, Show: MyShow, ShowText: ImagerRasterPrivate.RasterShowText, StartUnderline: ImagerState.StateStartUnderline, MaskUnderline: ImagerState.StateMaskUnderline, CorrectMask: ImagerState.StateCorrectMask, CorrectSpace: ImagerState.StateCorrectSpace, Space: ImagerState.StateSpace, SetCorrectMeasure: ImagerState.StateSetCorrectMeasure, SetCorrectTolerance: ImagerState.StateSetCorrectTolerance, Correct: ImagerState.StateCorrect, DontCorrect: ImagerState.StateDontCorrect, SetGray: ImagerState.StateSetGray, SetSampledColor: ImagerState.StateSetSampledColor, SetSampledBlack: ImagerState.StateSetSampledBlack, MaskFill: MyMaskFill, MaskStroke: MyMaskStroke, MaskDashedStroke: MyMaskDashedStroke, MaskRectangle: MyMaskRectangle, MaskRectangleI: MyMaskRectangleI, MaskVector: MyMaskVector, MaskPixel: MyMaskPixel, MaskBits: MyMaskBits, DrawBits: MyDrawBits, Clip: ImagerState.StateClip, ClipRectangle: ImagerState.StateClipRectangle, ClipRectangleI: ImagerState.StateClipRectangleI, GetCP: ImagerState.StateGetCP, GetBoundingRectangle: MyGetBounds, propList: NIL ]]; END. ŒGGFromImagerImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Michael Plass, October 19, 1985 3:55:31 pm PDT Pier, February 3, 1987 12:13:41 pm PST Bier, January 30, 1987 6:52:13 pm PST state.T _ ImagerTransformation.Scale[72/0.0254]; Takes a complex name like "xerox/pressfonts/Helvetica-MIR" and a font size and returns components. May already have a simple name like xerox/tiogafonts/Helvetica10I. KAP August 8, 1986 A kludge for the moment to avoid segments with sampled colors IF curSeg.hi = firstPoint THEN GGTraj.CloseWithSegment[curTraj, curSeg, lo] curSeg.color _ context.state.color; curSeg.color _ context.state.color; curSeg.color _ context.state.color; curSeg.color _ context.state.color; IF charToClientScale.y < 0 THEN totalTransform _ Concat[Scale2[[1, -1]], Concat[Translate[currentPoint], currentT]] ELSE totalTransform _ Concat[Translate[currentPoint], currentT]; GGObjects.SetLineEnds[outline, VAL[CARDINAL[state.np.strokeEnd]]]; Can't do dashed stokes in gargoyle yet. ipSlice _ GGSlice.MakeIPSliceFromMaster[ipMaster, NIL, NIL, NIL, TRUE]; ipSlice _ GGSlice.MakeIPSliceFromMaster[ipMaster, NIL, NIL, NIL, TRUE]; Κχ˜code™Kšœ<™œœ˜{Kšœ#œ˜'Kšœœ˜!Kšœ!œ˜%Kšœœ ˜Kšœ œ ˜šžœœ˜šœ œœ˜šœ œœ˜šœœ˜Kšœœ-™Kšœœ˜ Kšœ0˜0Kšœ&˜&K˜—šœ˜Kšœ0˜0Kšœ3œ˜8Kšœu˜uKšœ˜Kšœ-˜-K˜—K˜—Kšœ1˜5Kšœ˜—šœŸ@˜GKšœSœ˜]Kšœ˜—Kšœ œ˜ Kšœœœ.˜FKšœ5˜9Kšœ œ˜Kšœ˜—Kšœ˜—šžœœœ˜Kšœ ˜ Kšœ(˜(Kšœ˜Kšœ˜—šžœœœ˜Kšœ œœ1˜EKšœ8œ˜=Kšœu˜uKšœ#™#Kšœ˜Kšœ˜Kšœ˜—šžœœœ˜!Kšœ œœ1˜EKšœVœ˜[Kšœu˜uKšœ#™#Kšœ˜Kšœ˜Kšœ˜—šžœœ œœ˜&Kšœ œœ1˜EKšœJœ˜OKšœu˜uKšœ#™#Kšœ˜Kšœ˜Kšœ˜—šžœœ œ˜Kšœ œœ1˜EKšœEœ˜JKšœu˜uKšœ#™#Kšœ˜Kšœ˜Kšœ˜—Kšœ=˜=Kšœ ˜ Kšœ˜Kšœ˜K˜—šžœœ.œ˜CKšœ˜Kšœ˜Kšœ œ˜"Kšœ7˜7Kšœœ˜)Kšœ œ$˜3šœœ˜$Kšœ6˜6Kšœ7˜7Kšœ3œ˜:Kšœœ˜5Kšœ˜Kšœ œ˜Kšœœ˜Kšœœ˜Kšœ.œ˜3šœ™KšœS™S—Kšœ<™@Kšœ>˜>Kšœ>˜>KšœD˜DKšœ\˜\Kšœ,žœ&˜fKšœ œœœ˜K–T[m: ImagerTransformation.Transformation, n: ImagerTransformation.Transformation]šœ=˜=K–ί[slice: GGModelTypes.Slice, prefix: ROPE, family: ROPE, face: ROPE, faceRope: ROPE, scale: REAL _ 1.0, fontScale: REAL _ 1.0, transform: ImagerTransformation.Transformation, feedback: ViewerClasses.Viewer]šœ±œ˜ΆKšœ.˜.K˜—K–%[context: Imager.Context, v: VEC]šœ/˜/Kšœ˜K˜—šž œœ,œ˜EKšœ œ˜"Kšœ˜Kšœ&œ˜JKšœ œœ=˜Sšœœ œ˜0KšœHœ˜NKšœ1˜1Kšœ.˜.Kšœ˜—Kšœ˜K˜—šž œœ+œ˜FKšœ˜Kšœ œ˜"Kšœ˜Kšœ&œ˜Jšœœ˜$Kšœ:˜:Kšœœœ™BKšœ$œŸ˜:Kšœ.˜.Kšœ˜—Kšœ˜K˜—šžœœ/œ œœœœœ˜‰K™'Kšœœ˜#Kšœ˜K˜—šžœœ$˜9šœ˜Kšœ+˜+Kšœ2˜2Kšœ˜—Kšœœ˜!Kšœ˜K˜—šžœœœ˜AKšœ'˜'Kšœ˜K˜—šž œœœ˜5Kšœ*˜*Kšœœ˜#Kšœ˜K˜—šž œœ&˜7šž œœ˜,Kšœ˜K˜—Kšœ œ˜"K˜K˜Kšœ.˜.K˜Kšœ#˜#Kšœ6˜6Kšœ=œ ˜LKšœ,˜,Kšœ˜K˜—šž œœœœœœ œ˜~šž œœ˜+KšœJ˜JK˜—Kšœœœ˜#Kšœœ˜Kšœ œ˜"Kšœ˜Kšœ˜K˜K˜Kšœ9˜?K–’[context: Imager.Context, base: LONG POINTER, wordsPerLine: NAT, sMin: NAT, fMin: NAT, sSize: NAT, fSize: NAT, tx: INTEGER _ 0, ty: INTEGER _ 0]šœ œœ˜KšœN˜NKšœ-˜-Kšœ˜Kšœ œ˜'Kšœœœ ˜"Kšœ/œ˜4Kš œ2œœœœ™GKšœ,˜,Kšœ˜K˜—šž œœœœœœ œ˜~šž œœ˜+KšœJ˜JK˜—Kšœœœ˜#Kšœœ˜Kšœ œ˜"Kšœ˜Kšœ˜K˜K˜Kšœ9˜?K–’[context: Imager.Context, base: LONG POINTER, wordsPerLine: NAT, sMin: NAT, fMin: NAT, sSize: NAT, fSize: NAT, tx: INTEGER _ 0, ty: INTEGER _ 0]šœ œœ˜KšœN˜NKšœ-˜-Kšœ˜Kšœ œ˜'Kšœœœ ˜"Kšœ/œ˜4Kš œ2œœœœ™GKšœ,˜,Kšœ˜K˜—šž œœœ˜:Kšœ=˜BKšœ˜—K˜šœœ ˜'Kšœ˜Kšžœ˜ Kšžœ˜ Kšžœ˜"Kšžœ˜Kšžœ˜"Kšžœ˜$Kšž œ˜(Kšžœ˜ Kšžœ˜"Kšžœ˜Kšžœ˜"Kšžœ˜$Kšž œ˜(Kšžœ˜"Kšžœ˜"Kšžœ˜"Kšž œ˜(Kšžœ˜Kšžœ˜Kšžœ˜$Kšžœ ˜ Kšžœ%˜-Kšžœ"˜0Kšž œ!˜.Kšž œ˜*Kšž œ ˜,Kšžœ˜Kšžœ%˜6Kšžœ'˜:Kšžœ˜"Kšž œ˜*Kšžœ˜"Kšžœ#˜2Kšžœ#˜2Kšžœ ˜Kšž œ˜Kšžœ˜%Kšž œ˜Kšžœ˜!Kšž œ˜Kšž œ˜Kšžœ ˜Kšžœ ˜Kšžœ˜Kšž œ!˜.Kšžœ"˜0Kšžœ˜Kšžœ˜"Kšœ ˜ K˜—K˜Kšœ˜—…—:ΔRG