%% Centered Dash Patterns
%%                PostScript Language Tutorial and Cookbook

/centerdash {
  /pattern exch def
  /pathlen pathlength cvi def

  /patternlength 0 def
  pattern { patternlength add /patternlength
    exch def } forall
  pattern length 2 mod 0 ne {
    /patternlength patternlength 2 mul def } if
  /first pattern 0 get def
  /last patternlength first sub def
  /n pathlen last sub patternlength idiv def
  /endpart pathlen patternlength n mul sub last sub 2 div def

  /offset first endpart sub def
  pattern offset setdash
  } bind def

/pathlength {
  flattenpath
  /dist 0 def

  { /yfirst exch def /xfirst exch def
    /ymoveto yfirst def /xmoveto xfirst def }
  { /ynext exch def /xnext exch def
    /dist dist xnext xfirst sub dup mul
               ynext yfirst sub dup mul add sqrt add def
    /yfirst ynext def /xfirst xnext def }
  {}
  { /ynext ymoveto def /xnext xmoveto def
    /dist dist xnext xfirst sub dup mul
               ynext yfirst sub dup mul add sqrt add def
    /yfirst ynext def /xfirst xnext def }
    pathforall
  dist } def

5 setlinewidth

newpath
  72 500 moveto 378 500 lineto [30] centerdash stroke
newpath
  72 400 moveto 378 400 lineto [30 50] centerdash stroke
newpath
  72 300 moveto 378 300 lineto [30 10 5 10] centerdash stroke
newpath
  72 200 moveto 378 200 lineto [30 15 10] centerdash stroke
newpath
  225 390 300 240 300 arc [40 10] centerdash stroke

showpage

