// R O T A T E (PREPRESS) // catalog number ??? // //ROTATE is used to rotate character descriptions (CD) 90 degrees // counter-clockwise. get "ix.dfs" // outgoing procedures external [ Rotate ] // outgoing statics //external // [ // ] //static // [ // ] // incoming procedures external [ //WINDOW WindowRead WindowReadBlock WindowWrite WindowWriteBlock WindowGetPosition WindowSetPosition WindowCopy WindowClose //MAPCDTEMP MapCDtemp //UTIL FSGetX FSPut MoveBlock DoubleAdd //OS Usc ] // incoming statics //external // [ // ] // internal statics //static // [ // ] // File-wide structure and manifest declarations. // Procedures let Rotate() be MapCDtemp(RotateIx, RotateOne, nil) and RotateIx(ix, nil) be [ let r=ix>>IX.rotation+90*60 //Rotated form if Usc(r, 360*60) ge 0 then r=r-360*60 ix>>IX.rotation=r ] and RotateOne(cp, si, so, nil) be [ let a=WindowRead(si) //FHEAD let ns=a<<FHEAD.ns let hw=a<<FHEAD.hw let bufSize=hw*ns let C=FSGetX(bufSize) //Space to hold the bits WindowReadBlock(si, C, bufSize) let w=cp>>CharWidth.W let h=cp>>CharWidth.H let xl=cp>>CharWidth.XL let yb=cp>>CharWidth.YB //nx,ny denote new x, new y let nw=h let nh=w let nxl=-(yb+h-1) let nyb=xl //And fill into char descr cp>>CharWidth.W=nw cp>>CharWidth.H=nh cp>>CharWidth.XL=nxl cp>>CharWidth.YB=nyb //Now set WX←-WY; WY←WX let t=vec 1 MoveBlock(t, lv cp>>CharWidth.WY, 2) t!0=not t!0; t!1=not t!1 DoubleAdd(t, (table [ 0;1 ] )) MoveBlock(lv cp>>CharWidth.WY, lv cp>>CharWidth.WX, 2) MoveBlock(lv cp>>CharWidth.WX, t, 2) let nhw=(nh+15)/16 a<<FHEAD.ns=nw a<<FHEAD.hw=nhw WindowWrite(so, a) for nx=0 to nw-1 do for nwy=0 to nhw-1 do [ let nword=0 let nybase=nwy*16 for y=0 to 15 do [ let ny=y+nybase //We want to write the bit at (nx,ny) (0,0) at lower left of whole box. let oy=(h-1)-nx let ox=ny //Read bit at (ox,oy) let nbit=0 if ox ge 0 & ox ls w & oy ge 0 & oy ls h then [ let wd=C+(ox*hw)+(oy/16) nbit=@wd&(#100000 rshift (oy)) ] //Put it in word if nbit then nword=nword%(#100000 rshift y) ] WindowWrite(so, nword) ] FSPut(C) ]