subroutine gtchar(nchars,string,size,slength,xp,yp,co,si,ic,ifont,  &
  doclip,gpoly_clip)
  use phys_const
  use gtv_dependencies_interfaces
  use gtv_interfaces, except_this=>gtchar
  use gtv_tree
  use gtv_buffers
  use gtv_graphic
  use gtv_protocol
  !---------------------------------------------------------------------
  ! @ public
  !   Plots a character string according to current line attributes.
  ! Indices, subscripts, and special fonts are selected using the escape
  ! character \ (C.f. GREG and VSTRIN routine in CHARSHR).
  !
  !   The hard font line attribute is incompatible with the handling of
  ! the escape character \ . The argument IFONT indicates which font
  ! should be taken into account: 0 = Hardware, 1 Simplex, 2 Duplex. If
  ! the hardware generator cannot reasonably match (CO,SI) and SIZE, the
  ! SIMPLEX font is used.
  !---------------------------------------------------------------------
  integer(kind=4),  intent(in)  :: nchars      ! Number of characters
  character(len=*), intent(in)  :: string      ! Character string
  real(kind=4),     intent(in)  :: size        ! Character width (plot page units)
  real(kind=4),     intent(out) :: slength     ! String length (plot page units)
  real(kind=4),     intent(in)  :: xp          ! Position where to write the string
  real(kind=4),     intent(in)  :: yp          !
  real(kind=4),     intent(in)  :: co          ! Cosine of angle
  real(kind=4),     intent(in)  :: si          ! Sine of angle
  integer(kind=4),  intent(in)  :: ic          ! Centering option according to GREG conventions
  integer(kind=4),  intent(in)  :: ifont       ! Font type (0 Simplex, 1 Duplex)
  logical,          intent(in)  :: doclip      ! Clip with current Greg box?
  external                      :: gpoly_clip  !
  ! Interfaces
  interface
    subroutine gpoly_clip(nq,xq,yq)
      use gildas_def
      integer(kind=size_length), intent(in) :: nq     ! Number of points
      real(kind=4),              intent(in) :: xq(*)  ! Plot X coordinates
      real(kind=4),              intent(in) :: yq(*)  ! Plot Y coordinates
    end subroutine gpoly_clip
  end interface
  ! Local
  real(kind=4) :: rxp,ryp,xstart,ystart,dx,dy,angle
  integer(kind=4) :: xsign,ysign,kfont
  !
  if (.not.awake .or. error_condition)  return
  !
  if (nchars.le.0) then
    slength = 0.
    return
  endif
  !
  ! Save the current GTWHERE
  rxp = polyl%x(polyl%n)
  ryp = polyl%y(polyl%n)
  !
  ! Get the current font KFONT: 0 Simplex quality, 1 for Duplex.
  ! Compute position
  kfont = max(ifont,0)
  if (ic.ne.6) then
    xsign = mod(ic-1,3) - 1
    ysign = (ic-1)/3 - 1
    if (xsign.eq.1) then
      dx = 0
    else
      call vstrin(nchars,string,.false.,slength,0.,0.,0.,kfont,size,  &
        doclip,gtpolyl,gpoly_clip)
      dx = (xsign - 1) * 0.5 * slength
    endif
    dy = ysign * 0.5 * size
    xstart = xp + dx * co - dy * si
    ystart = yp + dy * co + dx * si
  else
    xstart = xp
    ystart = yp
  endif
  !
  ! Call the font generator
  ! We should pass CO and SI in argument of VSTRIN, not ANGLE...
  angle = atan2(si,co)
  angle = angle*180.0/pis
  ! Clipping or not clipping?
  !  - If clipping is not wanted, use directly the GTV dedicated subroutine
  !    (gtpolyl)
  !  - If clipping to the current box is wanted, use the GREG dedicated
  !    subroutine (passed as argument). This makes sense because the box
  !    is a Greg feature, not GTV.
  call vstrin(nchars,string,.true.,slength,xstart,ystart,angle,kfont,size,  &
    doclip,gtpolyl,gpoly_clip)
  !
  ! Reset the virtual pen location
  call gtreloc (rxp,ryp)
end subroutine gtchar
!
subroutine gtg_charlen (nchars,string,size,slength,ifont)
  use gtv_dependencies_interfaces
  use gtv_interfaces, except_this=>gtg_charlen
  use gtv_tree
  use gtv_graphic
  !---------------------------------------------------------------------
  ! @ public
  !   Returns the length of a character string according to current
  ! font attributes. No action on the plot. See also GTCHAR
  !---------------------------------------------------------------------
  integer(kind=4),  intent(in)  :: nchars   ! Number of characters
  character(len=*), intent(in)  :: string   ! Character string
  real(kind=4),     intent(in)  :: size     ! Character size (plot page units)
  real(kind=4),     intent(out) :: slength  ! String length (plot page units)
  integer(kind=4),  intent(in)  :: ifont    ! Font type
  ! Local
  integer(kind=4) :: kfont
  !
  if (.not.awake)  return
  !
  if (nchars.le.0) then
    slength = 0.
    return
  endif
  !
  ! Get the current font KFONT: 0 for Simplex quality, 1 for Duplex.
  ! Invoke VSTRIN to get the actual length.
  kfont = max(ifont,0)
  call vstrin(nchars,string,.false.,slength,0.,0.,0.,kfont,size,  &
    .false.,gtpolyl,dummy_clip)
  !
end subroutine gtg_charlen
!
subroutine dummy_clip(nq,xq,yq)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private-mandatory (because symbol is used elsewhere)
  ! Unused subroutine sent to 'vstrin' (doclip = .false.)
  !---------------------------------------------------------------------
  integer(kind=size_length), intent(in) :: nq     ! Number of points
  real(kind=4),              intent(in) :: xq(*)  ! Plot X coordinates
  real(kind=4),              intent(in) :: yq(*)  ! Plot Y coordinates
end subroutine dummy_clip
