subroutine gtx_chopper(out,cx1,cy1,cx2,cy2,up)
  use gtv_interfaces, except_this=>gtx_chopper
  use gtv_types
  use gtv_graphic
  use gtv_plot
  !---------------------------------------------------------------------
  ! @ private
  !  Dashed pattern and thickness generator
  !  Tente de corriger problemes vicieux si segments aleatoires tres
  ! courts ET segments nuls en mode pointille... Supprime le code
  ! specifique "segment longueur nulle"
  !---------------------------------------------------------------------
  type(gt_display), intent(inout) :: out      ! Input gt_display
  real*4,           intent(in)    :: cx1,cy1  ! X,Y coordinate of start point
  real*4,           intent(in)    :: cx2,cy2  ! X,Y coordinate of end point
  logical,          intent(in)    :: up       ! Force goto (CX1,CY1) pen up
  ! Local
  logical :: penup,trace, debut_trace
  save debut_trace
  real*4 :: start, dist, dtogo
  real*4 :: xc, yc, xd, yd, frac, d
  integer*4 :: istart, k
  !
  if (out%idashe.eq.1) then
    ! Solid line: no dash generator to use
    call gtx_weight(out,cx1,cy1,cx2,cy2,up)
    return
  endif
  !
  start = amod(out%totdist,onofflen(out%idashe))
  out%totdist = start
  do istart = 1,4
    if (start.lt.onoff(istart,out%idashe))  goto 6
    start = start - onoff(istart,out%idashe)
  enddo
  istart = 1                   ! Take care of rounding errors
6 continue
  !
  debut_trace = up .or. debut_trace
  penup       = debut_trace
  !
  dist = sqrt((cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1))
  xc = cx1
  yc = cy1
  dtogo = dist
  !
  k = istart
  d = onoff(k,out%idashe) - start
  trace = mod(istart,2).eq.1
  !
  do while (.true.)
    if (dtogo .eq. 0.0) then
      frac = 1.0
    else
      frac = min(d,dtogo) / dtogo
    endif
    xd = xc + frac*(cx2-xc)
    yd = yc + frac*(cy2-yc)
    if (trace) then
      if (out%iweigh.le.graisse(1)) then
        if (penup) call gtx_plot(out,xc,yc,3)
        call gtx_plot(out,xd,yd,2)
      else
        call gtx_weight(out,xc,yc,xd,yd,penup)
      endif
      debut_trace = .false.
    else
      debut_trace = .true.
      penup = .true.
    endif
    dtogo = dtogo - d
    if (dtogo.le.0.) goto 10
    xc = xd
    yc = yd
    if (k.lt.4) then
      k = k+1
    else
      k = 1
    endif
    trace = .not.trace
    d = onoff(k,out%idashe)
  enddo
  !
10 out%totdist = out%totdist + dist
end subroutine gtx_chopper
!
subroutine gtx_weight(out,cxa,cya,cxb,cyb,up)
  use gtv_interfaces, except_this=>gtx_weight
  use gtv_types
  use gtv_graphic
  !---------------------------------------------------------------------
  ! @ private
  !  Thickness generator (Suited for pencil plotters)
  !---------------------------------------------------------------------
  type(gt_display), intent(inout) :: out      ! Input gt_display
  real*4,           intent(in)    :: cxa,cya  ! X,Y coordinate of start point
  real*4,           intent(in)    :: cxb,cyb  ! X,Y coordinate of end point
  logical,          intent(in)    :: up       ! Force goto (CXA,CYA) pen up
  ! Local
  real*4 :: cx1,cx2,cy1,cy2
  integer :: lw,lw1,lw2,j
  !
  if (up) call gtx_plot(out,cxa,cya,3)
  ! Suppress above line for raster devices
  !
  if (out%dev%hardw_line_weig) then
    ! Device knows how to produce line width
    call gtx_plot(out,cxb,cyb,2)
    return
  endif
  !
  lw = max(set_weight_pixel(out),1)  ! We can get 0 for "hairline"
  lw1 = -(lw-1)/2
  lw2 = lw/2
  !
  do j=lw1,lw2
    !
    if (abs(cyb-cya).gt.abs(cxb-cxa)) then
      if (j.gt.0) then
        cx1 = min(cxa+j/60.,out%gx2)
        cx2 = min(cxb+j/60.,out%gx2)
      elseif (j.lt.0) then
        cx1 = max(cxa+j/60.,out%gx1)
        cx2 = max(cxb+j/60.,out%gx1)
      else
        cx1 = cxa
        cx2 = cxb
      endif
      cy1 = cya
      cy2 = cyb
    else
      if (j.gt.0) then
        cy1 = min(cya+j/60.,out%gy2)
        cy2 = min(cyb+j/60.,out%gy2)
      elseif (j.lt.0) then
        cy1 = max(cya+j/60.,out%gy1)
        cy2 = max(cyb+j/60.,out%gy1)
      else
        cy1 = cya
        cy2 = cyb
      endif
      cx1 = cxa
      cx2 = cxb
    endif
    !
    call gtx_plot(out,cx1,cy1,2)
    ! call gtx_plot(out,cx1,cy1,3) ! For raster devices
    !
    call gtx_plot(out,cx2,cy2,2)
    !
  enddo  ! j
  !
end subroutine gtx_weight
