// 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&#17))
				]
//Put it in word
			if nbit then nword=nword%(#100000 rshift y)
			]
		WindowWrite(so, nword)
		]

	FSPut(C)
]