/* PAUL MURRELL
   This is from the GNU plotutils libplot-2.3 distribution
   Several modifications have been made to use the R graphics engine
   for output.
   All references to HAVE_PROTOS removed
   All references to "plotter" replaced with references to "GEDevDesc"
*/

/* This file contains the internal method _falabel_hershey(), which plots a
   label using Hershey fonts.  Each character in a Hershey font is a
   sequence of pen motions, so this function simply calls fmoverel() and
   fcontrel() to `stroke' each character in the argument string.

   The width of the string in user units is returned.  The internal method
   _flabelwidth_hershey() is similar, but does not actually plot the label.
*/

/* PAUL MURRELL
   sys-defines.h not used
*/
/* #include "sys-defines.h" */

/* PAUL MURRELL
   extern.h renamed g_extern.h
*/
#include "g_extern.h"
#include "g_control.h"
#include "g_her_metr.h"

/* Shearing factor for oblique fonts, new_x = x + SHEAR * y  */

#define SHEAR (2.0/7.0)

/* Relative size of subscripts/superscripts (i.e. `indexical' size) */

#define SCRIPTSIZE (0.6)

/* Positioning of subscripts/superscripts */

#define SUBSCRIPT_DX 0.0
#define SUBSCRIPT_DY (-0.25)
#define SUPERSCRIPT_DX 0.0
#define SUPERSCRIPT_DY 0.4

/* Positioning of accents (in Hershey units).  UP_SHIFT is amount by which
   accents are raised when placed over upper-case letters.  RIGHT_SHIFT is
   applied as well, if the upper-case letter is italic. */

#define ACCENT_UP_SHIFT 7.0
#define ACCENT_RIGHT_SHIFT 2.0

/* Relative size of small Japanese Kana */
#define SMALL_KANA_SIZE 0.725

/* Hershey glyph arrays */

#define OCCIDENTAL 0
#define ORIENTAL 1

/* Location of first Kana in the occidental glyph arrays.  (Kana, unlike
   Kanji, are placed in the occidental array, at the very end.) */
#define BEGINNING_OF_KANA 4195

/* PAUL MURRELL
   Structure to contain vfont current position
*/
typedef struct {
    double currX;
    double currY;
    double angle;
} vfontContext;

/* forward references */
static bool _composite_char (unsigned char *composite,
			     unsigned char *character,
			     unsigned char *accent);
static void _draw_stroke (vfontContext *vc, const pGEcontext gc,
			  pGEDevDesc dd,
			  bool pendown, double deltax, double deltay);
static double _label_width_hershey (const pGEcontext gc, pGEDevDesc dd,
				    const unsigned short *label);
static void _draw_hershey_string (vfontContext *vc, const pGEcontext gc,
				  pGEDevDesc dd,
				  const unsigned short *string);

/* _draw_hershey_stroke() draws a stroke, taking into account the
   transformation from Hershey units to user units, and also the current
   transformation matrix (as set by the user).  _draw_stroke is similar,
   but takes arguments in user units. */
/* PAUL MURRELL
   _draw_stroke now takes arguments in INCHES;  it needs to work in
   an absolute coordinate system because it does the rotation
*/

static
void _draw_hershey_stroke (vfontContext *vc, const pGEcontext gc, pGEDevDesc dd,
			   bool pendown, double deltax, double deltay)
{
    _draw_stroke(vc, gc, dd, pendown,
		 fromDeviceWidth(HERSHEY_X_UNITS_TO_USER_UNITS (deltax),
				 GE_INCHES, dd),
		 fromDeviceHeight(HERSHEY_Y_UNITS_TO_USER_UNITS (deltay),
				  GE_INCHES, dd));
}

static void moverel(double dx, double dy, vfontContext *vc) {
    vc->currX += dx;
    vc->currY += dy;
}

static void linerel(double dx, double dy,
		    vfontContext *vc, const pGEcontext gc,
		    pGEDevDesc dd) {
    GELine(toDeviceX(vc->currX, GE_INCHES, dd),
	   toDeviceY(vc->currY, GE_INCHES, dd),
	   toDeviceX(vc->currX+dx, GE_INCHES, dd),
	   toDeviceY(vc->currY+dy, GE_INCHES, dd),
	   gc, dd);
    vc->currX += dx;
    vc->currY += dy;
}

