subroutine astro_draw(name,icat,argum,clip,error)
  use gbl_message
  use gkernel_types
  use gkernel_interfaces, no_interface=>gr8_marker
  use astro_interfaces, except_this=>astro_draw
  use ast_astro
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: name
  integer(kind=4),  intent(in)    :: icat
  character(len=*), intent(in)    :: argum(:) ! /Draw arguments
  logical,          intent(in) :: clip          ! clipping of source names
  logical,          intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='DRAW'
  real(kind=8) :: x,y
  character(len=commandline_length) :: command
  logical :: in,clip_state
  integer(kind=4) :: ns,is,i
  real(kind=4) :: siz,flux,test,zmin,xp,yp,xlen,ylen,margin
  parameter (zmin=5)
  type(projection_t) :: gregproj
  !
  ! Get new plot coords
  if (projection) then
    call greg_projec_get(gregproj)  ! Get current Greg projection
    if (frame.eq.'EQUATORIAL') then
      call abs_to_rel(gregproj,ra,dec,x,y,1)
    else
      call abs_to_rel(gregproj,azimuth,elevation,x,y,1)
    endif
  else
    if (frame.eq.'EQUATORIAL') then
      x = ra
      y = dec
    else
      x = azimuth
      y = elevation
    endif
  endif
  if (nsplot.lt.msplot .and. icat.gt.0) then
    nsplot = nsplot+1
    splot(nsplot) = name
    ccplot(nsplot) = catalog_name(icat)
    xsplot(nsplot) = x
    ysplot(nsplot) = y
    zsplot(nsplot) = z_axis
  endif
  !
  call gr_exec1('SET COORD USER')
  clip_state = gr_clip(.true.)
  in = isvisible(x,y)
  if (frame.eq.'HORIZONTAL') in = in .and. (elevation.ge.0d0)
  !
  do i=1,size(argum)
    if (argum(i).eq.'')  cycle
    !
    ! LINE
    if (argum(i).eq.'L') then
      call gr_segm('LINE',error)
      if (frame.eq.'EQUATORIAL') then
        call great_circle(ra_old,dec_old,ra,dec,error)
      elseif (frame.eq.'HORIZONTAL') then
        call great_circle(azimuth_old,elevation_old, azimuth,elevation,error)
      endif
      call gr_segm_close(error)
    endif
    !
    if (.not.in)  cycle  ! Next argument
    !
    ! MARKER or FULL
    if (argum(i).eq.'M' .or. argum(i).eq.'F') then
      call gr_get_marker(ns,is,siz)
      if (z_axis_type.eq.'MA') then
        flux = max((1.-(z_axis/zmin))*siz,0.0)
      elseif (z_axis_type.eq.'FL') then
        if (z_axis.ne.0) then
          ! test = -2.5*alog10(z_axis/100.)
          test = -5*alog10(z_axis) ! 1 Jy -> mag 0
          flux = max((1.-(test/zmin))*siz,0.0)
        else
          flux = siz
        endif
      endif
      call gr_set_marker(ns,is,flux)
      call gr_segm('MARKER',error)
      call gr8_marker(1,x,y,0d0,-1d0)
      call gr_segm_close(error)
      call gr_set_marker(ns,is,siz)
    endif
    !
    ! FULL
    if (argum(i).eq.'F') then  ! FULL = MARKER + SYMBOL above marker
      ! --- Ugly trick to Y-shift the text by one marker height
      call relocate(x,y)          ! Locate pen at marker position
      call gr_where(x,y,xp,yp)    ! Get pen position in user and phys coordinates
      call grelocate(xp,yp+flux)  ! Relocate pen at Y-shifted phys coordinates
      call gr_where(x,y,xp,yp)    ! Get pen position in user and phys coordinates
      ! --- End of trick
      write(command,'(A,2(1PG14.6,1X),3A)')  &
        'DRAW TEXT ',x,y,'"',trim(name),'" 8 /USER'
      if (clip) then
        write(command,'(A,1X,A)') trim(command),'/CLIP SOFT'
      endif
      call gr_exec1(command)
      call relocate(x,y)  ! Relocate pen at exact source position
    endif
    !
    ! SYMBOL
    if (argum(i).eq.'S') then
      write(command,'(A,2(1PG14.6,1X),3A)')  &
        'DRAW TEXT ',x,y,'"',trim(name),'" 5 /USER'
      if (clip) then
        write(command,'(A,1X,A)') trim(command),'/CLIP SOFT'
      endif
      call gr_exec1(command)
      call relocate(x,y)  ! Relocate pen at exact source position
    endif
    !
    ! BOX
    if (argum(i).eq.'B') then
      ! Get string height, taking into account G\SET CHAR and G\SET EXPAND.
      ! "\\g." is a square symbol, i.e. get its width and reuse it as height.
      call gstrlen(4,'\\g.',ylen)
      margin = ylen/10.
      ylen = ylen/2.+margin
      call gstrlen(len_trim(name),name,xlen)
      xlen = xlen/2.+margin
      call relocate(x,y)               ! Relocate pen at exact source position
      call gr_where(x,y,xp,yp)         ! Get pen position in user and physical
      call gr_segm('BOX',error)
      call grelocate(xp-xlen,yp-ylen)  ! Relocate at 1st box corner (physical coordinates)
      call gdraw    (xp+xlen,yp-ylen)  ! Draw to 2nd box corner (physical coordinates)
      call gdraw    (xp+xlen,yp+ylen)  !
      call gdraw    (xp-xlen,yp+ylen)  !
      call gdraw    (xp-xlen,yp-ylen)  ! Close the box
      call gr_segm_close(error)
      call relocate(x,y)               ! Relocate pen at exact source position
    endif
    !
  enddo
  elevation_old=elevation
  azimuth_old=azimuth
  ra_old=ra
  dec_old=dec
  !
