Patch title: Release 90 bulk changes
Abstract:
File: /graphic/image/transform.pli
Key:
    Removed line
    Added line
module "/pliant/language/compiler.pli"
module "prototype.pli"
module "/pliant/language/compiler/type/inherit.pli"
module "/pliant/math/point.pli"
module "/pliant/math/vector.pli"
module "/pliant/math/transform.pli"
module "/pliant/graphic/misc/transform.pli"

constant advanced true


type ImageTransform
  inherit ImagePrototype
  field Link:ImagePrototype image
  field Point2 z ; field Vector2 vx vy
  field Float zx zy ; field Float vxx vxy vyx vyy
  field CBool always_inside

ImagePrototype maybe ImageTransform


method p index_x x -> i
  arg ImagePrototype p ; arg Float x ; arg Int i
  i := cast (x-p:x0)/(p:x1-p:x0)*p:size_x-0.499 Int

method p index_y y -> i
  arg ImagePrototype p ; arg Float y ; arg Int i
  i := cast (y-p:y0)/(p:y1-p:y0)*p:size_y-0.499 Int

method p mm_x i -> x
  arg ImagePrototype p ; arg Int i ; arg Float x
  x := p:x0+i/p:size_x*(p:x1-p:x0)

method p mm_y i -> y
  arg ImagePrototype p ; arg Int i ; arg Float y
  y := p:y0+i/p:size_y*(p:y1-p:y0)

method t bind image trans target options -> status
  oarg_rw ImageTransform t ; oarg ImagePrototype image ; arg Transform2 trans ; arg ImagePrototype target ; arg Str options ; arg ExtendedStatus status
  t image :> image
  trans bbox image:x0 image:y0 image:x1 image:y1 (var Float tx0) (var Float ty0) (var Float tx1) (var Float ty1)
  var Int ix0 := max (target index_x tx0) 0
  var Int iy0 := max (target index_y ty0) 0
  var Int ix1 := min (target index_x tx1)+1 target:size_x
  var Int iy1 := min (target index_y ty1)+1 target:size_y
  addressof:t map ImagePrototype := image_prototype (target mm_x ix0) (target mm_x iy0) (target mm_x ix1) (target mm_x iy1) ix1-ix0 iy1-iy0 image:gamut
  if ix1=ix0
    if ix1<target:size_x
      ix1 += 1
    else
      ix0 -= 1
  if iy1=iy0
    if iy1<target:size_y
      iy1 += 1
    else
      iy0 -= 1
  check ix0>=0 and iy0>=0 and ix1<=target:size_x and iy1<=target:size_y
  check ix1>ix0 and iy1>iy0
  addressof:t map ImagePrototype := image_prototype (target mm_x ix0) (target mm_y iy0) (target mm_x ix1) (target mm_y iy1) ix1-ix0 iy1-iy0 image:gamut
  var Transform2 d := compose (transform image:x0 image:y0 (image:x1-image:x0)/image:size_x (image:y1-image:y0)/image:size_y 0 0) trans (transform -(t x0)*t:size_x/(t:x1-t:x0) -(t y0)*t:size_y/(t:y1-t:y0) t:size_x/(t:x1-t:x0) t:size_y/(t:y1-t:y0) 0 0)
  var Transform2 r := reverse d
  t z := r (point 0 0)
  t vx := r (vector 1 0)
  t vy := r (vector 0 1)
  var Point2 p := r (point 0.5 0.5) ; t zx := p:x-0.499 ; t zy := p:y-0.499
  var Vector2 v := r (vector 1 0) ; t vxx := v x ; t vxy := v y
  var Vector2 v := r (vector 0 1) ; t vyx := v x ; t vyy := v y
  t always_inside := options option "always_inside"
  status := success

method t read x y count adr
  oarg_rw ImageTransform t ; arg Int x y count ; arg Address adr
  var Int psize := t pixel_size
  memory_clear adr count*psize
  var Int mx0 := 0 ; var Int mx1 := 0 ; var Int my ; var Address madr := null
  var Point2 p
  p x := t:z:x+x*t:vx:x+y*t:vy:x
  p y := t:z:y+x*t:vx:y+y*t:vy:y
  var Address a := adr ; var Address stop := adr translate Byte count*psize
  while a<>stop
    var Int ix := cast p:x Int
    var Int iy := cast p:y Int
    if iy=my and ix>=mx0 and ix<mx1
      memory_copy (madr translate Byte (ix-mx0)*psize) a psize
    eif iy>=0 and iy<t:image:size_y and ix>=0 and ix<t:image:size_x
      if madr<>null
        t:image read_unmap mx0 my mx1-mx0 madr
      mx0 := 0 ; my := iy ; madr := t:image read_map mx0 my ix+1 t:image:size_x (var Int mcount) ; mx1 := mx0+mcount
      if mx1<=ix