/* e.g. for some Windows headers */
#ifndef M_PI
#define M_PI		3.141592653589793238462643383279502884197169399375
#endif

static void _draw_stroke (vfontContext *vc, const pGEcontext gc, pGEDevDesc dd,
			  bool pendown, double deltax, double deltay)
{
  double dx, dy;
  double theta;

  theta = M_PI * vc->angle / 180.0;

  dx = cos(theta) * deltax - sin(theta) * deltay;
  dy = sin(theta) * deltax + cos(theta) * deltay;

  if (pendown)
      linerel(dx, dy, vc, gc, dd);
  else
      moverel(dx, dy, vc);
}

/* PAUL MURRELL
   Renamed from _g_flabelwidth_hershey to GVStrWidth
   ... and added unit argument
   ... and rearranged order of arguments
*/

/* this is the version of the flabelwidth() method that is specific to the
   case when the current Plotter font is a Hershey font; called in
   g_flabelwidth () .
   
   Argument 'enc' is ignored: these are in their own encoding.
*/
attribute_hidden
double R_GE_VStrWidth (const char *s, cetype_t enc, 
		       const pGEcontext gc, pGEDevDesc dd)
{
  double label_width;
  unsigned short *codestring;

  /* PAUL MURRELL
     _controlify using R_alloc instead of xmalloc so need to do
     vmaxget() ... vmaxset() instead of free()
  */

  const void *vmax = vmaxget();

  /* convert string to a codestring, including annotations */
  codestring = _controlify (dd, (const unsigned char *) s,
			    gc->fontfamily[7] - 1, gc->fontface);

  label_width = _label_width_hershey (gc, dd, codestring);

  vmaxset(vmax);
  /*  free (codestring); */

  return label_width;
}

/* PAUL MURRELL
   Added _label_height_hershey and GVStrHeight function
*/

static double _label_height_hershey (const pGEcontext gc,
				     pGEDevDesc dd,
				     const unsigned short *label)
{
    return( HERSHEY_Y_UNITS_TO_USER_UNITS(HERSHEY_LARGE_CAPHEIGHT) );
}

attribute_hidden
double R_GE_VStrHeight (const char *s, cetype_t enc, 
			const pGEcontext gc, pGEDevDesc dd)
{
  double label_height;
  unsigned short *codestring;

  const void *vmax = vmaxget();

  /* convert string to a codestring, including annotations */
  codestring = _controlify (dd, (const unsigned char *) s,
			    gc->fontfamily[7] - 1, gc->fontface);

  label_height = _label_height_hershey (gc, dd, codestring);

  vmaxset(vmax);

  return label_height;
}

/* PAUL MURRELL
   This guy is the entry point to the GNU code
   Renamed from _g_falabel_hershey to GVText
   Reordered arguments
   Added x, y, rotation, and font specification arguments
   Re-typed x/y_justify from int to double
   Re-typed s from "unsigned char *" to char *
   Changed return value from double to void
*/

/* this is the version of the falabel() method that is specific
   to the case when the current Plotter font is a Hershey font */
