-- Compiler Text/nb -- Tiberi + Stone February 7, 1980 5:46 PM -- Tiberi January 29, 1980 2:58 PM -- implementing module for Griffin text -- Stone December 28, 1983 5:52 pm -- Last Edited by: Pier, February 13, 1984 5:57:48 pm PST DIRECTORY StyleDefs: FROM "StyleDefs" USING [StyleHandle, Anchor, Orientation], ControllerDefs: FROM "ControllerDefs" USING [CurrentStyle, FontWithNumber], ObjectDefs: FROM "ObjectDefs", Rope USING [ROPE, Cat, Length, Substr, Fetch, FromChar], Graphics USING [Context], IO USING [BS, DEL, ESC, CR, PutFR, rope, int], PointDefs: FROM "PointDefs" USING [ScrPt, ObjPt, X, Y, ScrToObj, ObjToScr, ObjPtSequence], MenuDefs: FROM "MenuDefs", CaretDefs: FROM "CaretDefs", RefreshDefs: FROM "RefreshDefs", GriffinDefs: FROM "GriffinDefs" USING [UserMessage], ScreenDefs: FROM "ScreenDefs" USING [EraseBox], GriffinFontDefs: FROM "GriffinFontDefs"; GriffinText: PROGRAM IMPORTS ObjectDefs, ScreenDefs, IO, ControllerDefs, Rope, MenuDefs, PointDefs, GriffinDefs, GriffinFontDefs, CaretDefs, RefreshDefs EXPORTS GriffinDefs, ObjectDefs = BEGIN ROPE: TYPE = Rope.ROPE; X: INTEGER = PointDefs.X; Y: INTEGER = PointDefs.Y; BW: CHARACTER = 27C; typing: BOOLEAN _ FALSE; textAnchorPt: PointDefs.ObjPt; tl, br, tlMin, brMax: PointDefs.ObjPt; textFont: GriffinFontDefs.FontDescriptorHandle; textReason: {menu, newCaption, oldCaption} _ newCaption; textString: ROPE; textStyle: StyleDefs.StyleHandle _ NIL; textItem: MenuDefs.MenuItemHandle _ NIL; itemWasSelected: BOOLEAN; textCaption: REF ObjectDefs.Object[caption] _ NIL; StartTypeIn: PROCEDURE [pt: PointDefs.ObjPt, style: StyleDefs.StyleHandle, string: ROPE] = BEGIN height, width: REAL; textAnchorPt _ pt; textStyle _ style; textFont _ ControllerDefs.FontWithNumber[style.fontid]; textString _ NIL; IF string # NIL THEN textString _ Rope.Cat[textString, string]; height _ GriffinFontDefs.StringHeight[textString, textFont, style.orientation]; width _ GriffinFontDefs.StringWidth[textString, textFont, style.orientation]; tl _ tlMin _ GriffinFontDefs.TopLeft[pt,height, width, style.anchor, style.orientation,textFont.rotation]; br _ brMax _ [tl[X]+width, tl[Y]-height]; SetCaretPt; typing _ TRUE; END; TypeIntoMenuItem: PUBLIC MenuDefs.MenuProc = BEGIN OPEN MenuDefs; itemWasSelected _ IsSelected[item]; Deselect[item]; StartTypeIn[PointDefs.ScrToObj[MenuAnchorPoint[item]], MenuStyle[], MenuString[item]]; textItem _ item; textReason _ menu; END; TypeIntoCaption: PUBLIC PROCEDURE[caption: ObjectDefs.ObjectHandle] = BEGIN OPEN ControllerDefs; cap: REF ObjectDefs.Object[caption] _ NARROW[caption]; IF caption.style # CurrentStyle[] THEN BEGIN ObjectDefs.EraseObject[caption]; caption.style _ CurrentStyle[]; DisplayCaption[cap, NIL]; END; StartTypeIn[cap.p0, cap.style, cap.text]; textCaption _ cap; textReason _ oldCaption; END; TypeInAtControlPt: PUBLIC PROCEDURE = BEGIN OPEN GriffinDefs; cps: PointDefs.ObjPtSequence _ ObjectDefs.ReadCPs[]; IF cps=NIL OR cps.length # 1 THEN SIGNAL GriffinDefs.UserMessage ["Place exactly one control point for caption."]; StartTypeIn[cps[0], ControllerDefs.CurrentStyle[], NIL]; RefreshDefs.EraseAndSaveAllCPs; ObjectDefs.DeleteAllCPs[]; RefreshDefs.RestoreScreen; textReason _ newCaption; END; TypeIn: PUBLIC PROCEDURE [ch: CHARACTER] = BEGIN SetBB: PROCEDURE = BEGIN height: REAL _ GriffinFontDefs.StringHeight[textString, textFont, textStyle.orientation]; width: REAL _ GriffinFontDefs.StringWidth[textString, textFont, textStyle.orientation]; tl _ GriffinFontDefs.TopLeft[textAnchorPt, height, width, textStyle.anchor, textStyle.orientation, textFont.rotation]; br _ [tl[X]+width, tl[Y]-height]; IF tl[X]tlMin[Y] THEN tlMin _ tl; IF br[X]>brMax[X] OR br[Y] NULL; IO.DEL => BEGIN CaretDefs.WithCaretOff[do: Erase]; textString _ NIL; END; IO.BS => BEGIN len: INT _ Rope.Length[textString]; IF len= 0 THEN RETURN; CaretDefs.WithCaretOff[do: Erase]; textString _ IF len=1 THEN NIL ELSE Rope.Substr[textString,0,len-1]; CaretDefs.WithCaretOff[do: DisplayString]; END; BW => BEGIN i: INTEGER; len: INTEGER _ Rope.Length[textString]; IF len = 0 THEN RETURN; CaretDefs.WithCaretOff[do: Erase]; FOR i DECREASING IN [0..len) DO IF Rope.Fetch[textString,i] # ' THEN EXIT ENDLOOP; FOR i DECREASING IN [0..i) DO IF Rope.Fetch[textString,i] = ' --blank-- THEN BEGIN textString _ Rope.Substr[textString, 0, i+1]; EXIT; END REPEAT FINISHED => textString _ NIL; ENDLOOP; CaretDefs.WithCaretOff[do: DisplayString]; END; ENDCASE => -- normal character BEGIN textString _ Rope.Cat[textString,Rope.FromChar[ch]]; CaretDefs.WithCaretOff[do: Erase]; CaretDefs.WithCaretOff[do: DisplayString]; END; SetBB; SetCaretPt; END; EndTypeIn: PUBLIC PROCEDURE = BEGIN IF ~typing THEN RETURN; CaretDefs.CaretOff; SELECT textReason FROM newCaption, oldCaption => BEGIN IF textReason=newCaption THEN textCaption _ NARROW[ObjectDefs.StartObject[ObjectDefs.ObjectType[caption]]]; textCaption.text _ textString; textCaption.style _ textStyle; textCaption.p0 _ textAnchorPt; textCaption.validEncoding _ FALSE; --this will set the bounding box on display IF textString=NIL THEN []_ObjectDefs.DeleteObject[textCaption] ELSE []_ObjectDefs.SelectObject[textCaption]; RefreshDefs.EraseAndSaveBox[PointDefs.ObjToScr[tlMin], PointDefs.ObjToScr[brMax]]; END; menu => BEGIN MenuDefs.SetMenuString[item: textItem, string: textString]; IF itemWasSelected THEN MenuDefs.Select[textItem]; RefreshDefs.EraseAndSaveBox[PointDefs.ObjToScr[tlMin], PointDefs.ObjToScr[brMax]]; END; ENDCASE => ERROR; typing _ FALSE; RefreshDefs.RestoreScreen; END; DisplayCaption: PUBLIC PROCEDURE [cobject: REF caption ObjectDefs.Object, dc: Graphics.Context] = BEGIN style: StyleDefs.StyleHandle = cobject.style; font: GriffinFontDefs.FontDescriptorHandle_ ControllerDefs.FontWithNumber [style.fontid]; IF ~cobject.validEncoding THEN { --set the bounding box ch: REAL _ GriffinFontDefs.StringHeight[cobject.text, font, style.orientation]; cw: REAL _ GriffinFontDefs.StringWidth[cobject.text, font, style.orientation]; ctl: PointDefs.ObjPt _ GriffinFontDefs.TopLeft[cobject.p0, ch, cw, style.anchor, style.orientation, font.rotation]; cbr: PointDefs.ObjPt _ [ctl[X]+cw, ctl[Y]-ch]; cobject.tl _ PointDefs.ObjToScr[ctl]; cobject.br _ PointDefs.ObjToScr[cbr]; cobject.validEncoding _ TRUE; }; ScreenDefs.EraseBox[cobject.tl,cobject.br,dc]; GriffinFontDefs.DisplayString [cobject.text, cobject.p0, style.anchor, style.orientation, font, dc] END; SetCaretPt: PROCEDURE = BEGIN pt: PointDefs.ObjPt _ NextTL[GriffinFontDefs.MaxWidth[textFont], GriffinFontDefs.MaxHeight[textFont]]; pt[Y] _ pt[Y]-GriffinFontDefs.MaxPosExtent[textFont]; CaretDefs.CaretAt[PointDefs.ObjToScr[pt]]; END; NextTL: PROCEDURE[width, height: REAL] RETURNS [pt: PointDefs.ObjPt] = BEGIN SELECT textStyle.orientation FROM or0 => pt _ [br[X]+32, tl[Y]]; --approx 32 micas/point or90=> pt _ [tl[X], tl[Y]-height]; or180=> pt _ [tl[X]-width, tl[Y]]; or270=> pt _ [tl[X], br[Y]+32]; ENDCASE; END; AppendNumber: PUBLIC PROC [rope: Rope.ROPE, number: INTEGER] RETURNS [Rope.ROPE] = { RETURN[IO.PutFR["%s%d",IO.rope[rope],IO.int[number]]]; }; END.