// O R B I T F O R M A T (PREPRESS) // catalog number ??? // // Transfers a font between types Chars and OrbitChars, and types out // amount of space used. //Modified by Lyle Ramshaw (PARC), January 16, 1980, to change the handling // of empty characters. If a character in the input font has a bounding box // with either height or width equal to zero, that character is interpreted // as being "empty", that is, having no associated black bits. In the output, // empty characters will have all dimensions of the bounding box equal to // zero, and they will have an associated empty raster block of the appropriate // type. get "ix.dfs" // outgoing procedures external [ OrbitFormat DeOrbitFormat ] // outgoing statics //external // [ // ] //static // [ // ] // incoming procedures external [ //WINDOW WindowRead WindowReadBlock WindowWrite WindowWriteBlock //MAPACTEMP MapACtemp //PREPRESSUTIL FSGetX FSPut Scream TypeForm //OS Noop DoubleAdd Zero SetBlock MoveBlock ] // incoming statics //external // [ // ] // internal statics static [ @pack=true ] // File-wide structure and manifest declarations. let DeOrbitFormat(inputName,outputName;numargs na) be [ if na eq 0 then [ inputName="ACtemp";outputName="ACtemp" ] let v=vec 1 v!0=0 MapACtemp(CheckDeOrbitIX, DeOrbitOne, v, inputName, outputName) TypeForm(10, v!0, " words of font storage.") ] and OrbitFormat(inputName,outputName;numargs na) be [ if na eq 0 then [ inputName="ACtemp";outputName="ACtemp" ] let v=vec 1 v!0=0 MapACtemp(CheckOrbitIX, OrbitOne, v, inputName, outputName) TypeForm(10, v!0, " words of font storage.") ] and CheckDeOrbitIX(ix) be [ unless ix>>IXH.Type eq IXTypeOrbitChars then [ Scream("DeOrbitize called with wrong input type");finish] ix>>IXH.Type=IXTypeChars ] and DeOrbitOne(p, si, so, arg) be [ let masks=vec 17 for i=0 to 16 do masks!i=(-1) rshift i //Check for a character with no bits in it let hb= p>>CharWidth.H let widthFromCharWidth = p>>CharWidth.W test (hb eq 0) % (widthFromCharWidth eq 0) ifso [ let result = vec 0 result!0=0 WindowWriteBlock(so, result, 1) arg!0=arg!0+1 p>>CharWidth.H = 0 p>>CharWidth.W = 0 p>>CharWidth.XL = 0 p>>CharWidth.YB = 0 ] ifnot [ //Find out dimensions of char let a=WindowRead(si) let hhb= -a a=WindowRead(si) let ns= a+1 //Compare height in character with height in info block if hhb ne hb then Scream("Character height inconsistency") //Compute height in words for DeOrbit output let hw=(hb+15)/16 //frag is the number of bits in last word of each scanline let frag=hb-16*(hw-1) let sizeNeeded=ns*hw+1 let pbits=FSGetX(sizeNeeded) pbits>>FHEAD.hw=hw //Height pbits>>FHEAD.ns=ns //Width let p,bp,w=pbits,0,nil for i=1 to ns do [ for j=1 to hw-1 do //note that hw ge 1 [ p=p+1 p!0=w lshift (16-bp) w=WindowRead(si) p!0=p!0 % (w rshift bp) ] p=p+1 test bp ge frag ifso [ p!0=(w lshift (16-bp))&(not masks!frag) bp=bp-frag ] ifnot [ p!0=w lshift (16-bp) w=WindowRead(si) p!0=(p!0%(w rshift bp))&(not masks!frag) bp=16+bp-frag ] ] WindowWriteBlock(so, pbits, sizeNeeded) arg!0=arg!0+sizeNeeded FSPut(pbits) ] ] and CheckOrbitIX(ix) be [ unless ix>>IXH.Type eq IXTypeChars then [ Scream("Orbit format called with wrong input type");finish] ix>>IXH.Type=IXTypeOrbitChars ] and OrbitOne(p, si, so, arg) be [ let masks=vec 16 for i=0 to 15 do masks!i=(-1) rshift i //Find out dimensions of char let a=WindowRead(si) let hw= a<<FHEAD.hw let ns=a<<FHEAD.ns let hb=p>>CharWidth.H // Place here "hb=16*hw" if you want unpacked fonts. unless pack then [ hb=16*hw; p>>CharWidth.H=hb ] // let hhw=(hb+15)/16 if hhw ne hw then Scream("Character height inconsistency") // sizeNeeded ← (hb*ns+15)/16 let mul=vec 1 DoubleMul(mul, hb, ns) DoubleAdd(mul, table [ 0;15 ] ) let sizeNeeded=(mul!0 lshift 12)+(mul!1 rshift 4) if sizeNeeded eq 0 then [ ns=0; hw=0; hb=0 p>>CharWidth.H=0 p>>CharWidth.W=0 p>>CharWidth.YB=0 p>>CharWidth.XL=0 ] sizeNeeded=(sizeNeeded+3)&(-2) //Account for header; even num let pbits=FSGetX(sizeNeeded+1) //1 extra because of p!1 below pbits!0=-hb //Height pbits!1=ns-1 //Width let p=pbits+2 let ob=0 for i=1 to ns do [ for j=1 to hw do [ let w=WindowRead(si) p!0=(p!0&(not masks!ob))+(w rshift ob) p!1=(p!1&(masks!ob))+(w lshift (16-ob)) p=p+1 ] ob=ob+hb p=p-hw+ob/16 ob=ob ] WindowWriteBlock(so, pbits, sizeNeeded) arg!0=arg!0+sizeNeeded FSPut(pbits) ] and DoubleMul(res, a, b) be [ let ad=vec 1 ad!0=0; ad!1=a res!0=0; res!1=0 for i=1 to b do DoubleAdd(res, ad) ]