attribute_hidden
void R_GE_VText (double x, double y, const char *s, cetype_t enc,
		 double x_justify, double y_justify, double rotation,
		 const pGEcontext gc, pGEDevDesc dd)
{
  unsigned short *codestring;
  double label_width, label_height;
  double x_offset, y_offset;
/*  double x_displacement; */

  /* PAUL MURRELL
     _controlify using R_alloc instead of xmalloc so need to do
     vmaxget() ... vmaxset() instead of free()
  */
  const void *vmax = vmaxget();

  /* PAUL MURRELL
     initialise the local currX and currY
     work in INCHES because that is what moverel and linerel work in
  */
  vfontContext vc;
  vc.currX = fromDeviceX(x, GE_INCHES, dd);
  vc.currY = fromDeviceY(y, GE_INCHES, dd);
  vc.angle = rotation;

  /* PAUL MURRELL
   * Override gc settings for lty and lwd
   */
  gc->lty = LTY_SOLID;
  gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_STROKE_WIDTH);
  gc->lend = GE_ROUND_CAP;
  gc->ljoin = GE_ROUND_JOIN;

  /* convert string to a codestring, including annotations */
  codestring = _controlify (dd, (const unsigned char *)s,
			    gc->fontfamily[7] - 1, gc->fontface);


  /* PAUL MURRELL
     Justification changed from char (e.g., 'l', 'c', 'r') to
     double (e.g., 0, .5, 1)
     Also added handling of NaN x_justify and y_justify
     ... and replaced HERSHEY_Y_UNITS_TO_USER_UNITS(HERSHEY_HEIGHT)
     with HERSHEY_Y_UNITS_TO_USER_UNITS(HERSHEY_LARGE_CAPHEIGHT)
     ... and replaced ((double)HERSHEY_ASCENT / (double)HERSHEY_HEIGHT)
     with 1.0
  */

  /* dimensions of the string, in user units */
  label_width = _label_width_hershey (gc, dd, codestring);
  label_height = _label_height_hershey(gc, dd, codestring);

  if (!R_FINITE(x_justify))
      x_justify = 0.5;
  if (!R_FINITE(y_justify))
      y_justify = 0.5;

  x_offset = 0 - x_justify;
  /* x_displacement = 1 - 2 * x_justify; */

  y_offset = 0 - y_justify * 1.0;

  /* save relevant drawing attributes, and restore them later */

  {
/*
    char *old_line_mode, *old_cap_mode, *old_join_mode;
    int old_fill_type;
    double oldposx, oldposy;
    bool old_dash_array_in_effect;

    old_line_mode = (char *)_plot_xmalloc (strlen (_plotter->drawstate->line_mode) + 1);
    old_cap_mode = (char *)_plot_xmalloc (strlen (_plotter->drawstate->cap_mode) + 1);
    old_join_mode = (char *)_plot_xmalloc (strlen (_plotter->drawstate->join_mode) + 1);
    oldposx = (_plotter->drawstate->pos).x;
    oldposy = (_plotter->drawstate->pos).y;

    strcpy (old_line_mode, _plotter->drawstate->line_mode);
    strcpy (old_cap_mode, _plotter->drawstate->cap_mode);
    strcpy (old_join_mode, _plotter->drawstate->join_mode);
    old_fill_type = _plotter->drawstate->fill_type;
    old_dash_array_in_effect = _plotter->drawstate->dash_array_in_effect;
*/
    /* Our choices for rendering: solid lines, rounded capitals and joins,
       a line width equal to slightly more than 1 Hershey unit, and
       transparent filling. */
/*
    _plotter->linemod (R___(_plotter) "solid");
    _plotter->capmod (R___(_plotter) "round");
    _plotter->joinmod (R___(_plotter) "round");
    _plotter->filltype (R___(_plotter) 0);
*/

    /* move to take horizontal and vertical justification into account;
       arguments here are in user units */
      /* PAUL MURRELL
	 arguments now in INCHES because _draw_stroke does rotation
	 so it needs to use absolute coordinates
      */
      _draw_stroke (&vc, gc, dd,
		    false,
		    fromDeviceWidth(x_offset * label_width, GE_INCHES, dd),
		    fromDeviceHeight(y_offset * label_height, GE_INCHES, dd));
    /* call stroker on the sequence of strokes obtained from each char (the
       stroker may manipulate the line width) */
      /* _draw_hershey_stroke (dd, true, 0, HERSHEY_EM);     */
      _draw_hershey_string (&vc, gc, dd, codestring);

    /* Restore original values of relevant drawing attributes, free
       storage.  endpath() will be invoked in here automatically, flushing
       the created polyline object comprising the stroked text. */
/*
    _plotter->linemod (R___(_plotter) old_line_mode);
    _plotter->capmod (R___(_plotter) old_cap_mode);
    _plotter->joinmod (R___(_plotter) old_join_mode);
    _plotter->filltype (R___(_plotter) old_fill_type);
    _plotter->drawstate->dash_array_in_effect = old_dash_array_in_effect;

    free (old_line_mode);
    free (old_cap_mode);
    free (old_join_mode);
*/
    /* return to original position */
      /*    _plotter->fmove (R___(_plotter) oldposx, oldposy); */
  }

  /* amount by which to shift after printing label (user units) */
