! EDWIN Device Driver for HP 2686A Laserjet Printer
!############################################################################
!# #
!# This is a module from the EDWIN Graphics Package, which was developed #
!# in the Department of Computer Science, at Edinburgh University, from #
!# 1978 to the present day, release 5 of EDWIN in October 1984. #
!# #
!# The principal author of the EDWIN Graphics Package was J Gordon Hughes, #
!# while working for the Edinburgh University Computer Sceince Department. #
!# Parts of EDWIN have been produced by many different people, too many #
!# too mention, working for different departments of Edinburgh and Leeds #
!# Universities. #
!# #
!# This module is regarded as being in the public domain, and the authors #
!# and accept no responsibility regarding the uses to which the software #
!# will be put. #
!# #
!############################################################################
! Neil Bergmann; January, 1985
from Edwin include Device
from Edwin include Icodes
from Edwin include Consts
from Imp include Lognames
const integer Max Styles = 15
const integer HBytes = 72, VBytes = 96
const integer HRes = (HBytes * 8-1), VRes = (VBytes * 8-1)
record format HLineFm(byte array Byte(0:HBytes - 1))
record format BitmapFm(record (HLineFm) array Line(0:VRes))
record format PointFm(integer x,y)
record format DataFm(record(PointFm) p, record(DataFm) name Next)
own record(BitmapFm) name Bitmap
own record(DataFm) name First Point == 0
own record(DataFm) name Next Point == 0
own integer SX = 0, SY = 0, Drawn = False, Colour = 1
own integer LX = 0, LY = 0, Max X = 0, Max Y = 0
own integer WLX = 0, WLY = 0, WHX = HRes, WHY = VRes
own integer Start X = 864, Start Y = 1260
own integer Shade Mode = Solid
own integer Colour Mode = Or Mode
own integer Res = 100
own integer i
own integer NPts = 0
own string(255) Temp = ""
const byte Escape = 27, FF = 12, CR = 13
own byte array Style Map(0:8 * Max Styles + 7) = -
{outline} 0(8),
{solid} 2_11111111(8),
{horizontal}
2_11111111,
2_00000000,
2_00000000,
2_00000000,
2_11111111,
2_00000000,
2_00000000,
2_00000000,
{vertical}
2_10001000,
2_10001000,
2_10001000,
2_10001000,
2_10001000,
2_10001000,
2_10001000,
2_10001000,
{/diagonal}
2_00010001,
2_00100010,
2_01000100,
2_10001000,
2_00010001,
2_00100010,
2_01000100,
2_10001000,
{¬diagonal}
2_10001000,
2_01000100,
2_00100010,
2_00010001,
2_10001000,
2_01000100,
2_00100010,
2_00010001,
{cross hatch}
2_10001000,
2_01010100,
2_00100010,
2_01010001,
2_10001000,
2_01000101,
2_00100010,
2_00010101,
{grid hatch}
2_11111111,
2_10001000,
2_10001000,
2_10001000,
2_11111111,
2_10001000,
2_10001000,
2_10001000,
{Light Stipple}
2_00000000,
2_01000010,
0(4),
2_01000010,
2_00000000,
{checker board}
2_11110000,
2_11110000,
2_11110000,
2_11110000,
2_00001111,
2_00001111,
2_00001111,
2_00001111,
{bricks}
2_11111111,
2_01000000,
2_01000000,
2_01000000,
2_11111111,
2_00000010,
2_00000010,
2_00000010,
{lime}
2_11000011,
2_10000001,
0(4),
2_10000001,
2_11000011,
{brown}
2_10011001(8),
{turquoise}
2_11111111,0,
2_11111111,0,
2_11111111,0,
2_11111111,0,
{user defined styles 14-15 }
0(16)
routine Esc(string(255) S)
integer I
TTPut(Escape)
TTPut(Charno(s,i)) for i = 1, 1, Length(s)
end
routine Raster Resolution(integer i)
Esc("*t".ItoS(i,0)."R")
end
routine Start Raster Graphics
Esc("&a".ItoS(Start X,0)."H")
Esc("&a".ItoS(Start Y,0)."V")
Esc("*r1A")
end
routine Transfer Raster Graphics(integer i)
routine Dummy Newline
TTPut(CR)
TTPut(NL)
Esc("&a-1R")
end
Dummy Newline
Esc("*b".ItoS(i,0)."W")
end
routine End Raster Graphics
Esc("*rB")
end
routine Check(integer X,Y)
if X > Max X then Max X = X
if Y > Max Y then Max Y = Y
end
routine Draw Line(integer TX,TY)
! This is algorithm 162 in the Collected Algorithms from CACM.
! It computes the code string required to move the pen of a
! digital incremental X-Y plotter from an initial point (SX,SY) to
! a terminal point (TX,TY) by the "best" approximation to the
! straight line between the points. The permitted elemental pen
! movement is to an adjacent point in a plane Cartesian point latice,
! diagonal moves permitted.
integer A, B, D, E, F, T, I, XMove, YMove, X, Y
const short array XCode(1:16) = 0,1,1,1,1,1,0,1,0,-1,-1,-1,-1,-1,0,-1
const short array YCode(1:16) = 1,1,0,1,0,-1,-1,-1,-1,-1,0,-1,0,1,1,1
! PY,PX+PY,PX,PX+PY,PX,PX+NY,NY,PX+NY,NY,NY+NX,NX,NX+NY,NX,NX+PY,PY,NX+PY
routine Mark
! make mark in line buffer - represented as a linear bit string
byte integer name B
byte Bit
B == Bitmap_Line(SY)_Byte(SX//8)
Bit = 16_80 >> (SX&7)
B = B ! Bit
if Colour = 0 then B = B !! Bit
Check(SX,SY)
end
Drawn = True
Mark and return if SX = TX and SY = TY
if SX < WLX then SX = WLX
if SY < WLY then SY = WLY
if TX > WHX then TX = WHX
if TY > WHY then TY = WLY
A = TX - SX
B = TY - SY
D = A + B
T = B - A
I = 0
if B >= 0 then I = 2
if D >= 0 then I = I + 2
if T >= 0 then I = I + 2
if A >= 0 then I = 8 - I else I = I + 10
A = -A if A < 0
B = -B if B < 0
F = A + B
D = B - A
if D >= 0 then T = A and D = -D else T = B
E = 0
XMove = XCode(I - 1)
YMove = YCode(I - 1)
X = XCode(I)
Y = YCode(I)
cycle
A = D + E
B = T + E + A
Mark
if B >= 0 start
E = A
F = F - 2
SX = SX + X
SY = SY + Y
else
E = E + T
F = F - 1
SX = SX + XMove
SY = SY + YMove
finish
exit if F <= 0
repeat
Mark
end
routine Clrbitmap
Bitmap = 0
Drawn = False
Max X = 0
Max Y = 0
end
routine Outpage
record(HLineFm) name Thisline
integer X, Y, Right
Raster Resolution(Res)
Start Raster Graphics
for Y = WHY, -1, 0 cycle
Thisline == Bitmap_Line(Y)
Right = Max X//8
Right = Right - 1 while Right > 1 and Thisline_Byte(Right) = 0
Transfer Raster Graphics(1 + Right)
TTPut(Thisline_Byte(X)) for X = 0, 1, Right
repeat
End Raster Graphics
TTPut(CR)
TTPut(FF)
TTPut(NL)
Flush Output
Clrbitmap
end
routine Draw Box(integer LX, LY, UX, UY)
integer SSX, SSY, X, Y, Highbyte, Lowbyte
byte B, BB
byte name Thisbyte
record(HLineFm) name Thisline
routine Test(integer name Low, High)
integer i
if Low > High start
i = Low
Low = High
High = i
finish
end
Test(LX,UX)
Test(LY,UY)
LX = LX + 1
return if UX <= LX {%or UY = LY
UX = UX - 1
UY = UY - 1 if UY # LY
return if LX > WHX or LY > WHY or UX < WLX or UY < WLY
if LX < WLX then LX = WLX
if LY < WLY then LY = WLY
if UX > WHX then UX = WHX
if UY > WHY then UY = WHY
Drawn = True
Check(UX,UY)
{ This is a solid box, outline boxes are filtered out by EDWIN before driver }
Lowbyte = LX//8
Highbyte = UX//8
for Y = LY, 1, UY cycle
Thisline == Bitmap_Line(Y)
for X = Lowbyte, 1, Highbyte cycle
Thisbyte == Thisline_Byte(X)
B = 2_11111111
BB = B
if X = Lowbyte then B = B>>(LX&7)
if X = Highbyte then B = (B<<(7 - (UX&7)))&2_11111111
if Colour Mode = Replace Mode then BB = BB!!B
B = Style Map((Y&2_111)!(Shade Mode<<3))&B
Thisbyte = (Thisbyte&BB)!B
repeat
repeat
end
include "polyfill.hpl"
routine Draw Polygon
integer i
record(DataFm) name pp
record(PointFm) array Pts(1:NPts + 1)
pp == First Point
for i = 1, 1, NPts cycle
Pts(i)_x = pp_p_x
Pts(i)_y = pp_p_y
if i = 1 start
SX = pp_p_x
SY = pp_p_y
else
Draw Line(pp_p_x, pp_p_y)
finish
pp == pp_Next
repeat
Pts(NPts + 1) = Pts(1)
Draw Line(Pts(1)_x, Pts(1)_y)
Polyfill(NPts + 1,Pts)
NPts = 0
end
routine Append(integer X, Y)
if NPts = 0 start
First Point_p_x = X
First Point_p_y = Y
Next Point == First Point
NPts = 1
finish
return if X = SX and Y = SY
if Next Point_Next == nil start
Next Point_Next == new(Next Point)
Next Point == Next Point_Next
Next Point_Next == nil
else
Next Point == Next Point_Next
finish
Next Point_p_x = X
Next Point_p_y = Y
NPts = NPts + 1
SX = X
SY = Y
end
routine Initialise
First Point == new(Next Point)
First Point_Next == nil
Bitmap == new(Bitmap)
Clrbitmap
Dev Data_Name = "HP 2686A Laserjet Printer"
Dev Data_Type = 2686
Dev Data_ARF = 100
Dev Data_DVX = HRes
Dev Data_DVY = VRes
Dev Data_MVX = HRes
Dev Data_MVY = VRes
Dev Data_Num Char Sizes = 255
Dev Data_Units Per CM = Res/2.54
if Viewing = 0 start
Temp = "EDWIN_".ItoS(Dev Data_Type,0)
if Translate(Temp) # Temp and Viewing = 0 start
Set Device(Temp)
finish
TTMode(1)
finish
end
external routine dd2686 alias "EDWIN___Z" (integer Com, X, Y)
switch Command(0:Max Com)
switch Att(0:Att Maximum)
routine Swap(integer name A, B)
integer C
C = A; A = B; B = C
end
Draw Polygon if NPts # 0 and (Com = 10 or Com < 5)
-> Command(Com)
Command(Dev Initialise):
if X = 2686300 start
Res = 300
finish else if X = 2686150 start
Res = 150
else
Res = 100
finish
Initialise
return
Command(Dev Terminate):
Outpage if Drawn = True
dispose(Bitmap)
return
Command(Dev Update):
return
Command(Dev Newframe):
Outpage if Drawn = True
return
Command(Dev Move):
SX = X
SY = Y
return
Command(Dev Line):
if Shade Mode = 0 start
Draw Line(X,Y)
else
Append(X,Y)
finish
return
Command(Dev Char):
signal 14, 14
Command(Dev Attribute):
if 0 <= X <= Att Maximum then -> Att(X) else return
Att(Att Colour):
Y = 1 if Y # 0
Colour = Y
return
Att(Att Colour Mode):
if Y = Replace Mode or Y = Or Mode then Colour Mode = Y
return
Att(Att Shade Mode):
Y = Solid unless 0 <= Y <=15
Shade Mode = Y
Att(*): return
Command(Dev Low WB):
WLX = X
WLY = Y
return
Command(Dev High WB):
WHX = X
WHY = Y
return
Command(Dev Low Box):
LX = X
LY = Y
return
Command(Dev High Box):
Swap(LX, X) if LX > X
Swap(LY, Y) if LY > Y
return if LX > WHX or X < WLX or LY > WHY or Y < WLY
LX = WLX if LX < WLX
LY = WLY if LY < WLY
X = WHX if X > WHX
Y = WHY if Y > WHY
! Box now clipped into the screen.
Draw Box(LX, LY, X, Y)
! Now outline it
return if Colour = 0
SX = LX
SY = LY
Draw Line(X,LY)
Draw Line(X,Y)
Draw Line(LX,Y)
Draw Line(LX,LY)
return
Command(*):
end
!%external %routine Set Laser Position %alias "EDWIN_LASER_POSITION" (%integer X,Y)
! Start X = X
! Start Y = Y
!%end
!
!%external %routine Set Laser Resolution %alias "EDWIN_LASER_RESOLUTION" (%integer i)
! %if i = 75 %or i = 100 %or i = 150 %or i = 300 %then Res = i
!%end
endoffile