-- 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]<tlMax[X] OR tl[Y]<tlMax[Y] THEN tlMax ← tl;
IF br[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]<tlMax[X] OR tl[Y]<tlMax[Y] THEN tlMax ← tl;
IF br[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.