/*
  postdx = x_displacement * label_width;
  theta = M_PI * rotation / 180.0;
  dx = cos (theta) * postdx
    - sin (theta) * 0;
  dy = sin (theta) * postdx
    + cos (theta) * 0;

  moverel(dx, dy);
*/

  vmaxset(vmax);
  /*  free (codestring); */

  /* PAUL MURRELL
     No return value
  */
  /* return label_width;		 user units */
}

/* In addition to scaling the character sizes and the `width', we perform
   the following (dx, dy):

   enter subscript	(dx, dy) = (-1/9, -1/2) * width
   exit subscript	(dx, dy) = (+1/6, +1/2) * width

   enter superscript	(dx, dy) = (-1/9, +1/2) * width
   exit superscript	(dx, dy) = (+1/6, -1/2) * width

   For clarity here, `width' refers to the width _before_ it is
   multiplied by a factor 2/3.

   [N.B. In Bob Beach's original UGS character stroke generator,
   the +1/6's here were +2/9 instead.  Better?] */

/* _label_width_hershey() computes the width (total delta x) of a
   controlified character string to be rendered in a vector font, in user
   units */
static double _label_width_hershey (const pGEcontext gc, pGEDevDesc dd,
				    const unsigned short *label)
{
  const unsigned short *ptr = label;
  unsigned short c;
  double charsize = 1.0;	/* relative char size, 1.0 means full size */
  double saved_charsize = 1.0;
  double width = 0.0;		/* label width */
  double saved_width = 0.0;

  /* loop through unsigned shorts in label */
  while ((c = (*ptr)) != (unsigned short)'\0')
    {
      int glyphnum;		/* glyph in Hershey array */
      const unsigned char *glyph;

      if (c & RAW_HERSHEY_GLYPH)
	/* glyph was spec'd via an escape, not as a char in a font */
	{
	  glyphnum = c & GLYPH_SPEC;
	  glyph = (const unsigned char *)(_occidental_hershey_glyphs[glyphnum]);

	  if (*glyph != '\0')	/* nonempty glyph */
	    /* 1st two chars are bounds */
	    width += charsize * ((int)glyph[1] - (int)glyph[0]);
	}
      else if (c & RAW_ORIENTAL_HERSHEY_GLYPH)
	/* glyph was spec'd via an escape, not as a char in a font */
	{
	  glyphnum = c & GLYPH_SPEC;
	  glyph = (const unsigned char *)_oriental_hershey_glyphs[glyphnum];

	  if (*glyph != '\0')	/* nonempty glyph */
	    /* 1st two chars are bounds */
	    width += charsize * ((int)glyph[1] - (int)glyph[0]);
	}
      else if (c & CONTROL_CODE)	/* parse control code */
	{
	  switch (c & ~CONTROL_CODE)
	    {
	    case C_BEGIN_SUBSCRIPT:
	    case C_BEGIN_SUPERSCRIPT :
	      charsize *= SCRIPTSIZE;
	      break;

	    case C_END_SUBSCRIPT:
	    case C_END_SUPERSCRIPT:
	      charsize /= SCRIPTSIZE;
	      break;

	    case C_PUSH_LOCATION:
	      saved_width = width;
	      saved_charsize = charsize;
	      break;

	    case C_POP_LOCATION:
	      width = saved_width;
	      charsize = saved_charsize;
	      break;

	    case C_RIGHT_ONE_EM:
	      width += charsize * HERSHEY_EM;
	      break;

	    case C_RIGHT_HALF_EM:
	      width += charsize * HERSHEY_EM / 2.0;
	      break;

	    case C_RIGHT_QUARTER_EM:
	      width += charsize * HERSHEY_EM / 4.0;
	      break;

	    case C_RIGHT_SIXTH_EM:
	      width += charsize * HERSHEY_EM / 6.0;
	      break;

	    case C_RIGHT_EIGHTH_EM:
	      width += charsize * HERSHEY_EM / 8.0;
	      break;

	    case C_RIGHT_TWELFTH_EM:
	      width += charsize * HERSHEY_EM / 12.0;
	      break;

	    case C_LEFT_ONE_EM:
	      width -= charsize * HERSHEY_EM;
	      break;

	    case C_LEFT_HALF_EM:
	      width -= charsize * HERSHEY_EM / 2.0;
	      break;

	    case C_LEFT_QUARTER_EM:
	      width -= charsize * HERSHEY_EM / 4.0;
	      break;

	    case C_LEFT_SIXTH_EM:
	      width -= charsize * HERSHEY_EM / 6.0;
	      break;

	    case C_LEFT_EIGHTH_EM:
	      width -= charsize * HERSHEY_EM / 8.0;
	      break;

	    case C_LEFT_TWELFTH_EM:
	      width -= charsize * HERSHEY_EM / 12.0;
	      break;

	      /* unrecognized control code */
	    default:
	      break;
	    }
	}
      else			/* yow, an actual character */
	{
	  int raw_fontnum;

	  /* compute index of font, in table in g_fontdb.c */
	  raw_fontnum = (c >> FONT_SHIFT) & ONE_BYTE;

	  c &= ~FONT_SPEC;	/* extract character proper */
	  glyphnum = (_hershey_font_info[raw_fontnum].chars)[c];

	  /* could be a pseudo glyph number, e.g. an indication that
	     character is composite */
	  if (glyphnum == ACC0 || glyphnum == ACC1 || glyphnum == ACC2)
	    {
		unsigned char composite, character = '\0' /* -Wall */, accent;

	      /* if so, use 1st element of composite character */
	      composite = (unsigned char)c;
	      if (_composite_char (&composite, &character, &accent))
		glyphnum = (_hershey_font_info[raw_fontnum].chars)[character];
	      else
		glyphnum = UNDE; /* hope this won't happen */
	    }

	  /* could also be a glyph number displaced by KS, to indicate
	     that this is a small kana */
	  if (glyphnum & KS)
	    glyphnum -= KS;

	  glyph = (const unsigned char *)(_occidental_hershey_glyphs[glyphnum]);
	  if (*glyph != '\0')	/* nonempty glyph */
	    /* 1st two chars are bounds */
	    width += charsize * ((int)glyph[1] - (int)glyph[0]);
	}

      ptr++;			/* bump pointer in string */
    }

  return HERSHEY_X_UNITS_TO_USER_UNITS (width);
}

