%!PS-Adobe-2.0 %%Pages: 1 %%BoundingBox: 0 0 595 841 %%DocumentPaperSizes: A4 %%EndComments % Protractor by Tom Quetchenbach, 2009 % http://wombatula.com/wombats/protractor.php % You may use, modify, reproduce, distribute, transmit, build upon, % etc, with no restrictions. % I don't actually know how DSC works, but the above seems to be ok. % Options passed by PHP script: % TYPE="180" METRIC="false" OFFSET="90" CENTER_BOTTOM_EDGE="false" % MIRROR="false" OUTER="4 inch" THICKNESS="1 inch" FONTSIZE="12" % PAPER_HEIGHT="841" PAPER_WIDTH="595" PAPER_NAME="A4" /inch {72 mul} bind def /cm {72 2.54 div mul} bind def % user definitions % type must be one of 90, 180, or 360; anything else is undefined /type 180 def % ruler in metric /metric false def % offet of center point; useful values are 0 and 90 /offset 90 def % whether to place the center point on the bottom edge /center_bottom_edge false def % if set, 0 degrees is on the left and increases clockwise /mirror false def % font size in points /fontsize 12 def % height of the page including margins /page_height 841 def % width of the page including margins /page_width 595 def % major tick mark interval in degrees /major 10 def % minor tick mark interval in degrees /minor 5 def % in addition there are even smaller tick marks every degree % outer radius of the protractor. Note that the width of the protractor is outer % if center_bottom_edge is set; otherwise outer + thickness / 2 /outer 4 inch def % thickness (outer radius - inner radius) of the protractor /thickness 1 inch def % end user definitions type 360 eq { /center_bottom_edge true def /offset 0 def } if /inner outer thickness sub def /tick_len outer inner sub 4 div def % syntax: x h arcsin -- computes arcsin (x/h) /arcsin { /hv exch def /xv exch def xv hv dup mul xv dup mul sub sqrt atan } bind def % temp string for int->str conversion /tmp 3 string def % set up font /Helvetica findfont 12 scalefont setfont /bottom_edge center_bottom_edge { 0 } { thickness -2 div } ifelse def type 360 eq { /inner_angle 0 def /amax 270 def outer 2 div 0 translate } { /inner_angle thickness bottom_edge add inner arcsin def type 90 eq { /amax 0 def 0 outer 2 div translate } { /amax 90 def } ifelse } ifelse % move protractor to center of page page_width outer sub bottom_edge neg add 2 div page_height 2 div translate % outer arc bottom_edge outer neg moveto 0 0 outer -90 amax arc center_bottom_edge not { amax 90 add dup rotate thickness 2 div 0 rlineto neg rotate } if bottom_edge type 180 eq {outer} {0} ifelse type 90 eq {bottom_edge neg add}if lineto bottom_edge outer neg lineto % inner arc type 360 eq { 0 0 moveto 0 0 inner -90 270 arc } { bottom_edge thickness add type 90 eq {thickness bottom_edge add neg} {0} ifelse 2 copy moveto 0 0 inner -90 inner_angle add amax inner_angle sub arc lineto } ifelse % crosshair, or if center is on bottom edge just a long tick mark and % half-circle center_bottom_edge { type 360 eq { tick_len 2 mul 0 moveto tick_len 2 mul neg 0 lineto tick_len 4 div 0 moveto 0 0 tick_len 4 div 0 360 arc } { bottom_edge 0 moveto tick_len 2 mul 0 rlineto 0 tick_len 4 div neg moveto 0 0 tick_len 4 div 270 amax arc } ifelse } { bottom_edge 0 moveto tick_len 0 rlineto type 90 eq { 0 thickness 2 div moveto 0 tick_len neg rlineto } if tick_len 2 div dup dup dup 0 exch moveto 0 exch neg lineto 0 moveto neg 0 lineto tick_len 4 div 0 moveto 0 0 tick_len 4 div 0 360 arc } ifelse % big tick-marks at 0 and 180 amax rotate inner 0 moveto outer 0 lineto amax neg rotate 0 outer neg moveto 0 inner neg lineto % the rest of the tick-marks -89 1 amax 1 sub { /angle exch def angle rotate % select tick-mark length based on angle angle major mod 0 eq { % major tick-mark labels, rotated to be parallel with long edge of page outer tick_len 2 mul sub 0 translate angle neg 90 sub rotate 0 0 moveto angle mirror not {neg} if offset exch sub tmp cvs dup stringwidth pop -2 div 0 moveto show angle 90 add rotate outer tick_len 2 mul sub neg 0 translate tick_len } { angle minor mod 0 eq { tick_len 2 div } { tick_len 4 div } ifelse } ifelse % draw tick on outer edge and inner edge if adjacent dup outer exch sub 0 moveto outer 0 lineto inner add 0 moveto amax angle sub inner_angle gt angle 90 add inner_angle gt and{ inner 0 lineto } if angle neg rotate } for % ruler on bottom edge metric { /unit 0.1 cm def /ticks1 10 def /ticks2 5 def /ticks3 1 def /ticks4 1 def } { /unit .0625 inch def /ticks1 16 def /ticks2 8 def /ticks3 4 def /ticks4 2 def } ifelse 1 1 outer unit div { /i exch def /x i unit mul neg def i ticks1 mod 0 eq { -90 rotate /num_text i ticks1 div cvi tmp cvs def /num_width num_text stringwidth pop def x num_width -2 div sub dup neg bottom_edge tick_len 4 add add moveto num_width -2 div add outer neg gt { num_text show amax 90 sub dup rotate num_width -2 div x add fontsize neg thickness 2 div bottom_edge add add moveto num_text show neg rotate } if 90 rotate tick_len } { i ticks2 mod 0 eq { tick_len 2 div } { i ticks3 mod 0 eq { tick_len 4 div } { i ticks4 mod 0 eq { tick_len 8 div } { tick_len 16 div } ifelse } ifelse } ifelse } ifelse bottom_edge x moveto dup 0 rlineto amax 90 sub rotate bottom_edge x neg moveto 0 rlineto 90 amax sub rotate } for % done! stroke showpage