if advanced

  method t read x y count adr
    oarg_rw ImageTransform t ; arg Int x y count ; arg Address adr
    var Int psize := t pixel_size
    if not t:always_inside
      memory_clear adr count*psize
    var Int factor := 2^29\(max (max abs:(cast t:vxx Int) abs:(cast t:vxy Int)) 1)
    var Float px := t:zx+x*t:vxx+y*t:vyx ; var Int ix := cast px Int ; var Int fx := cast (px-ix+0.499)*factor Int
    var Int dx := cast t:vxx*factor Int
    var Float py := t:zy+x*t:vxy+y*t:vyy ; var Int iy := cast py Int ; var Int fy := cast (py-iy+0.499)*factor Int
    var Int dy := cast t:vxy*factor Int
    var Int mx0 my0 mx1 my1 ; var Int step_x step_y ; var Address madr := null
    var CBool eoa := true ; var Address c
    var Address a := adr ; var Address stop := adr translate Byte count*psize
    while a<>stop
      if eoa
        if madr<>null
          t:image read_unmap mx0 my mx1-mx0 madr
        mx0 := ix ; my := iy ; madr := t:image read_map mx0 my 1 t:image:size_x-ix (var Int mcount) ; mx1 := mx0+mcount
          t:image rectangle_read_unmap mx0 my0 mx1 my1 madr
          madr := null
        if ix>=0 and ix<t:image:size_x and iy>=0 and iy<t:image:size_y
          madr := t:image rectangle_read_map ix iy mx0 my0 mx1 my1 step_x step_y
          if madr=null
            error error_id_missing "Transform requires mapping capabilities"
          c := madr translate Byte (ix-mx0)*step_x+(iy-my0)*step_y
          memory_copy c a psize
          eoa := false
      else
        memory_copy c a psize
      a := a translate Byte psize
      fx += dx
      while fx>=factor
        ix += 1 ; fx -= factor
        c := c translate Byte step_x
        if ix>=mx1
          eoa := true        
      while fx<0
        ix -= 1 ; fx += factor
        c := c translate Byte -step_x
        if ix<mx0
          eoa := true        
      fy += dy
      while fy>=factor
        iy += 1; fy -= factor
        c := c translate Byte step_y
        if iy>=my1
          eoa := true        
      while fy<0
        iy -= 1 ; fy += factor
        c := c translate Byte -step_y
        if iy<my0
          eoa := true        
    if madr<>null
      t:image rectangle_read_unmap mx0 my0 mx1 my1 madr

  method t line_clip x y count
    oarg_rw ImageTransform t ; arg_rw Int x y count
    var Int factor := 2^29\(max (max abs:(cast t:vxx Int) abs:(cast t:vxy Int)) 1)
    var Int dx := cast t:vxx*factor Int
    var Int dy := cast t:vxy*factor Int
    for (var Int lap) 0 1
      var Float px := t:zx+(x+(shunt lap=0 0 count-1))*t:vxx+y*t:vyx ; var Int ix := cast px Int ; var Int fx := cast (px-ix+0.499)*factor Int
      var Float py := t:zy+(x+(shunt lap=0 0 count-1))*t:vxy+y*t:vyy ; var Int iy := cast py Int ; var Int fy := cast (py-iy+0.499)*factor Int
      if lap=1
        dx := -dx ; dy := -dy
      while (ix<0 or ix>=t:image:size_x or iy<0 or iy>=t:image:size_y) and count>0
        if lap=0
          x += 1
        count -= 1
        fx += dx
        while fx>=factor
          ix += 1 ; fx -= factor
        while fx<0
          ix -= 1 ; fx += factor
        fy += dy
        while fy>=factor
          iy += 1; fy -= factor
        while fy<0
          iy -= 1 ; fy += factor

else

  method t read1 x y count adr
    oarg_rw ImageTransform t ; arg Int x y count ; arg Address adr
    var Int psize := t pixel_size
    if not t:always_inside
      memory_clear adr count*psize
    var Int mx0 := 0 ; var Int my0 := 0 ; var Int mx1 := 0 ; var Int my1 := 0 ; var Int step_x step_y ; var Address madr := null
    var Float px := t:zx+x*t:vxx+y*t:vyx
    var Float py := t:zy+x*t:vxy+y*t:vyy
    var Address a := adr ; var Address stop := adr translate Byte count*psize
    while a<>stop
      var Int ix := cast px Int
      var Int iy := cast py Int
      if ix>=mx0 and ix<mx1 and iy>=my0 and iy<my1
        memory_copy (madr translate Byte (ix-mx0)*step_x+(iy-my0)*step_y) a psize
      eif ix>=0 and ix<t:image:size_x and iy>=0 and iy<t:image:size_y
        if madr<>null
          t:image rectangle_read_unmap mx0 my0 mx1 my1 madr
        madr := t:image rectangle_read_map ix iy mx0 my0 mx1 my1 step_x step_y
        if madr=null
          error error_id_missing "Transform requires mapping capabilities"
          return
      memory_copy (madr translate Byte (ix-mx0)*psize) a psize
    p x += t:vx x ; p y += t:vx y ; a := a translate Byte psize
  if madr<>null
    t:image read_unmap mx0 my mx1-mx0 madr
        memory_copy (madr translate Byte (ix-mx0)*step_x+(iy-my0)*step_y) a psize
      px += t vxx ; py += t vxy ; a := a translate Byte psize
    if madr<>null
      t:image rectangle_read_unmap mx0 my0 mx1 my1 madr
  

export ImageTransform '. bind'
  method t is_inside x y -> c
    oarg_rw ImageTransform t ; arg Int x y ; arg CBool c
    var Int ix := cast t:zx+x*t:vxx+y*t:vyx Int
    if ix<0 or ix>=t:image:size_x
      return false
    var Int iy := cast t:zy+x*t:vxy+y*t:vyy Int
    if iy<0 or iy>=t:image:size_y
      return false
    c := true

  method t line_clip x y count
    oarg_rw ImageTransform t ; arg_rw Int x y count
    while not (t is_inside x y) and count>0
      x += 1 ; count -= 1
    while not (t is_inside x+count-1 y) and count>0
      count -= 1

export ImageTransform '. bind' '. line_clip'