! EDWIN Device Driver for Postscript ! Revision History ! 14-DEC-1988 ANY Completed ! from Edwin include Device from Edwin include Icodes from Edwin include Specs from Edwin include Consts include IPROCS, PATTERN from IMP include ASCII,LOGNAMES,MATHS external long real function spec S TO R alias "IMP_S_TO_R" - (string(255) value) ! Control characters ! Plotting information and defaults ! The defaults, and external values are in mm const real Default left margin = 15 const real Default bottom margin = 15 const real Default page width = 180 const real Default page length = 270 ! Internally we work on inches, ugh own real left margin own real bottom margin own real page width own real page length own real device resolution = 300 own byte Some Graphics Done = false own integer XL { } own integer XR { Window box } own integer YB { } own integer YT { } own integer CX { Current Position } own integer CY { } own integer PX { Proper Position } own integer PY { } own integer Last Drew = 0 own integer Drawing Mode = 0 own integer current colour = 1 own integer Char Mirror = No Mirroring own integer Current Char Size = 1 own integer Current Char Rot = 0 own integer Current Line Style = 0 own string (7) Current Poly = "eopoly" { eopoly or dopoly as required } own string(255) Char String = "" own integer Num Spaces = 0 own string(255) Mirror = "" const integer Max Fonts = 13 own string (31) array Fonts (0:Max Fonts) = "Courier", "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Symbol" own integer Current Font = 0 own string(255) Font external routine PS alias "EDWIN___P" (integer COM, X, Y) string(255) temp1,temp2,temp3,temp4 own integer boxx=-1,boxy=-1 integer I,J routine SWAP (integer name A, B) integer C C = A; A = B; B = C end string(255) function I To Hex (integer Number) const byte array Letters (0:15) = '0','1','2','3','4','5','6','7', '8','9','A','B','C','D','E','F' string(255) Result = "" integer I,J for I = 1,1,4 cycle J = Number // 16 Result = Letters(Number - J * 16).Result Number = J repeat result = result end routine TTString(string (255) Thing) integer I for I=1,1,Length(Thing) cycle TTPut(Charno(Thing,I)) repeat end routine Newln TTput(nl) end real function Get Value (real default,string(255) Logical) string(255) Log Value = Translate(Logical) if Log Value = Logical start result = Default else result = stor(Log Value) finish end routine Fix Font string (255) Test String = "Edwin is WONDERFUL" Font = Fonts(Current Font) TTString("/".font." findfont setfont");newln TTString("/font_scale (".test string.") stringwidth pop ") TTString(itos(Length(test string),0)." div 1 exch div def");newln TTString("currentfont ".itos(Current Char Size,0)." font_scale mul ") TTString("scalefont setfont");newln end routine Output Char String long real Rot Angle integer String Width = Current Char Size * Length(Char String) if PX # CX or PY # CY then TTString(itos(PX,0)." ".itos(PY,0)." m");newln TTString("gsave currentpoint translate ") if Current Char Rot # 0 start TTstring(itos(Current Char Rot,0)." ") TTstring("rotate ") finish TTString(mirror) newln TTString(itos(Num Spaces,0)." ".itos(String Width,0)) TTString(" (".char string.") edstr grestore");newln if Char Mirror & Mirror in Y Axis = Mirror in Y Axis start Rot Angle = (1 + Current Char Rot)/180 * PI else Rot Angle = Current Char Rot/180 * PI finish PX = PX + round(cos(Rot Angle) * String Width) PY = PY + round(sin(Rot Angle) * String Width) CX = -1 CY = -1 Char String = "" Num Spaces = 0 Last Drew = COM end routine Clean Up Ends return if Last Drew = 0 if Last Drew = 6 and COM # 6 start Output Char String else if Drawing Mode = 3 and COM = 10 TTString(current poly) and newln if Last Drew = 5 CX = -1 CY = -1 Drawing Mode = 0 finish end switch SW(0:MAX COM) routine CHANGE ATTRIBUTE (integer WHICH, TO) integer newto Clean Up Ends switch AS(0:ATT MAXIMUM) -> AS(WHICH) AS(att Shade Mode): if TO > Max Pat or TO < 0 then TO = 1 TTString("/fill_cur fill_".itos(TO,0)." def");newln return AS(att Colour): if TO # 0 then newto= 0 else newto = 1 if newto # current colour start TTString(itos(1-current colour, 0)." setgray");newln current colour = newto finish return AS(att line style): if TO < 0 or TO > 4 then TO = 0 if TO # Current Line Style start TTString("[") if TO = 1 start TTString("1 9") elseif TO = 2 TTString("50 10 10 10") elseif TO = 3 TTString("15") elseif TO = 4 TTString("50 15") finish TTString("] 0 setdash");newln Current Line Style = To finish return AS(att char size): if TO # Current Char Size start Current Char Size = TO TTString("/".font." findfont ".itos(TO,0)." font_scale mul ") TTString("scalefont setfont");newln finish return AS(Att Char Rot): Current Char Rot = TO return AS(Att Char Mirror): if TO = Mirror in X Axis start Mirror = "1 -1 scale" else if TO = Mirror in Y Axis Mirror = "-1 1 scale" else if TO = Mirror in Both Axes Mirror = "-1 -1 scale" else if TO = No Mirroring Mirror = "" else return finish Char Mirror = TO return AS(att char font): if TO > Max Fonts or TO < 0 then TO = 0 if Current Font # TO start Current Font = TO FixFont finish return AS(att poly render): if Y=0 start current poly = "eopoly" else current poly = "dopoly" finish return AS(*): ! Ignore all other attributes end routine Establish Graphics Defaults integer I, J TTString("%! Edwin PostScript Output");newln TTString("initgraphics");newln TTString("/m {moveto} def");newln TTString("/l {lineto} def");newln TTString("/cp {closepath} def");newln TTString("/np {newpath} def");newln TTString("/st {currentpoint stroke moveto} def");newln TTString("/rl {rlineto st} def");newln TTString("/rln {rlineto} def");newln Read Patterns(round(device resolution)) TTstring("/quad {/tempstring exch def ");newln TTstring("/outstring tempstring length 16 mul string def");newln TTstring("0 1 15 {/whichln exch def ");newln TTstring("/thisln tempstring whichln 2 mul 2 getinterval def");newln TTstring("0 128 384 {/y exch def 0 2 6 {/x exch def");newln TTstring("outstring whichln 8 mul x add y add thisln putinterval");newln TTstring("} for } for } for outstring} def");newln for I = 0,1,Max Pat cycle TTString("/fill_".itos(I,0)." <") for J = 0,1,15 cycle TTString(I To Hex(Patterns(I*16+J))) repeat TTString("> quad def");newln repeat TTString("/fill_cur fill_0 def");newln TTString("/dopoly { fill_cur fill_0 eq {stroke}");newln TTString("{fill_cur fill_1 eq {gsave fill grestore stroke}");newln TTString("{pathbbox");newln TTString("/uy exch def");newln TTString("/ux exch def");newln TTString("/ly exch cvi 16 idiv 16 mul def");newln TTString("/lx exch cvi 16 idiv 16 mul def");newln TTString("gsave clip");newln TTString("lx 64 ux {/tx exch def ly 64 uy {/ty exch def ");newln TTString("gsave tx ty translate");newln TTString("64 64 true [1 0 0 -1 0 64] {fill_cur} imagemask grestore");newln TTString("}for}for");newln TTString("grestore stroke} ifelse } ifelse } def");newln TTString("/b {/ybit exch def /xbit exch def currentpoint np m");newln TTString("0 ybit rlineto xbit 0 rlineto ") TTString("0 ybit neg rlineto xbit neg 0 rlineto");newln TTString("dopoly} def");newln TTString("/eopoly { fill_cur fill_0 eq {stroke}");newln TTString("{fill_cur fill_1 eq {gsave eofill grestore stroke}");newln TTString("{pathbbox");newln TTString("/uy exch def");newln TTString("/ux exch def");newln TTString("/ly exch cvi 16 idiv 16 mul def");newln TTString("/lx exch cvi 16 idiv 16 mul def");newln TTString("gsave eoclip");newln TTString("lx 64 ux {/tx exch def ly 64 uy {/ty exch def ");newln TTString("gsave tx ty translate");newln TTString("64 64 true [1 0 0 -1 0 64] {fill_cur} imagemask grestore");newln TTString("}for}for");newln TTString("grestore stroke} ifelse } ifelse } def");newln TTString("/b {/ybit exch def /xbit exch def currentpoint np m");newln TTString("0 ybit rlineto xbit 0 rlineto ") TTString("0 ybit neg rlineto xbit neg 0 rlineto");newln TTString("eopoly} def");newln TTString("/edstr {");newln TTString("/outstring exch def /strwid exch def /numspace exch def");newln TTstring("numspace 0 eq {outstring show} {");newln TTString("outstring stringwidth pop strwid exch sub numspace div");newln TTString("0 8#040 outstring widthshow} ifelse} def");newln temp1 = rtos(72 / device resolution,0,4) temp2 = rtos(device resolution * (Left Margin + Page Width),0,4) temp3 = rtos(device resolution * Bottom Margin,0,4) TTString(temp1." ".temp1." scale");newln TTString("90 rotate");newln TTString(temp3." -".temp2." translate");newln TTString("0 0 m");newln if Translate("EDWIN_PS_FONT") # "EDWIN_PS_FONT" start Fonts(0) = Translate("EDWIN_PS_FONT") finish Fix Font CX = 0 CY = 0 PX = CX PY = CY end -> SW(COM) SW(0): ! Initialise dev data_name = "a Postscript file" Left Margin = get value(Default Left Margin,"EDWIN_PS_LEFT_MARGIN") / 25.4 Bottom Margin = get value(Default Bottom Margin,"EDWIN_PS_BOTTOM_MARGIN") / 25.4 Page Width = get value(Default Page Width,"EDWIN_PS_PAGE_X") / 25.4 Page Length = get value(Default Page Length,"EDWIN_PS_PAGE_Y") / 25.4 Device Resolution = get value(Device Resolution,"EDWIN_PS_DEVICE_RESOLUTION") XL = 0 YB = 0 XR = round(Page Length * Device Resolution) YT = round(Page Width * Device Resolution) dev data_Mvx = XR dev data_Mvy = YT dev data_Dvx = XR dev data_Dvy = YT dev data_Max Styles = 4 dev data_Num Char Rots = 255 dev data_Num Char Sizes = 255 I = round(device resolution / 2.54) dev data_X Units Per Cm = I dev data_Y Units Per Cm = I Set Device("EDWIN_PS") if Viewing = 0 Establish Graphics Defaults return SW(1): !Terminate Clean Up Ends TTString("showpage");newln Flush Output return SW(2): ! Update Clean Up Ends return SW(3): ! New frame if Some Graphics Done = true start Clean Up Ends TTString("showpage");newln Flush Output Establish Graphics Defaults Last Drew = 0 ps (9, xr, yt) { re-establish window size } finish Some Graphics Done = false return SW(4): ! Move Abs Clean Up Ends PX = X PY = Y return SW(5): ! Line Abs Clean Up Ends if PX # CX or PY#CY start TTString(itos(PX,0)." ".itos(PY,0)." m");newln finish TTString(itos(X-PX,0)." ".itos(Y-PY,0)." rl") if Drawing Mode = 3 then TTPut('n') newln PX = X PY = Y CX = PX CY = PY Flush Output Some Graphics Done = True Last Drew = COM return SW(6): ! Character Some Graphics Done = True Clean Up Ends Char String = Char String.X Num Spaces = Num Spaces + 1 if X = ' ' if Length(Char String) = 255 then Output Char String Last Drew = 6 return SW(7): ! Attribute Change Change Attribute(X,Y) return SW(8): ! Lower window bounds XL = X if XL < 0 then XL = 0 YB = Y if YB < 0 then YB = 0 return SW(9): ! Upper window bounds Clean Up Ends XR = X if XR > dev data_mvx then XR = dev data_mvx YT = Y if YT > dev data_mvy then YT = dev data_mvy TTString("np ".itos(XL,0)." ".itos(YB,0)." m");newln TTstring(itos(XL,0)." ".itos(YT,0)." l");newln TTString(itos(XR,0)." ".itos(YT,0)." l");newln TTString(itos(XR,0)." ".itos(YB,0)." l");newln TTString("cp clippath np");newln CX = -1 CY = -1 Last Drew = COM return SW(10): ! Set Drawing Mode Clean Up Ends Drawing Mode = X Last Drew = COM return SW(12): ! Lower box bounds boxx = x boxy = y return SW(13): ! Upper box bounds Clean Up Ends if X < BoxX then swap(X,BoxX) if Y < BoxY then swap(Y,BoxY) return if BoxX > XR or X < XL or BoxY > YT or Y < YB BoxX = XL if BoxX < XL BoxY = YB if BoxY < YB X = XR if X > XR Y = YT if Y > YT ! Box now clipped into the screen. Com = Current Line Style if Current Line Style # 0 start ! Set solid lines to border the box, restore afterwards TTString("[] 0 setdash");newln Current Line Style = 0 finish if BoxX # CX or BoxX # CY start TTString(itos(BoxX,0)." ".itos(BoxY,0)." m");newln finish TTString(itos(X-BoxX,0)." ".itos(Y-BoxY,0)." b");newln Change Attribute (Att Line Style, Com) if Com # 0 CX = -1 CX = -1 PX = X PY = Y Some Graphics Done = True Flush Output Last Drew = 13 return SW(14): ! Draw Circle Clean Up Ends if PX + X # CX or PY # CY start TTString(itos(PX+X,0)." ".itos(PY,0)." m");newln finish TTString(itos(PX,0)." ".itos(PY,0)." ".itos(X,0)." 0 360 arc dopoly");newln CX = PX + X CY = PY return SW(*): end end of file