/* _draw_hershey_penup_stroke() draws a penup stroke, along a vector
   specified in Hershey units.  Size scaling and obliquing (true/false) are
   specified.  This is used for repositioning during rendering of
   composite (accented) characters. */
static
void _draw_hershey_penup_stroke(vfontContext *vc, const pGEcontext gc,
				pGEDevDesc dd,
				double dx, double dy,
				double charsize, bool oblique)
{
  double shear;

  shear = oblique ? (SHEAR) : 0.0;
  _draw_hershey_stroke (vc, gc, dd,
			false,	/* pen up */
			charsize * (dx + shear * dy),
			charsize * dy);
}

/* _draw_hershey_glyph() invokes move() and cont() to draw a raw Hershey
   glyph, specified by index in the occidental or oriental glyph arrays.
   Size scaling and obliquing (true/false) are specified. */
static
void _draw_hershey_glyph (vfontContext *vc, const pGEcontext gc, pGEDevDesc dd,
			  int glyphnum,
			  double charsize, int type, bool oblique)
{
  double xcurr, ycurr;
  double xfinal, yfinal;
  bool pendown = false;
  const unsigned char *glyph;
  double dx, dy;
  double shear;

  shear = oblique ? (SHEAR) : 0.0;
  switch (type)
    {
    case OCCIDENTAL:
    default:
      glyph = (const unsigned char *)(_occidental_hershey_glyphs[glyphnum]);
      break;
    case ORIENTAL:
      glyph = (const unsigned char *)(_oriental_hershey_glyphs[glyphnum]);
      break;
    }

  if (*glyph != '\0')	/* nonempty glyph */
    {
      xcurr = charsize * (double)glyph[0];
      xfinal = charsize * (double)glyph[1];
      ycurr = yfinal = 0.0;
      glyph += 2;
      while (*glyph)
	{
	  int xnewint;

	  xnewint = (int)glyph[0];

	  if (xnewint == (int)' ')
	    pendown = false;
	  else
	    {
	      double xnew, ynew;

	      xnew = (double)charsize * xnewint;
	      ynew = (double)charsize
		* ((int)'R'
		   - ((int)glyph[1] + (double)HERSHEY_BASELINE));
	      dx = xnew - xcurr;
	      dy = ynew - ycurr;
	      _draw_hershey_stroke (vc, gc, dd,
				    pendown, dx + shear * dy, dy);
	      xcurr = xnew, ycurr = ynew;
	      pendown = true;
	    }

	  glyph +=2;	/* on to next pair */
	}

      /* final penup stroke, to end where we should */
      dx = xfinal - xcurr;
      dy = yfinal - ycurr;
      _draw_hershey_stroke (vc, gc, dd, false, dx + shear * dy, dy);
    }
}

