// F E D I T L O O P (PREPRESS)
//
// FEDIT -- font editor for low resolution fonts.
//
//Bcpl/f FEditLoop.bcpl
//
//Last modified February 5, 1980 1:16 PM by Kerry A. LaPrade, XEOS
// Split out initialization stuff. Added full octal capability
// for "Show TypeIn". Reworked "File Character" section of
// user interface.
//Modified: December 17, 1979 10:40 AM (by LaPrade)
// Added gnat to update box; changed Consec box default
//Modified: December 10, 1979 11:15 AM (by LaPrade)
//Modified: December 3, 1979 10:52 AM (by LaPrade)
//Modified: November 30, 1979 9:47 AM (by LaPrade)
//Modified: September 12, 1978 (by LaPrade)
get "AuxiliaryMenuDefs.d"
get "FEdit.DFS"
get "FEditNames.d"
// outgoing procedures
external
[
ClearEditWindow
FEditLoop
WriteCharCodes
]
// outgoing statics
external
[
@backgroundArea
@backgroundOn
@backgroundView
@bits //bits!0 = #100000
@currentCharacterCode //0 to 377b
@currentCharacterWidths
@editBox
@editBoxXSize
@editBoxYSize
@EFactorX //Enlargement factor of background
@EFactorY
@FEditMenu
@foregroundView
@readBBT
@readBit
@showBox
@showBoxXSize
@showBoxYSize
@showTypeInString
@updateBox
@WidthChanged //true if width marker moved
@WidthMarker //Vector of width information (index by border #)
]
static
[
@backgroundArea
@backgroundOn = true
@backgroundView
@bits //bits!0 = #100000
@currentCharacterCode = 377b //0 to 377b
@currentCharacterWidths
@editBox
@editBoxXSize
@editBoxYSize
@EFactorX //Enlargement factor of background
@EFactorY
@FEditMenu
@foregroundView
@readBBT
@readBit
@showBox
@showBoxXSize
@showBoxYSize
@showTypeInString
@updateBox
@WidthChanged = false //true if width marker moved
@WidthMarker //Vector of width information (index by border #)
]
// incoming procedures
external
[
//FEDITFILE
// Area
EditFindChar
EditReadChar
EditUnWriteChar
EditWriteChar
// EFileFinish
// EFileStart
//FEDITUTIL
FEditMemoryAlloc
FlipGrid
PaintString
PaintWidthMarker
ReadCharBit
TurnGridOff
WriteCharBit
//FLOAT
FDV
FLDI
//PREPRESSUTIL
FSGetX
FSPut
IllCommand
//SCAN
AppendChar
SearchChar
StringToValue
TypeForm
//STRINGSTREAMS
CreateStringStream
//STRINGUTIL
CopyString
ExtractSubstring
]
// incoming statics
external
[
//FEDITFILE
@LastCharCodeWritten
//FEDITUTIL
@gridIsDesired //True if user wants grid displayed
@gridIsOn //True if grid is on
//PREPRESSMENU1
@selectedBoxNum
@selectedButton
]
// internal statics
static
[
editState
currentBackgroundOffsetx //Current background offset in x.
currentBackgroundOffsety // ditto for y
cursorPattern
gnatIsDesired = true
needToGetBackground
startSequenceChar = 0
widthsMode = false
]
manifest
[
backSpace = 10b
editStateGetDelete = 1
editStatePutCancel = 2
editStateGetUnwrite = 3
]
//Procedures
//*********************************************************
let FEditLoop() be
//*********************************************************
[FEditLoop
[EditLooprepeat
unless (gridIsDesired eqv gridIsOn) do FlipGrid()
//Poll "active" boxes.
// ScanMenu(Menu, loopOverMenu [true], returnKey [false], sweep [false])
let s = ScanMenu(FEditMenu, false, true)
selectedBoxNum = s<<SELECTION.boxNumber
selectedButton = GetMouseButton(s)
let selectedBox = FEditMenu!selectedBoxNum
test selectedBoxNum
ifso
[ifso
Wl("") //Scroll message window so user won't be confused by old messages
test selectedBoxNum eq bWidths
ifso
[
test widthsMode
ifso
[
FillBox(selectedBox, flip)
DeActivateWidths()
]
ifnot ActivateWidths()
]
ifnot if widthsMode then DeActivateWidths()
switchon selectedBoxNum into
[
case bSymbol:
case bOctal:
ReadCharCode(selectedBoxNum)
endcase
case bGetPut:
test editState eq editStatePutCancel
ifso
[
PutChar()
ClearEditWindow()
ChangeBoxes(editStateGetUnwrite)
FillBox(selectedBox, flip)
]
ifnot GetNewCharacter()
endcase
case bAuto:
Auto()
endcase
case bDeleteCancelUnwrite:
DeleteCancelUnwrite(s)
endcase
case bGrid:
gridIsDesired = not gridIsDesired
endcase
case bShiftBackground:
ShiftBackground()
endcase
//case bWidths:
// unless widthsMode do ActivateWidths()
//endcase
case bBkgrnd:
backgroundOn = not backgroundOn
GetBackground(currentCharacterCode, currentBackgroundOffsetx, currentBackgroundOffsety)
endcase
case bArea:
Area()
endcase
case bUpdateBox:
gnatIsDesired = not gnatIsDesired
endcase
case bQuit:
if ((LastCharCodeWritten eq -1 & editState eq editStateGetDelete) ? true, ConfirmMenuSelection("Quit", s)) then
[
PutChar()
return
]
endcase
case bShowBox:
case bShowSequence:
case bShowTypeIn:
Show()
endcase
]
unless selectedBoxNum eq bWidths do DeSelect(selectedBox)
]ifso
//Poll "edit" box (inactive)
ifnot
[
test widthsMode
ifso TickMarks()
ifnot
if CursorInside(editBox, 0, 0) then Draw()
]
]EditLooprepeat
repeat
]FEditLoop
//Utilities....
//*********************************************************
and DeleteThisCharacter() be
//*********************************************************
[
FillBox(editBox, flip, 0)
unless ConfirmMenuSelection("Are you sure you want to delete this character?") do
[
FillBox(editBox, flip, 0)
return
]
let w = vec (size CharWidth / 16)
if EditFindChar(currentCharacterCode, w, 1) % EditFindChar(currentCharacterCode, w, 2) then
EditWriteChar(currentCharacterCode, true, w)
]
//*********************************************************
and ReadCharCode(boxNumber) be
//*********************************************************
[
until Endofs(keys) do Gets(keys)
if selectedBoxNum eq bGetPut then FillBox(FEditMenu!boxNumber, flip)
switchon boxNumber into
[
case bGetPut:
currentCharacterCode = LastCharCodeWritten
endcase
case bSymbol:
[
currentCharacterCode = Gets(keys)
]
repeatuntil Endofs(keys)
endcase
case bOctal:
let string = vec 1; string!0 = 0
for I = 1 to 3 do
[
let temp = Gets(keys)
unless (temp ge $0) & (temp le $7) do break
AppendChar(temp, string)
FillBox(FEditMenu!bOctal, white, 0)
WriteBox(FEditMenu!bOctal, string)
FillBox(FEditMenu!bOctal, flip, 0)
]
currentCharacterCode = StringToValue(string, 8)
endcase
]
WriteCharCodes(currentCharacterCode)
unless selectedBoxNum eq bGetPut do FillBox(FEditMenu!boxNumber, flip)
]
//*********************************************************
and WriteCharCodes(code) be
//*********************************************************
[
if code ge 400b then code = 0
if code ls 0 then code = 377b
let string = vec 1; string!0 = 0
test code ls $*s
ifso
[
AppendChar($↑, string)
AppendChar(code + $@, string)
]
ifnot AppendChar(code, string)
OverwriteBox(FEditMenu!bSymbol, string)
let stringStream = CreateStringStream(string, 3)
if code ls 100b then
[
Puts(stringStream, $0)
if code ls 10b then Puts(stringStream, $0)
]
Wns(stringStream, code, 0, 10b)
Closes(stringStream)
OverwriteBox(FEditMenu!bOctal, string)
ChangeBoxes(((code eq LastCharCodeWritten) ? editStateGetUnwrite, editStateGetDelete))
currentCharacterCode = code
]
//*********************************************************
and Auto() be
//*********************************************************
[
PutChar()
let w = vec (size CharWidth / 16)
let direction = selecton selectedButton into
[
case 1: 1
case 2: 0
case 3: -1
]
if direction ne 0 then
[
let quitLoop = false
[
currentCharacterCode = currentCharacterCode + direction
WriteCharCodes(currentCharacterCode)
for J = 1 to 3 do
if EditFindChar(currentCharacterCode, w, J) then
quitLoop = true
if quitLoop then break
switchon direction into
[
case -1: if currentCharacterCode eq 0 then return
endcase
case 1: if currentCharacterCode eq 377b then return
]
]
repeat
]
NewChar()
]
//*********************************************************
and GetNewCharacter() be
//*********************************************************
[
let boxNum = selecton selectedButton into
[
case 1: bSymbol
case 2: bOctal
case 3: selectedBoxNum
]
ReadCharCode(boxNum)
NewChar()
FillBox(FEditMenu!bGetPut, flip)
]
//*********************************************************
and NewChar(useLatestVersionOfChar; numargs na) be
//*********************************************************
[
DefaultArgs(lv na, 0, true)
FillBox(FEditMenu!bGetPut, flip)
let changeIt = false
let a = EditFindChar(currentCharacterCode, currentCharacterWidths, 1) //Check scratch file.
test (a ne 0) & useLatestVersionOfChar
ifso
[
Wl("Getting character from *"ACEdits*" file . . .")
changeIt = currentCharacterCode eq LastCharCodeWritten
WidthChanged = valof
[
let w = vec (size CharWidth / 16)
let temp = EditFindChar(currentCharacterCode, w, 2)
for I = 0 to (size CharWidth / 16) - 1 do
if w!I ne currentCharacterWidths!I then resultis true
resultis false
]
a = EditFindChar(currentCharacterCode, currentCharacterWidths, 1) //Position file window again just in case.
]
ifnot
[
a = EditFindChar(currentCharacterCode, currentCharacterWidths, 2) //Use original file.
if a ne 0 then Wl("Getting character from original file . . .")
]
TurnGridOff()
WriteCharBit(foregroundView) //Erase foreground
if a ne 0 then
EditReadChar(foregroundView, a, currentCharacterWidths)
GetBackground(currentCharacterCode, 0, 0)
ChangeBoxes(changeIt ? editStateGetUnwrite, editStateGetDelete)
]
//*********************************************************
and ClearEditWindow() be
//*********************************************************
[
FillBox(editBox, flip, 0)
// changes = false
// changesPending = false
// widthsMode = false
WidthChanged = false
ChangeBoxes(editStateGetDelete)
//Erase tick marks
FillBox(FEditMenu!bLeftBorder, white, 0)
FillBox(FEditMenu!bRightBorder, white, 0)
FillBox(FEditMenu!bBottomBorder, white, 0)
FillBox(FEditMenu!bTopBorder, white, 0)
Zero(WidthMarker, 7)
//Erase updateBox
FillBox(updateBox, white, 0)
//Erase edit area
FillBox(editBox, white, 0)
gridIsOn = false
]
//*********************************************************
and PutChar() be
//*********************************************************
[
unless editState eq editStatePutCancel do return
unless selectedBoxNum eq bGetPut do FillBox(FEditMenu!bGetPut, flip)
EditWriteChar(currentCharacterCode, false, currentCharacterWidths)
unless selectedBoxNum eq bGetPut do FillBox(FEditMenu!bGetPut, flip)
// ClearEditWindow()
ChangeBoxes(editStateGetUnwrite)
if selectedBoxNum eq bGetPut then FillBox(FEditMenu!bGetPut, flip)
]
//*********************************************************
and GetBackground(char, xof, yof) be
//*********************************************************
[
currentBackgroundOffsetx = xof //Save for motions.
currentBackgroundOffsety = yof
WriteCharBit(backgroundView) //Clear it.
unless backgroundOn do return
let w = vec (size CharWidth / 16)
let a = EditFindChar(char, w, 3) //Background
if a then EditReadChar(backgroundView, a, w, xof, yof)
]
//*********************************************************
and ShiftBackground() be
//*********************************************************
[
let xyPair1 = vec 1
let xyPair2 = vec 1
until CursorInside(FEditMenu!bShiftBackground) & GetButtons() do
[
if CursorInside2(editBox, 0, 0, xyPair1) & GetButtons() then
[
while GetButtons() do Noop()
[
if CursorInside2(editBox, 0, 0, xyPair2) & GetButtons() then
[
let dx = (xyPair2!0 - xyPair1!0) / backgroundView>>VIEW.dotSize
let dy = - (xyPair2!1 - xyPair1!1) / backgroundView>>VIEW.dotSize
GetBackground(currentCharacterCode, currentBackgroundOffsetx + dx, currentBackgroundOffsety + dy)
return // break
]
]
repeatuntil CursorInside(FEditMenu!bShiftBackground) & GetButtons()
]
]
while GetButtons() do Noop()
]
//*********************************************************
and ActivateWidths() be
//*********************************************************
[
OutlineBorderBoxes(black)
let t = table
[
000000b;
000000b;
000000b;
000000b;
000400b;
000400b;
000400b;
007740b;
000400b;
000400b;
000400b;
000000b;
000000b;
000000b;
000000b;
000000b;
]
cursorPattern = t
ChangeCursor(cursorPattern)
needToGetBackground = false
widthsMode = true
]
//*********************************************************
and TickMarks() be
//*********************************************************
[
CheckTickMark(bLeftBorder, left, 1)
CheckTickMark(bRightBorder, right, 1)
CheckTickMark(bBottomBorder, bottom, 0)
CheckTickMark(bTopBorder, top, 0)
]
//*********************************************************
and CheckTickMark(borderBoxNum, border, n) be
//*********************************************************
[
// n = 0 if interested in x coordinate
// n = 1 if interested in y coordinate
let xyPair = vec 1
if CursorInside2(FEditMenu!borderBoxNum, 4, 4, xyPair) & GetButtons() then
[
ChangeBoxes(editStatePutCancel)
PaintWidthMarker(border, (n * foregroundView>>VIEW.nDotsY) + (1 - 2 * n) * (xyPair!n / (foregroundView>>VIEW.dotSize)))
WidthChanged = true
if (border eq left) % (border eq bottom) then needToGetBackground = true
]
]
//*********************************************************
and DeActivateWidths() be
//*********************************************************
[
ChangeCursor(cursorPattern)
OutlineBorderBoxes(white)
if needToGetBackground then GetBackground(currentCharacterCode, currentBackgroundOffsetx, currentBackgroundOffsety)
FillBox(FEditMenu!bWidths, flip)
widthsMode = false
]
//*********************************************************
and OutlineBorderBoxes (color) be
//*********************************************************
[
OutlineBox(FEditMenu!bLeftBorder, 1, color)
OutlineBox(FEditMenu!bRightBorder, 1, color)
OutlineBox(FEditMenu!bBottomBorder, 1, color)
OutlineBox(FEditMenu!bTopBorder, 1, color)
]
//*********************************************************
and Show() be
//*********************************************************
[
let string = vec 127
switchon selectedBoxNum into
[
case bShowSequence:
[
string!0 = 0
unless selectedButton eq 3 do
[
until Endofs(keys) do Gets(keys)
Ws("Start string with: ")
startSequenceChar = Gets(keys)
if startSequenceChar eq $*N then
startSequenceChar = currentCharacterCode
Puts(dsp, startSequenceChar); Wl("")
]
for I = startSequenceChar to startSequenceChar + 376b do
AppendChar(((I gr 377b)?I - 400b, I), string)
endcase
]
case bShowTypeIn:
unless selectedButton eq 3 do
[
let numberString = nil
let numberPosition = nil
let char = nil
until Endofs(keys) do Gets(keys)
OverwriteBox(FEditMenu!bShowBox, showTypeInString)
FillBox(showBox, flip)
char = Gets(keys)
unless char eq $*n do
[
showTypeInString!0 = 0
[
switchon char into
[
case $*n:
break
endcase
case backSpace:
unless showTypeInString>> STRING.length eq 0 do
showTypeInString>> STRING.length =
showTypeInString>> STRING.length - 1
endcase
case $x:
test kbdAd!3 eq 177773b
ifso
[
numberPosition = valof
[
for I = showTypeInString>> STRING.length to 1 by -1 do
if showTypeInString>> STRING.char↑I eq $# then resultis I
resultis 0
]
if numberPosition gr 0 then
[
numberString = ExtractSubstring(showTypeInString, numberPosition + 1)
if numberString>> STRING.length le 3 then
[
showTypeInString>> STRING.length = numberPosition - 1
AppendChar(StringToValue(numberString, 8), showTypeInString)
]
Free(sysZone, numberString)
]
]
ifnot AppendChar(char, showTypeInString)
endcase
default:
AppendChar(char, showTypeInString)
endcase
]
OverwriteBox(showBox, showTypeInString)
FillBox(showBox, flip)
char = Gets(keys)
]
repeat
]
]
CopyString(string, showTypeInString)
endcase
case bShowBox:
string!0 = 0
let tempChar = (selectedButton eq 3) ? currentCharacterCode, $H
AppendChar(tempChar, string)
AppendChar(currentCharacterCode, string)
AppendChar(tempChar, string)
endcase
] //end switchon
if SearchChar(string, currentCharacterCode) then PutChar()
PaintString(string)
if selectedBoxNum eq bShowBox then FillBox(showBox, flip)
]
//*********************************************************
and Draw() be
//*********************************************************
[Draw
let xyPair, squareSize = vec 1, foregroundView>>VIEW.dotSize
let lastX, strokeBeginX, lastY, strokeBeginY = -1, -1, nil, nil
while CursorInside2(editBox, -4, -4, xyPair) do
[
let x = xyPair!0 / squareSize
let y = (editBoxYSize - xyPair!1) / squareSize
//foregroundView>>VIEW.nDotsY - xyPair!1 / squareSize
if x ne lastX % y ne lastY then
[
FlipGnat(lastX, lastY) //Gets clipped if lastX ls 0
FlipGnat(x, y)
lastX, lastY = x, y
]
let buttons = GetButtons()
test buttons
ifso
[
let paint, string = true, "Flip"
test buttons<<MOUSE.key1
ifso
[
paint = not ReadCharBit(foregroundView, x, y)
string = "Draw"
]
ifnot
[
if buttons<<MOUSE.key3 then
[
paint = ReadCharBit(foregroundView, x, y)
string = "Erase"
]
]
if strokeBeginX ls 0 then
[
Wl("")
Ws(string)
Ws(" from")
WriteCoordinates(x, y)
strokeBeginX, strokeBeginY = x, y
Ws(" to")
]
if paint then
[
unless editState eq editStatePutCancel do ChangeBoxes(editStatePutCancel)
WriteCharBit(foregroundView, x, y)
// FlipGnat(x, y)
// lastX = -1
[
buttons = GetButtons()
]
repeatwhile buttons<<MOUSE.key2
]
]
ifnot
[
if strokeBeginX ge 0 then
[
WriteCoordinates(x, y)
Ws(". Extent is")
let deltaX, deltaY = (x - strokeBeginX, y - strokeBeginY)
WriteCoordinates(Max(deltaX, -deltaX) + 1, Max(deltaY, -deltaY) + 1)
Wl(".")
strokeBeginX = -1
]
]
]
FlipGnat(lastX, lastY)
]Draw
//*********************************************************
and WriteCoordinates(x, y) be
//*********************************************************
[
Ws(" (")
Wns(dsp, x)
Ws(", ")
Wns(dsp, y)
Ws(")")
]
//*********************************************************
and FlipGnat(x, y) be
//*********************************************************
if gnatIsDesired then
PartialFillBox(updateBox, flip, x, foregroundView>>VIEW.nDotsY - y - 1, 1, 1)
//*********************************************************
and GetButtons() = (not @177030b) & 7
//*********************************************************
//*********************************************************
and ChangeBoxes(newEditState; numargs na) be
//*********************************************************
[
DefaultArgs(lv na, 0, editStateGetDelete)
editState = newEditState
let string, inactive = nil, true
OverwriteBox(FEditMenu!bGetPut, "Get")
switchon editState into
[
case editStateGetDelete:
string = "Delete"
inactive = false
endcase
case editStatePutCancel:
OverwriteBox(FEditMenu!bGetPut, "Put")
string = "Cancel"
endcase
case editStateGetUnwrite:
string = "Unput"
endcase
]
OverwriteBox(FEditMenu!bDeleteCancelUnwrite, string)
(FEditMenu!bSymbol) >>BOX.inactive = inactive
(FEditMenu!bOctal) >>BOX.inactive = inactive
]
//*********************************************************
and DeleteCancelUnwrite(s) be
//*********************************************************
[
switchon editState into
[
//Delete
case editStateGetDelete:
unless ConfirmMenuSelection("Remove this character from file?", s) do return
DeleteThisCharacter()
ClearEditWindow()
endcase
//Cancel
case editStatePutCancel:
PartialFillBox(editBox, grayFlip, 0)
unless ConfirmMenuSelection("Wipe the screen?", s) do
[
PartialFillBox(editBox, grayFlip, 0)
return
]
ClearEditWindow()
NewChar()
endcase
//Unwrite
case editStateGetUnwrite:
PartialFillBox(editBox, grayFlip, 0)
test ConfirmMenuSelection("*"Undo*" previously-Put changes to this character?", s)
ifso
[
Wl("Reverting to prior version of this character.")
EditUnWriteChar(currentCharacterCode)
ClearEditWindow()
NewChar(selectedButton ne 2)
ChangeBoxes(editStatePutCancel)
PutChar()
]
ifnot
[
PartialFillBox(editBox, grayFlip, 0)
return
]
endcase
]
FillBox(FEditMenu!bDeleteCancelUnwrite, flip)
]
//*********************************************************
and Area() be
//*********************************************************
[
//Compute area of char on screen
let ar = 0
Wl("Computing area")
for x = 0 to foregroundView>>VIEW.nDotsX - 1 do
for y = 0 to foregroundView>>VIEW.nDotsY - 1 do
if ReadCharBit(foregroundView, x, y) then ar = ar + 1
TypeForm("Area: ", 10, ar, ". Background area: ")
FLDI(1, backgroundArea)
FLDI(2, EFactorX); FLDI(3, EFactorY)
FDV(1, 2); FDV(1, 3)
TypeForm(2, 1, 0)
]