// October 10, 1979 10:14 AM by Taft *** RESIDENT *** //Edited by Lyle Ramshaw September 4, 1980 2:55 PM: // Hacked on text postioning; added isArrows flag checks get "ZPDEFS.bcpl" // outgoing procedures external [ incTextBuffer decTextBuffer refreshTextBuffer turnTextOn turnTextOff checkTextID newTextID complementBox makeText remakeText markText showText writeText rewriteText eraseText textColorSymbol fontAddress ] // outgoing statics external [ @maxStringHeight // ZPCONVERT ] static [ @maxStringHeight ] // incoming procedures external [ MoveBlock // SYSTEM Zero CreateDiskStream Closes ReadBlock typeForm // ZPUTIL obtainBlock // ZPBLOCK putBlock giveUp paintString // ZPCONVERT XORcolorSymbol // ZPDRAW ] // incoming statics external [ @bitmap00 // ZPINIT @scanlineWidth @Xmax @Ymax @maxTextID @textTable @fontDefTable @fontFile @font @dspFont @dspFontAddress @textOK @textString @textWidth @textHeight @textBitmap @textBitmapSize @colorOn // ZPEDIT ] // local definitions: // ALTO font format structure WX [ wx bit 15 noExt bit 1 ] structure WXplus1 [ skip byte bits byte ] //*************************************************** // text command procedures //*************************************************** let incTextBuffer(char) be [incTextBuffer if textOK then turnTextOff() let c=textString>>STRING.length+1 unless c le maxChar return textString>>STRING.char^c=char textString>>STRING.length=c refreshTextBuffer() ]incTextBuffer and decTextBuffer()be [decTextBuffer if textOK return let c=textString>>STRING.length unless c return textString>>STRING.length=c-1 refreshTextBuffer() ]decTextBuffer and refreshTextBuffer() be [refreshTextBuffer clearTextBuffer() let stringLength=textString>>STRING.length if stringLength eq 0 return let fontPointer=fontAddress(font) textHeight=@(fontPointer-2) let textSkip=nil let arrowsHack=false if (stringLength eq 1)& (fontDefTable!font>>FONTDEF.isArrows eq 1) then arrowsHack=true textSize(arrowsHack, textString, fontPointer, lv textWidth, lv textHeight, lv textSkip) let destAd = textBitmap if arrowsHack then destAd = textBitmap-textSkip*scanlineWidth paintString(textString, scanlineWidth, 15, destAd, fontPointer) if textOK then complementBox(textBitmap, 0, textWidth, textHeight+1) ]refreshTextBuffer and turnTextOn() be [turnTextOn if textOK return textOK=textString>>STRING.length if textOK then complementBox(textBitmap, 0, textWidth, textHeight+1) ]turnTextOn and turnTextOff() be [turnTextOff unless textOK return clearTextBuffer() textOK=0 textWidth=0 textHeight=0 textString>>STRING.length=0 ]turnTextOff and clearTextBuffer() be [clearTextBuffer Zero(textBitmap, textBitmapSize) ]clearTextBuffer //*************************************************** // "Box" procedures //*************************************************** and complementBox(w0, b, boxWidth, boxHeight) be XORbox(w0, b, boxWidth, boxHeight, -1) and XORbox(w0, b, boxWidth, boxHeight, p) be [XORbox let n=(boxWidth+b) rshift 4 let s=((-1) rshift b) & p let r=((-1) lshift (16 - ((boxWidth+b) & #17))) & p unless n then [ s=s & r; r=0 ] for i=1 to boxHeight do [ @w0=@w0 xor s for w=w0+1 to w0+n-1 do @w=@w xor p if r then @(w0+n)=@(w0+n) xor r w0=w0 + scanlineWidth ] ]XORbox and eraseBox(w0, b, boxWidth, boxHeight) be [eraseBox let n=(boxWidth+b) rshift 4 let s=(-1) lshift (16-b) let r=(-1) rshift ((boxWidth+b) & #17) for i=1 to boxHeight do [ @w0=@w0 & s for w=w0+1 to w0+n-1 do @w=0 if r then @(w0+n)=@(w0+n) & r w0=w0 + scanlineWidth ] ]eraseBox and stripeBox(w0, b, boxWidth, boxHeight) be XORbox(w0, b, boxWidth, boxHeight, #146314) //*************************************************** // level 1 text procedures (parameter is text ID) //*************************************************** and makeText(string, x, y, f, color, showIt; numargs n) = valof [makeText if n le 5 then showIt=true let id=createText(string, x, y, f, color) if showIt then showText(id) resultis id ]makeText and remakeText(textPointer) = valof [remakeText let id=newTextID() unless id resultis 0 textTable!id=textPointer textTable!0=textTable!0+1 showText(id) resultis id ]remakeText and createText(string, left, top, f, color, b; numargs n) = valof [createText let c=string>>STRING.length unless c resultis 0 let id=newTextID() unless id resultis 0 let textPointer=obtainBlock(TEXTblockSize+c/2+1) unless textPointer resultis giveUp("[makeText]") let textString=textPointer+TEXTblockSize MoveBlock(textString, string, c/2+1) textPointer>>TEXT.left=left textPointer>>TEXT.top=top textPointer>>TEXT.selected= (n ls 6) ? 0, b textPointer>>TEXT.tFlag=1 textPointer>>TEXT.color=color setFont(textPointer, f) textTable!id=textPointer textTable!0=textTable!0+1 resultis id ]createText and showText(id) be [showText writeText(checkTextID(id)) ]showText and rewriteText(id) be [rewriteText let textPointer=checkTextID(id) unless textPointer return unless setFont(textPointer, font) return processBox(textPointer, eraseBox) textPointer>>TEXT.font=font writeText(textPointer) ]rewriteText and markText(id, b) be [markText let textPointer=checkTextID(id) unless textPointer return textPointer>>TEXT.selected=b processBox(textPointer, complementBox) ]markText and eraseText(id) be [eraseText let textPointer=checkTextID(id) textColorSymbol(textPointer) processBox(textPointer, eraseBox) ]eraseText and newTextID() = valof [newTextID for id=1 to maxTextID do unless textTable!id resultis id typeForm(0, "Sorry, no room for more than ", 10, maxTextID, 0, " text strings*N", 0, "To get more work space for text, start DRAW with switch /T (e.g.: DRAW ", 10, 2*maxTextID, 0, "/T )*N") resultis 0 ]newTextID and checkTextID(id) = ((id ls 1) % (id gr maxTextID)) ? 0, textTable!id //*************************************************** // level 0 text procedures (parameter is text pointer) //*************************************************** and writeText(textPointer) be [writeText unless textPointer return let thisFont=textPointer>>TEXT.font let fontPointer=fontAddress(thisFont) let textString=textPointer+TEXTblockSize let arrowsHack=false if (textString>>STRING.length eq 1)& (fontDefTable!thisFont>>FONTDEF.isArrows eq 1) then arrowsHack=true let x=textPointer>>TEXT.left let y=textPointer>>TEXT.top let box=vec TEXTblockSize+1 let h, w, skip=nil, nil, nil textSize(arrowsHack, textString, fontPointer, lv w, lv h, lv skip) textPointer>>TEXT.right=x+w-1 textPointer>>TEXT.bottom=y-h+1 textPointer>>TEXT.skip=skip MoveBlock(box, textPointer, TEXTblockSize) switchon clipBox(box) into [ case 0: paintString(textString, scanlineWidth, (15-(x & #17)), wordAddress(x, (arrowsHack ? y+skip, y))-scanlineWidth, fontPointer) endcase case 1: return case 2: processBox(box, stripeBox) endcase ] if textPointer>>TEXT.selected then processBox(textPointer, complementBox) textColorSymbol(textPointer) ]writeText and setFont(textPointer, fontNumber) = valof [setFont unless (fontNumber ge 0) & (fontNumber le 3) then fontNumber=0 if textPointer>>TEXT.font eq fontNumber resultis 0 textPointer>>TEXT.font=fontNumber resultis true ]setFont and textColorSymbol(textPointer) be [textColorSymbol unless textPointer return let textColor=textPointer>>TEXT.color unless colorOn & textColor ne black return XORcolorSymbol((textPointer>>TEXT.left + textPointer>>TEXT.right)/2, textPointer>>TEXT.bottom, textColor) ]textColorSymbol and processBox(textPointer, process) be [processBox unless textPointer return let box=vec 4 box>>TEXT.left=textPointer>>TEXT.left-1 box>>TEXT.top=textPointer>>TEXT.top+1 box>>TEXT.right=textPointer>>TEXT.right+1 box>>TEXT.bottom=textPointer>>TEXT.bottom-1 if clipBox(box) eq 1 return let x=box>>TEXT.left let y=box>>TEXT.top process(wordAddress(x, y), (x & #17), box>>TEXT.right-x+1, y-box>>TEXT.bottom+1) ]processBox and clipBox(box) = valof [clipBox let left=box>>TEXT.left let top=box>>TEXT.top let right=box>>TEXT.right let bottom=box>>TEXT.bottom // OK, no clipping if (left ge 0) & (right le Xmax) & (top le Ymax) & (bottom ge 0) resultis 0 // no display if (right ls 0) % (left gr Xmax) % (bottom gr Ymax) % (top ls 0) resultis 1 // clipping box>>TEXT.left= (left ls 0) ? 0, left box>>TEXT.top= (top gr Ymax) ? Ymax, top box>>TEXT.right= (right gr Xmax) ? Xmax, right box>>TEXT.bottom= (bottom ls 0) ? 0, bottom resultis 2 ]clipBox and wordAddress(x, y) = (bitmap00 + (x rshift 4) - y*scanlineWidth) and textSize(arrowsFlag, textPointer, fontPointer, widthAd, heightAd, skipAd; numargs n) be [textSize let w, hb, ht=0, 0, @(fontPointer-2) let stringLength=textPointer>>STRING.length for i=1 to stringLength do [ let c=textPointer>>STRING.char^i [ let wxpt=fontPointer+c+fontPointer!c let newht=(wxpt+1)>>WXplus1.skip let newhb=newht+(wxpt+1)>>WXplus1.bits if newhb gr hb then hb=newhb if newht ls ht then ht=newht c=wxpt>>WX.wx if wxpt>>WX.noExt then [ w=w+c; break ] w=w+16 ] repeat ] switchon n into [ case 6: @skipAd=(arrowsFlag ? ht, 0); case 5: @heightAd=(arrowsFlag ? hb-ht, (fontPointer-2)>>AL.height); case 4: @widthAd=w ] ]textSize and fontAddress(f) = valof [fontAddress // is font in memory ?? let fontLength=fontFile>>FONTFILE.length^f test fontLength eq 0 ifnot [ // yes => is it the current font? let fontBuffer=fontFile>>FONTFILE.buffer if fontFile>>FONTFILE.current ne f then [ let fontStream=CreateDiskStream(lv(fontFile>>FONTFILE.fp^f), ksTypeReadOnly) ReadBlock(fontStream, fontBuffer, fontLength) Closes(fontStream) fontFile>>FONTFILE.current=f ] resultis (fontBuffer+2) ] ifso [ // no => use the display font if f ne dspFont then typeForm(0, "No font ", 10, f, 0, ", message font used instead*N") resultis dspFontAddress ] ]fontAddress