/* _draw_hershey_string() strokes a string beginning at present location,
   which is taken to be on the string's baseline.  Besides invoking move()
   and cont(), it invokes linewidth(). */
static
void _draw_hershey_string (vfontContext *vc, const pGEcontext gc, pGEDevDesc dd,
			   const unsigned short *string)
{
  unsigned short c;
  const unsigned short *ptr = string;
  double charsize = 1.0;
  int line_width_type = 0;	/* 0,1,2 = unset,occidental,oriental */

  while ((c = (*ptr++)) != '\0')
    {
      /* Check for the four possibilities: (1) a Hershey glyph specified by
	 glyph number, (2) an oriental Hershey glyph specified by glyph
	 number, (3) a control code, and (4) an ordinary font character,
	 which will be mapped to a Hershey glyph by one of the tables in
	 g_fontdb.c. */

      if (c & RAW_HERSHEY_GLYPH)
	{
	  if (line_width_type != 1)
	    {
	      gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_STROKE_WIDTH);
	      line_width_type = 1;
	    }
	  _draw_hershey_glyph (vc, gc, dd,
			       c & GLYPH_SPEC, charsize, OCCIDENTAL, false);
	}

      else if (c & RAW_ORIENTAL_HERSHEY_GLYPH)
	{
	  if (line_width_type != 2)
	    {
	      gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_STROKE_WIDTH);
	      line_width_type = 2;
	    }
	  _draw_hershey_glyph (vc, gc, dd,
			       c & GLYPH_SPEC, charsize, ORIENTAL, false);
	}

      else if (c & CONTROL_CODE)
	switch (c & ~CONTROL_CODE) /* parse control codes */
	  {
	  case C_BEGIN_SUPERSCRIPT :
	    _draw_hershey_stroke (vc, gc, dd,
				  false,
				  SUPERSCRIPT_DX * charsize * HERSHEY_EM,
				  SUPERSCRIPT_DY * charsize * HERSHEY_EM);
	    charsize *= SCRIPTSIZE;
	    break;

	  case C_END_SUPERSCRIPT:
	    charsize /= SCRIPTSIZE;
	    _draw_hershey_stroke (vc, gc, dd,
				  false,
				  - SUPERSCRIPT_DX * charsize * HERSHEY_EM,
				  - SUPERSCRIPT_DY * charsize * HERSHEY_EM);
	    break;

	  case C_BEGIN_SUBSCRIPT:
	    _draw_hershey_stroke (vc, gc, dd,
				  false,
				  SUBSCRIPT_DX * charsize * HERSHEY_EM,
				  SUBSCRIPT_DY * charsize * HERSHEY_EM);
	    charsize *= SCRIPTSIZE;
	    break;

	  case C_END_SUBSCRIPT:
	    charsize /= SCRIPTSIZE;
	    _draw_hershey_stroke (vc, gc, dd,
				  false,
				  - SUBSCRIPT_DX * charsize * HERSHEY_EM,
				  - SUBSCRIPT_DY * charsize * HERSHEY_EM);
	    break;

	  case C_PUSH_LOCATION:
	      /* saved_charsize = charsize;
		 saved_position_x = _plotter->drawstate->pos.x;
		 saved_position_y = _plotter->drawstate->pos.y; */
	    break;

	  case C_POP_LOCATION:
	      /* charsize = saved_charsize;
		 _plotter->fmove (R___(_plotter)
		 saved_position_x, saved_position_y); */
	    break;

	  case C_RIGHT_ONE_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, charsize * HERSHEY_EM, 0.0);
	    break;

	  case C_RIGHT_HALF_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, charsize * HERSHEY_EM / 2.0, 0.0);
	    break;

	  case C_RIGHT_QUARTER_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, charsize * HERSHEY_EM / 4.0, 0.0);
	    break;

	  case C_RIGHT_SIXTH_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, charsize * HERSHEY_EM / 6.0, 0.0);
	    break;

	  case C_RIGHT_EIGHTH_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, charsize * HERSHEY_EM / 8.0, 0.0);
	    break;

	  case C_LEFT_ONE_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, - charsize * HERSHEY_EM, 0.0);
	    break;

	  case C_LEFT_HALF_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, - charsize * HERSHEY_EM / 2.0, 0.0);
	    break;

	  case C_LEFT_QUARTER_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, - charsize * HERSHEY_EM / 4.0, 0.0);
	    break;

	  case C_LEFT_SIXTH_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, - charsize * HERSHEY_EM / 6.0, 0.0);
	    break;

	  case C_LEFT_EIGHTH_EM:
	    _draw_hershey_stroke (vc, gc, dd,
				  false, - charsize * HERSHEY_EM / 8.0, 0.0);
	    break;

	    /* unrecognized control code, punt */
	  default:
	    break;
	  }

      else
	/* yow, an actual font character!  Several possibilities: could be
	   a composite (accented) character, could be a small Kana, or
	   could be a garden-variety character. */
	{
	  int raw_fontnum;
	  int glyphnum;		/* glyph in Hershey array */
	  int char_glyphnum, accent_glyphnum; /* for composite chars */
	  int char_width, accent_width; /* for composite chars */
	  const unsigned char *char_glyph, *accent_glyph;
	  unsigned char composite, character = '\0', accent = '\0' /* -Wall */;
	  bool oblique, small_kana = false;

	  /* compute index of font, in font table in g_fontdb.c */
	  raw_fontnum = (c >> FONT_SHIFT) & ONE_BYTE;
	  /* shear font?  (for HersheySans-Oblique, etc.) */
	  oblique = _hershey_font_info[raw_fontnum].obliquing;

	  c &= ~FONT_SPEC;	/* extract character proper */
	  glyphnum = (_hershey_font_info[raw_fontnum].chars)[c];

	  if (glyphnum & KS) /* a small kana? */
	    {
	      glyphnum -= KS;
	      small_kana = true;
	    }

	  switch (glyphnum)
	    {
	      /* special case: this is a composite (accented) character;
		 search font table in g_fontdb.c for it */
	    case ACC0:
	    case ACC1:
	    case ACC2:
	      composite = (unsigned char)c;
	      if (_composite_char (&composite, &character, &accent))
		{
		  char_glyphnum =
		    (_hershey_font_info[raw_fontnum].chars)[character];
		  accent_glyphnum =
		    (_hershey_font_info[raw_fontnum].chars)[accent];
		}
	      else
		{		/* hope this won't happen */
		  char_glyphnum = UNDE;
		  accent_glyphnum = 0;
		}
	      char_glyph =
		(const unsigned char *)_occidental_hershey_glyphs[char_glyphnum];
	      accent_glyph =
		(const unsigned char *)_occidental_hershey_glyphs[accent_glyphnum];

	      if (*char_glyph != '\0') /* nonempty glyph */
		/* 1st two chars are bounds, in Hershey units */
		char_width = (int)char_glyph[1] - (int)char_glyph[0];
	      else
		char_width = 0;

	      if (*accent_glyph != '\0') /* nonempty glyph */
		/* 1st two chars are bounds, in Hershey units */
		accent_width = (int)accent_glyph[1] - (int)accent_glyph[0];
	      else
		accent_width = 0;

	      /* draw the character */
	      if (line_width_type != 1)
	      {
		  gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_STROKE_WIDTH);
		  line_width_type = 1;
		}
	      _draw_hershey_glyph (vc, gc, dd,
				   char_glyphnum, charsize,
				   OCCIDENTAL, oblique);
	      /* back up to draw accent */
	      _draw_hershey_penup_stroke (vc, gc, dd,
					  -0.5 * (double)char_width
					  -0.5 * (double)accent_width,
					  0.0, charsize, oblique);

	      /* repositioning for uppercase and uppercase italic */
	      if (glyphnum == ACC1)
		_draw_hershey_penup_stroke (vc, gc, dd,
					    0.0,
					    (double)(ACCENT_UP_SHIFT),
					    charsize, oblique);
	      else if (glyphnum == ACC2)
		_draw_hershey_penup_stroke (vc, gc, dd,
					    (double)(ACCENT_RIGHT_SHIFT),
					    (double)(ACCENT_UP_SHIFT),
					    charsize, oblique);

	      /* draw the accent */
	      _draw_hershey_glyph (vc, gc, dd,
				   accent_glyphnum, charsize,
				   OCCIDENTAL, oblique);

	      /* undo special repositioning if any */
	      if (glyphnum == ACC1)
		_draw_hershey_penup_stroke (vc, gc, dd,
					    0.0,
					    -(double)(ACCENT_UP_SHIFT),
					    charsize, oblique);
	      else if (glyphnum == ACC2)
		_draw_hershey_penup_stroke (vc, gc, dd,
					    -(double)(ACCENT_RIGHT_SHIFT),
					    -(double)(ACCENT_UP_SHIFT),
					    charsize, oblique);

	      /* move forward, to end composite char where we should */
	      _draw_hershey_penup_stroke (vc, gc, dd,
					  0.5 * (double)char_width
					  -0.5 * (double)accent_width,
					  0.0, charsize, oblique);
	      break;

	      /* not a composite (accented) character; just an ordinary
		 glyph from occidental+Kana array (could be a Kana, in
		 particular, could be a small Kana) */
	    default:
	      if (small_kana)
		{
		  int kana_width;
		  const unsigned char *kana_glyph;
		  double shift = 0.5 * (1.0 - (SMALL_KANA_SIZE));

		  kana_glyph =
		    (const unsigned char *)_occidental_hershey_glyphs[glyphnum];
		  kana_width = (int)kana_glyph[1] - (int)kana_glyph[0];

		  /* draw small Kana, preceded and followed by a penup
		     stroke in order to traverse the full width of an
		     ordinary Kana */
		  _draw_hershey_penup_stroke (vc, gc, dd,
					      shift * (double)kana_width,
					      0.0, charsize, oblique);
		  if (line_width_type != 2)
		    {
			gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_STROKE_WIDTH);
		      line_width_type = 2;
		    }
		  _draw_hershey_glyph (vc, gc, dd,
				       glyphnum,
				       (SMALL_KANA_SIZE) * charsize,
				       OCCIDENTAL, oblique);
		  _draw_hershey_penup_stroke (vc, gc, dd,
					      shift * (double)kana_width,
					      0.0, charsize, oblique);
		}
	      else
		/* whew! just an ordinary glyph from the occidental array
		   (could be a Kana however, since they're confusingly
		   placed in that array, at the end) */
		{
		  if (glyphnum >= BEGINNING_OF_KANA)
		    {
		      if (line_width_type != 2)
			{
			gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_ORIENTAL_STROKE_WIDTH);
			  line_width_type = 2;
			}
		    }
		  else
		      if (line_width_type != 1)
			{
			gc->lwd = HERSHEY_LINE_WIDTH_TO_LWD (HERSHEY_STROKE_WIDTH);
			  line_width_type = 1;
			}
		_draw_hershey_glyph (vc, gc, dd,
				     glyphnum, charsize,
				     OCCIDENTAL, oblique);
		}
	      break;
	    } /* end of case statement that switches based on glyphnum */

	} /* end of font character case */

    } /* end of loop through unsigned shorts in the codestring */

  return;
}

/* retrieve the two elements of a composite character from the table in
   g_fontdb.c */
static bool _composite_char (unsigned char *composite,
			     unsigned char *character,
			     unsigned char *accent)
{
  const struct plHersheyAccentedCharInfoStruct *compchar = _hershey_accented_char_info;
  bool found = false;
  unsigned char given = *composite;

  while (compchar->composite)
    {
      if (compchar->composite == given)
	{
	  found = true;
	  /* return char and accent via pointers */
	  *character = compchar->character;
	  *accent = compchar->accent;
	}
      compchar++;
    }

  return found;
}

