-- Compiler Text/nb -- Tiberi + Stone February 7, 1980 5:46 PM -- Tiberi January 29, 1980 2:58 PM -- implementing module for Griffin text DIRECTORY StyleDefs: FROM "StyleDefs" USING [StyleHandle, Anchor, Orientation], GriffinMemoryDefs: FROM "GriffinMemoryDefs" USING [AllocateString, FreeString, Free], ControllerDefs: FROM "ControllerDefs" USING [CurrentStyle, FontWithNumber], ObjectDefs: FROM "ObjectDefs", StringDefs: FROM "StringDefs" USING [AppendString], IODefs: FROM "IODefs" USING [BS, DEL, ESC, CR], PointDefs: FROM "PointDefs" USING [ScrPt, ObjPt, X, Y, ScrToObj, ObjToScr, ObjValToScrVal], BitBltDefs: FROM "BitBltDefs" USING [BBoperation], MenuDefs: FROM "MenuDefs", CaretDefs: FROM "CaretDefs", RefreshDefs: FROM "RefreshDefs", GriffinDefs: FROM "GriffinDefs" USING [UserMessage], ScreenDefs: FROM "ScreenDefs" USING [MoveScreenBox, EraseBox, SetFunction], GriffinFontDefs: FROM "GriffinFontDefs"; Text: PROGRAM IMPORTS GriffinMemoryDefs, ObjectDefs, ScreenDefs, ControllerDefs, StringDefs, MenuDefs, PointDefs, GriffinDefs, GriffinFontDefs, CaretDefs, RefreshDefs EXPORTS GriffinDefs, ObjectDefs = BEGIN OPEN GriffinFontDefs; X: CARDINAL = PointDefs.X; Y: CARDINAL = PointDefs.Y; BW: CHARACTER = 27C; maxStringLength: CARDINAL = 200; typing: BOOLEAN _ FALSE; textAnchorPt: PointDefs.ObjPt; tlCaret, tl, br, tlMax, brMax: PointDefs.ScrPt; textFont: GriffinFontDefs.FontDescriptor; textReason: {menu, newCaption, oldCaption} _ newCaption; textString: STRING = [maxStringLength]; textStyle: StyleDefs.StyleHandle _ NIL; textItem: MenuDefs.MenuItemHandle _ NIL; itemWasSelected: BOOLEAN; textCaption: ObjectDefs.ObjectHandle _ NIL; StartTypeIn: PROCEDURE [pt: PointDefs.ScrPt, style: StyleDefs.StyleHandle, string: STRING] = BEGIN OPEN GriffinFontDefs; height, width: CARDINAL; textAnchorPt _ PointDefs.ScrToObj[pt]; textStyle _ style; textFont _ ControllerDefs.FontWithNumber[style.fontid]; textString.length _ 0; IF string # NIL THEN StringDefs.AppendString[textString, string]; height _ StringHeight[textString, @textFont, style.orientation]; width _ StringWidth[textString, @textFont, style.orientation]; tl _ tlMax _ PointDefs.ObjToScr[TopLeft[PointDefs.ScrToObj[pt], height, width, style.anchor, style.orientation, textFont.rotation]]; br _ brMax _ [tl[X]+PointDefs.ObjValToScrVal[width], tl[Y]+PointDefs.ObjValToScrVal[height]]; SetCaretPt; typing _ TRUE; END; TypeIntoMenuItem: PUBLIC MenuDefs.MenuProc = BEGIN OPEN MenuDefs; itemWasSelected _ IsSelected[item]; Deselect[item]; StartTypeIn[MenuAnchorPoint[item], MenuStyle[], MenuString[item]]; textItem _ item; textReason _ menu; END; TypeIntoCaption: PUBLIC PROCEDURE[caption: ObjectDefs.ObjectHandle] = BEGIN OPEN ControllerDefs; WITH cap: caption SELECT FROM caption => BEGIN IF caption.style # CurrentStyle[] THEN BEGIN ObjectDefs.EraseObject[caption]; caption.style _ CurrentStyle[]; DisplayCaption[@cap]; END; StartTypeIn[PointDefs.ObjToScr[cap.p0], cap.style, cap.text]; END; ENDCASE => ERROR; textCaption _ caption; textReason _ oldCaption; END; TypeInAtControlPt: PUBLIC PROCEDURE = BEGIN OPEN GriffinDefs; pt: PointDefs.ScrPt; cps: DESCRIPTOR FOR ARRAY OF PointDefs.ObjPt _ ObjectDefs.ReadCPs[]; IF LENGTH[cps] # 1 THEN SIGNAL GriffinDefs.UserMessage ["Place exactly one control point for caption."]; pt _ PointDefs.ObjToScr[cps[0]]; StartTypeIn[pt, ControllerDefs.CurrentStyle[], NIL]; RefreshDefs.EraseAndSaveAllCPs; ObjectDefs.DeleteAllCPs[]; GriffinMemoryDefs.Free[BASE[cps]]; RefreshDefs.RestoreScreen; textReason _ newCaption; END; TypeIn: PUBLIC PROCEDURE [ch: CHARACTER] = BEGIN OPEN StyleDefs; bltpt: PointDefs.ScrPt; tlOld,brOld: PointDefs.ScrPt; twiddle: CARDINAL; width: CARDINAL; height: CARDINAL; font: GriffinFontDefs.FontDescriptorHandle = @textFont; vertical, aligned: BOOLEAN; SetBB: PROCEDURE = BEGIN IF tl[X]brMax[X] OR br[Y]>brMax[Y] THEN brMax _ br; height _ StringHeight[textString, @textFont, textStyle.orientation]; width _ StringWidth[textString, @textFont, textStyle.orientation]; tl _ PointDefs.ObjToScr[TopLeft[textAnchorPt, height, width, textStyle.anchor, textStyle.orientation, textFont.rotation]]; br _ [tl[X]+PointDefs.ObjValToScrVal[width], tl[Y]+PointDefs.ObjValToScrVal[height]]; IF tl[X]brMax[X] OR br[Y]>brMax[Y] THEN brMax _ br; END; Erase: PROCEDURE = BEGIN ScreenDefs.EraseBox [tl, br] END; DisplayString: PROCEDURE = BEGIN GriffinFontDefs.DisplayString[textString, PointDefs.ObjToScr[textAnchorPt], textStyle.anchor, textStyle.orientation, @textFont]; END; IF ~typing THEN BEGIN TypeInAtControlPt; END; vertical _ textStyle.orientation = or90 OR textStyle.orientation = or270; aligned _ IF vertical THEN font.rotation = Rot0Degrees OR font.rotation = Rot180Degrees ELSE font.rotation = Rot90Degrees OR font.rotation = Rot270Degrees; SELECT ch FROM IODefs.ESC, IODefs.CR => NULL; IODefs.DEL => BEGIN CaretDefs.WithCaretOff[do: Erase]; textString.length _ 0; SetBB; SetCaretPt; RETURN; END; IODefs.BS => BEGIN IF textString.length = 0 THEN RETURN; CaretDefs.WithCaretOff[do: Erase]; textString.length _ textString.length - 1; CaretDefs.WithCaretOff[do: DisplayString]; SetBB; SetCaretPt; RETURN; END; BW => BEGIN i: CARDINAL; IF textString.length = 0 THEN RETURN; CaretDefs.WithCaretOff[do: Erase]; FOR i DECREASING IN [0..textString.length) DO IF textString[i] # ' THEN EXIT ENDLOOP; FOR i DECREASING IN [0..i) DO IF textString[i] = ' --blank-- THEN BEGIN textString.length _ i+1; EXIT; END REPEAT FINISHED => textString.length _ 0; ENDLOOP; CaretDefs.WithCaretOff[do: DisplayString]; SetBB; SetCaretPt; RETURN; END; ENDCASE => -- normal character BEGIN ShowChar: PROCEDURE = BEGIN ScreenDefs.SetFunction[replace]; GriffinFontDefs.BltChar [ch, bltpt, font] END; IF textString.length = maxStringLength THEN SIGNAL GriffinDefs.UserMessage["String too long."]; bltpt _ NextTL[Width[ch, font], Height[ch, font]]; width _ PointDefs.ObjValToScrVal[Width[ch, font]]; height _ PointDefs.ObjValToScrVal[Height[ch, font]]; twiddle _ IF vertical THEN (PointDefs.ObjValToScrVal[MaxWidth[font]] - width)/2 ELSE (PointDefs.ObjValToScrVal[MaxHeight[font]] - height)/2; IF aligned THEN IF vertical THEN bltpt[X] _ bltpt[X] + twiddle ELSE bltpt[Y] _ bltpt[Y] + twiddle; CaretDefs.WithCaretOff[do: ShowChar]; IF aligned THEN IF vertical THEN bltpt[X] _ bltpt[X] - twiddle ELSE bltpt[Y] _ bltpt[Y] - twiddle; SELECT textStyle.orientation FROM or0 => br[X] _ br[X] + width; or90 => tl[Y] _ bltpt[Y]; or180 => tl[X] _ bltpt[X]; or270 => br[Y] _ br[Y] + height; ENDCASE; textString [textString.length] _ ch; textString.length _ textString.length + 1; END; tlOld _ tl; brOld _ br; SetBB; SetCaretPt; SELECT textStyle.anchor FROM left => NULL; center, right => BEGIN Move: PROCEDURE = BEGIN ScreenDefs.MoveScreenBox [tlOld, brOld, tl[X]-tlOld[X], tl[Y]-tlOld[Y]]; END; Erase: PROCEDURE = BEGIN ScreenDefs.EraseBox[tlSlop, brSlop]; END; tlSlop, brSlop: PointDefs.ScrPt; CaretDefs.WithCaretOff[do: Move]; SELECT textStyle.orientation FROM or0 => BEGIN tlSlop _ [br[X]+1, tl[Y]]; brSlop _ brOld; END; or90 => BEGIN tlSlop _ tlOld; brSlop _ [br[X], tl[Y]-1]; END; or180 => BEGIN tlSlop _ tlOld; brSlop _ [tl[X]-1, br[Y]]; END; or270 => BEGIN tlSlop _ [tl[X], br[Y]+1]; brSlop _ brOld; END; ENDCASE; CaretDefs.WithCaretOff[do: Erase]; END; ENDCASE; END; EndTypeIn: PUBLIC PROCEDURE = BEGIN string: STRING; IF ~typing THEN RETURN; CaretDefs.CaretOff; SELECT textReason FROM newCaption => BEGIN -- put caption in object list textCaption _ ObjectDefs.StartObject[ObjectDefs.ObjectType [caption]]; textCaption.validEncoding _ TRUE; textCaption.body _ caption[p0: [0,0], text: NIL]; textReason _ oldCaption; EndTypeIn[]; --note recursion END; oldCaption => WITH cap: textCaption SELECT FROM caption => BEGIN IF cap.text # NIL THEN GriffinMemoryDefs.FreeString[cap.text]; string _ GriffinMemoryDefs.AllocateString [textString.length]; StringDefs.AppendString [string, textString]; cap.style _ textStyle; cap.body _ caption [p0: textAnchorPt, text: string]; cap.tl _ tl; cap.br _ br; IF textString.length=0 THEN []_ObjectDefs.DeleteObject[textCaption] ELSE []_ObjectDefs.SelectObject[textCaption]; RefreshDefs.EraseAndSaveBox[tlMax, brMax]; END; ENDCASE => ERROR; menu => BEGIN MenuDefs.SetMenuString[item: textItem, string: textString]; IF itemWasSelected THEN MenuDefs.Select[textItem]; RefreshDefs.EraseAndSaveBox[tlMax, brMax]; END; ENDCASE => ERROR; typing _ FALSE; RefreshDefs.RestoreScreen; END; DisplayCaption: PUBLIC PROCEDURE [cobject: POINTER TO caption ObjectDefs.Object] = BEGIN style: StyleDefs.StyleHandle = cobject.style; pt: PointDefs.ObjPt = cobject.p0; font: GriffinFontDefs.FontDescriptor _ ControllerDefs.FontWithNumber [style.fontid]; height: CARDINAL _ StringHeight[cobject.text, @font, style.orientation]; width: CARDINAL _ StringWidth[cobject.text, @font, style.orientation]; cobject.tl _ PointDefs.ObjToScr[TopLeft[pt, height, width, style.anchor, style.orientation, font.rotation]]; cobject.br _ [cobject.tl[X]+PointDefs.ObjValToScrVal[width], cobject.tl[Y]+PointDefs.ObjValToScrVal[height]]; cobject.validEncoding _ TRUE; ScreenDefs.EraseBox[cobject.tl,cobject.br]; GriffinFontDefs.DisplayString [cobject.text, PointDefs.ObjToScr[pt], style.anchor, style.orientation, @font] END; SetCaretPt: PROCEDURE = BEGIN pt: PointDefs.ScrPt; tlCaret _ NextTL[MaxWidth[@textFont], MaxHeight[@textFont]]; pt _ [tlCaret[X], tlCaret[Y]+PointDefs.ObjValToScrVal[BaseLine[@textFont]]]; CaretDefs.CaretAt[pt]; END; NextTL: PROCEDURE[width, height: CARDINAL] RETURNS [pt: PointDefs.ScrPt] = BEGIN SELECT textStyle.orientation FROM or0 => pt _ [br[X]+1, tl[Y]]; or90=> pt _ [tl[X], tl[Y]-PointDefs.ObjValToScrVal[height]]; or180=> pt _ [tl[X]-PointDefs.ObjValToScrVal[width], tl[Y]]; or270=> pt _ [tl[X], br[Y]+1]; ENDCASE; END; END.