Patch title: Release 94 bulk changes
Abstract:
File: /pliant/graphic/vector/stroke.pli
Key:
    Removed line
    Added line
module "/pliant/language/unsafe.pli"
module "/pliant/math/point.pli"
module "/pliant/math/vector.pli"
module "/pliant/math/curve.pli"
module "/pliant/math/curve/mode.pli"
module "/pliant/math/transform.pli"
module "/pliant/graphic/draw/prototype.pli"

constant epsilon 1e-3
constant default_epsilon 1e-3


function '+' p1 v -> p2
  arg Point2 p1 ; arg Vector2 v ; arg Point2 p2
  p2 x := p1:x+v:x
  p2 y := p1:y+v:y

function '-' p1 p2 -> v
  arg Point2 p1 p2 ; arg Vector2 v
  v x := p1:x-p2:x
  v y := p1:y-p2:y

function '*' c v -> w
  arg Float c ; arg Vector2 v w
  w x := c*v:x
  w y := c*v:y

function '*' v1 v2 -> p
  arg Vector2 v1 v2 ; arg Float p
  p := v1:x*v2:x+v1:y*v2:y

function norme v -> d
  arg Vector2 v ; arg Float d
  d := ( v:x*v:x + v:y*v:y )^0.5
  if d=undefined
    d := 0

function orthogonal v -> w
  arg Vector2 v w
  w x := -(v y)
  w y := v x

function resize v d -> w
  arg Vector2 v ; arg Float d ; arg Vector2 w
  w := (d/norme:v)*v

function intersection a b c d -> i
  arg Point2 a b c d i
  var Float m := a:y-b:y      # we have to solve (m n) * (X) = (x)
  var Float n := b:x-a:x      #                  (o p)   (Y)   (y)
  var Float o := c:y-d:y
  var Float p := d:x-c:x
  var Float det := m*p-o*n
  var Float x := a:x*m+a:y*n
  var Float y := c:x*o+c:y*p
  i x := (p*x-n*y)/det
  i y := (m*y-o*x)/det 


function '+=' c p
  arg_rw Curve c ; arg Point2 p
  c angle p:x p:y

function corner p0 p1 p2 width join miter line
  arg Point2 p0 p1 p2 ; arg Float width ; arg Int join ; arg Float miter ; arg_rw Curve line
  var Vector2 o01 := resize (orthogonal p1-p0) width/2
  var Vector2 o12 := resize (orthogonal p2-p1) width/2
  var Point2 q0 := p0+o01
  var Point2 q1 := p1+o01
  var Point2 q2 := p1+o12
  var Point2 q3 := p2+o12
  var Point2 inter := intersection q0 q1 q2 q3
  if join=2 or inter:x=undefined or inter:y=undefined or (norme inter-p1)>miter*width/2 or (inter-q1)*(q1-q0)<0 or (inter-q2)*(q2-q3)<0
    line += q1
    line += q2
  else
    line += inter


method curve polyline -> points
  arg Curve curve ; arg Array:Point2 points
method curve polyline epsilon -> points
  arg Curve curve ; arg Float epsilon ; arg Array:Point2 points
  points := curve polyline transform epsilon
  var Int j := 1
  while j<points:size
    if (norme (points j)-(points j-1))<epsilon/10
      for (var Int k) j points:size-2
        points k := points k+1
      points size -= 1
    else
      j += 1


method d stroke curves width options t color
  oarg_rw DrawPrototype d ; arg Array:Curve curves ; arg Float width ; arg Str options ; arg Transform2 t ; arg Address color
  var Int cap := options option "cap" Int 0
  var Int join := options option "join" Int 0
  var Float miter := options option "miter" Float 1.415
  var Float epsilon := options option "epsilon" Float default_epsilon
  for (var Int i) 0 curves:size-1
    if curves:i=success
      (var Array:Curve stroke) size := 0
      var Array:Point2 points := curves:i polyline
      var Array:Point2 points := curves:i polyline epsilon
      if (curves:i:mode .and. outline)<>0
        if points:size>1 and (norme (points points:size-1)-(points 0))<epsilon/10
          points size -= 1
        var Int m := points size
        (var Curve line) reset
        for (var Int j) 0 m-1
          corner (points j) (points (j+1)%m) (points (j+2)%m) width join miter line
        line compute outline
        if line=success
          stroke += line
        (var Curve line) reset
        for (var Int j) 0 m-1
          corner (points m-1-j) (points m-1-(j+1)%m) (points m-1-(j+2)%m) width join miter line
        line compute outline
        if line=success
          stroke += line
      else
        (var Curve line) reset
        line += points:0+(resize (orthogonal points:1-points:0) width/2)
        for (var Int j) 0 points:size-3
          corner (points j) (points j+1) (points j+2) width join miter line
        line += (points points:size-1)+(resize (orthogonal (points points:size-1)-(points points:size-2)) width/2)
        line += (points points:size-1)+(resize (orthogonal (points points:size-2)-(points points:size-1)) width/2)
        for (var Int j) points:size-1 2 step -1
          corner (points j) (points j-1) (points j-2) width join miter line
        line += points:0+(resize (orthogonal points:0-points:1) width/2)
        line compute outline
        if line=success
          stroke += line
      if stroke:size>0
        d fill stroke fill_nonzero t color
        if false # width>1
          var Int all := -1
          d stroke stroke 0.5 "" t addressof:all


export '. stroke'