subroutine labels(line,error)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>labels
  use greg_kernel
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  ! GREG	Support routine for command
  !	LABEL "Un texte quelconque" [Orien] /APPEND /CENTERING n 
  !       /X [Yoffset] /Y [Xoffset]
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line          ! Command line
  logical, intent(inout) :: error               ! Error flag
  ! Local
  character(len=*), parameter :: rname='LABEL'
  integer(4) :: lcar,iset,iloc,i
  real(8) :: angsa
  real(4) :: off
  character(len=256) :: chain
  !
  if (.not.sic_present(0,1)) then
    call greg_message(seve%e,rname,'No string given')
    error = .true.
    return
  endif
  !
  ! Check the options present
  iset = 0
  do i=1,4
    if (sic_present(i,0)) then
      if (iset.ne.0) then
        call greg_message(seve%e,rname,'Conflicting options')
        error = .true.
        return
      else
        iset = i
      endif
    endif
  enddo
  call sic_ch (line,0,1,chain,lcar,.true.,error)
  if (error) return
  angsa = tangle
  call sic_r8 (line,0,2,tangle,.false.,error)
  if (error) return
  !
  iloc = icente
  if (iset.eq.1) then
    off = label_xoff
    call sic_r4(line,1,1,off,.false.,error)
    call xlabel(lcar,chain,off)    ! /X
  elseif (iset.eq.2) then
    off = label_yoff
    call sic_r4(line,2,1,off,.false.,error)
    call ylabel(lcar,chain,off)    ! /Y
  elseif (iset.eq.4) then
    call label(lcar,chain,tangle,.false.)  ! /APPEND
  else
    if (iset.eq.3) then
      call sic_i4 (line,3,1,iloc,.false.,error)
      if (error) then
        tangle = angsa
        return
      endif
    endif
    if (iloc.eq.0) iloc = 6
    call putlabel(lcar,chain,iloc,tangle,.false.) ! /CENTER Iloc
  endif
  tangle = angsa
end subroutine labels
!
subroutine xlabel(nchar,string,off)
  use greg_interfaces, except_this=>xlabel
  use greg_kernel
  use greg_pen
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  ! GREG	Internal routine
  !	  Write an X label
  !---------------------------------------------------------------------
  integer(4), intent(in) :: nchar                ! Number of characters
  character(len=*), intent(in) :: string         ! String
  real(4), intent(in) :: off                     ! Offset in Y from axis
  ! Local
  real(4) :: ch,xstart,ystart,slength
  real(8) :: angle
  !
  call setdas(1)
  angle = 0.d0
  ch = cdef * expand * cheight
  call gstrlen(nchar,string,slength)
  xstart = gx1 + (gx2 - gx1 - slength) / 2
  ystart = gy1 - off * ch
  if (ystart.lt.ch/2) then
    call greg_message(seve%w,'XLABEL','Label brought back within PLOT_PAGE')
    ystart = ch/2
  endif
  call grelocate(xstart,ystart)
  call gstring(nchar,string,angle,.false.)
end subroutine xlabel
!
subroutine ylabel(nchar,string,off)
  use phys_const
  use gbl_message
  use greg_interfaces, except_this=>ylabel
  use greg_kernel
  use greg_pen
  !---------------------------------------------------------------------
  ! @ private
  ! GREG	Internal routine
  !	Write an Y label at proper position
  !---------------------------------------------------------------------
  integer(4), intent(in) :: nchar                ! Number of characters
  character(len=*), intent(in) :: string         ! String
  real(4), intent(in) :: off                     ! Offset in X from axis
  ! Local
  real(4) :: ch,cw,xstart,ystart,slength
  real(8) :: angle
  !
  call setdas(1)
  angle = pi/2.d0
  cw = cdef * expand * cwidth
  ch = cdef * expand * cheight / 2
  call gstrlen(nchar,string,slength)
  ystart = gy1 + (gy2 - gy1 - slength) / 2
  xstart = gx1 - off * cw
  if (xstart.lt.ch*0.7) then
    call greg_message(seve%w,'YLABEL','Label brought back within PLOT_PAGE')
    xstart = ch*0.7
  endif
  call grelocate(xstart,ystart)
  call gstring(nchar,string,angle,.false.)
end subroutine ylabel
!
subroutine putlabel(nchar,string,loc,angle,doclip)
  use phys_const
  use greg_interfaces, except_this=>putlabel
  use greg_kernel
  use greg_pen
  !---------------------------------------------------------------------
  ! @ private
  !  Puts a label according to location (VT100 numeric Keypad...)
  !     7 8 9
  !     4 5 6
  !     1 2 3
  ! Left, center or right in X and Y
  !---------------------------------------------------------------------
  integer(kind=4),  intent(in) :: nchar   ! Number of characters
  character(len=*), intent(in) :: string  ! String
  integer(kind=4),  intent(in) :: loc     ! Centering option
  real(kind=8),     intent(in) :: angle   ! [deg] Text angle
  logical,          intent(in) :: doclip  ! Clip the text to the current box?
  ! Local
  real(kind=4) :: ch,slength,xstart,ystart,dx,dy
  real(kind=8) :: alpha
  integer(kind=4) :: xsign,ysign
  !
  if (loc.ne.6) then
    ch = cdef * expand * cheight
    call gstrlen(nchar,string,slength)
    xsign = mod(loc-1,3) - 1
    ysign = (loc-1)/3 - 1
    dx = (xsign - 1) * .5 * slength
    dy = ysign * .5 * ch
    alpha = angle*pi/180.d0
    xstart = xp + dx * cos(alpha) - dy * sin(alpha)
    ystart = yp + dx * sin(alpha) + dy * cos(alpha)
    call grelocate(xstart,ystart)
  endif
  !
  call label(nchar,string,angle,doclip)
  !
end subroutine putlabel
!
subroutine label(nchar,string,angle,doclip)
  use phys_const
  use greg_interfaces, except_this=>label
  !---------------------------------------------------------------------
  ! @ private
  ! Puts a label at current location, with current angle
  !---------------------------------------------------------------------
  integer(kind=4),  intent(in) :: nchar   ! Number of characters
  character(len=*), intent(in) :: string  ! String
  real(kind=8),     intent(in) :: angle   ! [deg] Text angle
  logical,          intent(in) :: doclip  ! Soft clipping?
  ! Local
  real(kind=8) :: alpha
  !
  call setdas(1)
  alpha = angle*pi/180.d0
  call gstring(nchar,string,alpha,doclip)
end subroutine label