contains
  function isvisible(x,y)
    logical :: isvisible
    real(kind=8), intent(in) :: x,y
    ! Local
    real(kind=8) :: xmin,xmax,ymin,ymax,x1
    !
    call sic_get_dble('USER_XMIN',xmin,error)
    call sic_get_dble('USER_XMAX',xmax,error)
    call sic_get_dble('USER_YMIN',ymin,error)
    call sic_get_dble('USER_YMAX',ymax,error)
    if (xmax.lt.xmin) then
      x1 = xmin
      xmin = xmax
      xmax = x1
    endif
    if (ymax.lt.ymin) then
      x1 = ymin
      ymin = ymax
      ymax = x1
    endif
    isvisible = x.le.xmax .and. x.ge.xmin  .and. y.le.ymax .and. y.ge.ymin
  end function isvisible
  !
end subroutine astro_draw
!
subroutine astro_draw_parse(caller,line,optdraw,drawargs,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>astro_draw_parse
  !---------------------------------------------------------------------
  ! @ private
  !  Support routine for
  !   SOURCE|PLANET /DRAW Arg1 ... ArgN
  !  Parse the arguments of the option /DRAW
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: caller
  character(len=*), intent(in)    :: line
  integer(kind=4),  intent(in)    :: optdraw
  character(len=*), intent(out)   :: drawargs(:)
  logical,          intent(inout) :: error
  ! Local
  integer(kind=4) :: iarg,narg,ikey,nc
  character(len=12) :: arg,key
  character(len=message_length) :: mess
  integer(kind=4), parameter :: mdrawkinds=5
  character(len=6), parameter :: drawkinds(mdrawkinds) =  &
    (/ 'LINE  ', 'MARKER', 'SYMBOL', 'FULL  ', 'BOX   ' /)
  !
  ! Loop on arguments of /DRAW
  drawargs(:) = ''
  narg = sic_narg(optdraw)
  if (narg.gt.size(drawargs)) then
    narg = size(drawargs)
    write(mess,'(A,I0,A)')  '/DRAW argument list truncated to ',narg,' keywords'
    call astro_message(seve%w,caller,mess)
  endif
  !
  if (narg.le.0) then
    drawargs(1) = 'S'  ! Default SYMBOL
    return
  endif
  !
  do iarg=1,narg
    call sic_ke(line,1,iarg,arg,nc,.true.,error)
    if (error) return
    call sic_ambigs(caller,arg,key,ikey,drawkinds,mdrawkinds,error)
    if (error)  return
    drawargs(iarg) = key  ! Truncated to 1 character
  enddo
  !
end subroutine astro_draw_parse
