DIRECTORY Atom USING [MakeAtomFromRefText], BitmapViewer USING [], ImagerBackdoor USING [DrawBits], ImagerPixelMap USING [Create, DeviceRectangle, PixelMap, ShiftMap, Window], Menus USING [CreateMenu, Menu], Real USING [Round], ViewerClasses USING [HBltRule, HScrollProc, InitProc, PaintProc, ScrollProc, VBltRule, Viewer, ViewerClass, ViewerClassRec, ViewerFlavor, ViewerRec], ViewerOps USING [CreateViewer, PaintViewer, RegisterViewerClass]; BitmapViewerImpl: CEDAR PROGRAM IMPORTS Atom, ImagerBackdoor, ImagerPixelMap, Menus, Real, ViewerOps EXPORTS BitmapViewer = BEGIN PixelMap: TYPE ~ ImagerPixelMap.PixelMap; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; Viewer: TYPE ~ ViewerClasses.Viewer; ViewerData: TYPE ~ REF ViewerDataRep; ViewerFlavor: TYPE ~ ViewerClasses.ViewerFlavor; HBltRule: TYPE ~ ViewerClasses.HBltRule; VBltRule: TYPE ~ ViewerClasses.VBltRule; ViewerDataRep: TYPE = RECORD [ sShift: INTEGER _ 0, fShift: INTEGER _ 0, tx, ty: INTEGER, bitmap: PixelMap _ ImagerPixelMap.Create[0, [0,0,0,0]] ]; Create: PUBLIC PROC [info: ViewerClasses.ViewerRec _ [], paint: BOOL _ TRUE, bltH: HBltRule _ left, bltV: VBltRule _ top] RETURNS [Viewer] ~ { RETURN [ViewerOps.CreateViewer[GetFlavor[bltH, bltV], info, paint]]; }; GetFlavor: PUBLIC PROC [bltH: HBltRule, bltV: VBltRule] RETURNS [ViewerFlavor] ~ { RETURN [flavor[bltH][bltV]]; }; SetBitmap: PUBLIC PROC [viewer: Viewer, bitmap: PixelMap] ~ { data: ViewerData _ NARROW[viewer.data]; data.bitmap _ bitmap; ViewerOps.PaintViewer[viewer, client, FALSE]; }; GetBitmap: PUBLIC PROC [viewer: Viewer] RETURNS [bitmap: PixelMap] ~ { data: ViewerData _ NARROW[viewer.data]; bitmap _ data.bitmap; }; TouchUp: PUBLIC PROC [viewer: Viewer, deviceRectangle: DeviceRectangle] ~ { ViewerOps.PaintViewer[viewer, client, FALSE]; }; ViewerInit: ViewerClasses.InitProc = TRUSTED { viewerData: ViewerData _ NEW[ViewerDataRep]; menu: Menus.Menu _ Menus.CreateMenu[1]; viewerData.sShift _ 0; viewerData.fShift _ 0; self.data _ viewerData; self.menu _ menu; }; Percent: PROC [r: REAL] RETURNS [INTEGER] ~ { RETURN [Real.Round[MIN[MAX[r, 0], 1]*100]]; }; ComputePercentages: PROC [self: Viewer] RETURNS [top, bottom: INTEGER] = { data: ViewerData _ NARROW [self.data]; bitmapSize: REAL _ data.bitmap.sSize; viewerSize: REAL _ self.ch; topPos: REAL _ data.ty; bottomPos: REAL _ topPos-bitmapSize; top _ Percent[(topPos-viewerSize)/MAX[bitmapSize, 1]]; bottom _ Percent[1.0+bottomPos/MAX[bitmapSize, 1]]; }; ComputeHPercentages: PROC [self: Viewer] RETURNS [left, right: INTEGER] = { data: ViewerData _ NARROW [self.data]; bitmapSize: REAL _ data.bitmap.fSize; viewerSize: REAL _ self.cw; leftPos: REAL _ data.tx; rightPos: REAL _ leftPos+bitmapSize; left _ Percent[-leftPos/MAX[bitmapSize, 1]]; right _ Percent[1.0-(rightPos-viewerSize)/MAX[bitmapSize, 1]]; }; ViewerScroll: ViewerClasses.ScrollProc = TRUSTED { data: ViewerData _ NARROW [self.data]; IF data = NIL OR op = query THEN {[top, bottom] _ ComputePercentages[self]; RETURN}; IF op = thumb THEN {data.sShift _ 0; ViewerOps.PaintViewer[self, client]; RETURN}; IF amount = 0 THEN RETURN; IF op = down THEN amount _ -amount; data.sShift _ data.sShift - amount; ViewerOps.PaintViewer[self, client]; RETURN; }; ViewerHScroll: ViewerClasses.HScrollProc = TRUSTED { data: ViewerData _ NARROW [self.data]; IF data = NIL OR op = query THEN {[left, right] _ ComputeHPercentages[self]; RETURN}; IF op = thumb THEN {data.fShift _ 0; ViewerOps.PaintViewer[self, client]; RETURN}; IF amount = 0 THEN RETURN; IF op = right THEN amount _ -amount; data.fShift _ data.fShift - amount; ViewerOps.PaintViewer[self, client, TRUE]; RETURN; }; NormalizeData: PROC [viewer: Viewer] RETURNS [ViewerData] ~ { data: ViewerData ~ NARROW[viewer.data]; b: DeviceRectangle ~ data.bitmap.ShiftMap[data.sShift, data.fShift].Window; ox: INT ~ SELECT viewer.class.bltH FROM none, left => 0, center => viewer.cw/2, right => viewer.cw, ENDCASE => ERROR; oy: INT ~ SELECT viewer.class.bltV FROM none, top => viewer.ch, center => viewer.ch/2, bottom => 0, ENDCASE => ERROR; bx: INT _ b.fMin; by: INT _ -b.sSize-b.sMin; bw: INT ~ b.fSize; bh: INT ~ b.sSize; IF ox + bx >= viewer.cw THEN bx _ viewer.cw - ox - 1; IF ox + bx + bw <= 0 THEN bx _ - ox - bw + 1; IF oy + by >= viewer.ch THEN by _ viewer.ch - oy - 1; IF oy + by + bh <= 0 THEN by _ - oy - bh + 1; data.fShift _ data.fShift + (bx-b.fMin); data.sShift _ data.sShift - (by-(-b.sSize-b.sMin)); data.tx _ bx; data.ty _ oy + by + bh; RETURN [data] }; ViewerPaint: ViewerClasses.PaintProc = { data: ViewerData _ NormalizeData[self]; bits: PixelMap _ data.bitmap.ShiftMap[data.sShift, data.fShift]; ImagerBackdoor.DrawBits[context: context, base: bits.refRep.pointer, wordsPerLine: bits.refRep.rast, sMin: bits.sMin, fMin: bits.fMin, sSize: bits.sSize, fSize: bits.fSize, tx: data.tx, ty: data.ty]; }; viewerClass: REF ARRAY HBltRule OF ARRAY VBltRule OF ViewerClasses.ViewerClass; flavor: REF ARRAY HBltRule OF ARRAY VBltRule OF ViewerClasses.ViewerFlavor; Init: PROC ~ { txt: REF TEXT ~ "BitmapViewerHV"; viewerClass _ NEW[ARRAY HBltRule OF ARRAY VBltRule OF ViewerClasses.ViewerClass]; flavor _ NEW[ARRAY HBltRule OF ARRAY VBltRule OF ViewerClasses.ViewerFlavor]; FOR hblt: HBltRule IN HBltRule DO txt[txt.length-2] _ '0+ORD[hblt]; FOR vblt: VBltRule IN VBltRule DO txt[txt.length-1] _ '0+ORD[vblt]; flavor[hblt][vblt] _ Atom.MakeAtomFromRefText[txt]; viewerClass[hblt][vblt] _ NEW [ViewerClasses.ViewerClassRec _ [ init: ViewerInit, paint: ViewerPaint, scroll: ViewerScroll, hscroll: ViewerHScroll, bltH: hblt, bltV: vblt, icon: tool ]]; ViewerOps.RegisterViewerClass[flavor[hblt][vblt], viewerClass[hblt][vblt]]; ENDLOOP; ENDLOOP; }; Init[]; END. BitmapViewerImpl.mesa Copyright (C) 1984, Xerox Corporation. All rights reserved. Michael Plass, July 11, 1985 4:43:52 pm PDT HScrollHit: Menus.ClickProc = TRUSTED { viewer: ViewerClasses.Viewer _ NARROW[parent]; data: ViewerData _ NARROW[viewer.data]; IF data = NIL THEN RETURN; data.fShift _ data.fShift + (IF mouseButton = red THEN -64 ELSE 64); IF mouseButton = yellow THEN data.fShift _ 0; ViewerOps.PaintViewer[viewer, client, TRUE]; }; Menus.InsertMenuEntry[menu, Menus.CreateEntry[name: "<<<-->>>", proc: HScrollHit]]; Κ˜šœ™J™˜DJšœ˜J˜—codešŸ œœœ"œ˜RKšœ˜Kšœ˜K˜—šŸ œœœ'˜=Jšœœ˜'Jšœ˜Jšœ&œ˜-Jšœ˜—J˜šŸ œœœœ˜FJšœœ˜'Jšœ˜Jšœ˜J˜—šŸœœœ7˜KJšœ&œ˜-Jšœ˜J˜—šŸ œœ™'Jšœœ ™.Jšœœ™'Jšœœœœ™Jšœœœœ™DJšœœ™-Jšœ&œ™,J™J™—šŸ œœ˜.Jšœœ˜,Jšœ'˜'JšœS™SJšœ˜Jšœ˜Jšœ˜Jšœ˜J˜J˜—š Ÿœœœœœ˜-Kšœ œœ˜+Kšœ˜K˜—šŸœœœœ˜JJšœœ ˜&Jšœ œ˜%Jšœ œ ˜Jšœœ ˜Jšœ œ˜$Jšœ"œ˜6Jšœœ˜3J˜J˜—šŸœœœœ˜KJšœœ ˜&Jšœ œ˜%Jšœ œ ˜Jšœ œ ˜Jšœ œ˜$Jšœœ˜,Jšœ*œ˜>J˜J˜—šŸ œœ˜2Jšœœ ˜&Jš œœœ œ,œ˜TJšœ œ7œ˜RJšœ œœ˜Jšœ œ˜#Jšœ#˜#J˜$Jšœ˜J˜J˜—šŸ œœ˜4Jšœœ ˜&Jš œœœ œ-œ˜UJšœ œ7œ˜RJšœ œœ˜Jšœ œ˜$Jšœ#˜#Jšœ$œ˜*Jšœ˜J˜J˜—šŸ œœœ˜=Jšœœ˜'JšœK˜Kšœœœ˜'Kšœ˜Kšœ˜Kšœ˜Kšœœ˜—šœœœ˜'Kšœ˜Kšœ˜Kšœ ˜ Kšœœ˜—Jšœœ ˜Jšœœ˜Jšœœ ˜Jšœœ ˜Jšœœ˜5Jšœœ˜-Jšœœ˜5Jšœœ˜-Jšœ(˜(Jšœ3˜3Jšœ ˜ Jšœ˜Jšœ˜ Jšœ˜J˜—šŸ œ˜(Jšœ'˜'Jšœ@˜@JšœΗ˜ΗJ˜J˜—š œ œœ œœ œ˜OJ˜—š œœœ œœ œ˜LJ˜—šŸœœ˜Kšœœœ˜!Kš œœœ œœ œ˜QKš œ œœ œœ œ˜Mšœœ ˜!Kšœœ˜!šœœ ˜!Kšœœ˜!Kšœ3˜3šœœ"˜?Jšœ˜Jšœ˜Jšœ˜Jšœ˜Kšœ ˜ Kšœ ˜ J˜ J˜—JšœK˜KKšœ˜—Kšœ˜—Kšœ˜K˜—J˜J˜—Jšœ˜—…—Dέ