# include <kapa_internal.h>
# define NROTCHARS 256

/* writes commands to print string at location and angle using
   currently set font and size */
void PSRotText (FILE *f, int x, int y, char *string, int pos, double angle) {

  char *segment, basename[64], *currentname;
  int i, N, code;
  int dX, dY, Xoff, Yoff, X, Y, Nseg, NSEG, YoffBase;
  double cs, sn, fscale, currentscale;
  int basesize, currentsize;
  RotFont *currentfont;
  
  currentname = GetRotFont (&currentsize);
  currentfont = GetRotFontData (&currentscale);
  strcpy (basename, currentname);
  basesize = currentsize;

  /* strip off leading WHITESPACE */
  stripwhite (string);
  if (*string == 0) return;
  
  /* compute string length */
  /* PS fonts are somewhat different scales from bitmap font equivalents */
  fscale = 1.0;
  if (!strcmp (currentname, "times")) fscale = 1.07;
  if (!strcmp (currentname, "courier")) fscale = 1.5;
  if (!strcmp (currentname, "helvetica")) fscale = 0.9;
  if (!strcmp (currentname, "symbol")) fscale = 1.2;
  dX = fscale*RotStrlen (string);
  dY = currentfont[65].ascent;
  
  /* apply appropriate offset */
  Xoff = Yoff = 0;
  switch (pos) {
  case 0: Xoff =     -dX; Yoff = -dY; break;
  case 1: Xoff = -0.5*dX; Yoff = -dY; break;
  case 2: Xoff =       0; Yoff = -dY; break;
  case 3: Xoff =     -dX; Yoff = -0.5*dY; break;
  case 4: Xoff = -0.5*dX; Yoff = -0.5*dY; break;
  case 5: Xoff =       0; Yoff = -0.5*dY; break;
  case 6: Xoff =     -dX; Yoff = 0; break;
  case 7: Xoff = -0.5*dX; Yoff = 0; break;
  case 8: Xoff =       0; Yoff = 0; break;
  }
  cs = cos(angle*RAD_DEG);
  sn = sin(angle*RAD_DEG);
  X = x + Xoff*cs + Yoff*sn;
  Y = y - Xoff*sn + Yoff*cs;

  PSSetFont (f, currentname, currentsize);
  fprintf (f, "gsave\n");
  fprintf (f, " %d %d moveto %f rotate\n", X, Y, -angle);

  Nseg = 0;
  NSEG = strlen(string) + 2;
  ALLOCATE (segment, char, NSEG);
  bzero (segment, NSEG);

  code = FALSE;
  YoffBase = 0;
  /* accumulate string segments with common state */
  for (i = 0; i < strlen (string); i++) {
    N = (int)(string[i]);
    if ((N < 0) || (N >= NROTCHARS)) continue;

    /* check for special characters */
    if (!code) {
      /* superscript character (^) */
      if (N == 94) {
	PSDumpRotSegment (f, segment, &Nseg);
	SetRotFont (currentname, (int)(0.8*currentsize));
	currentfont = GetRotFontData (&currentscale);
	Yoff = 0.75*currentscale*dY;
	fprintf (f, "0 %d rmoveto\n", Yoff);
	YoffBase += Yoff;
	PSSetFont (f, currentname, currentsize);
	continue;
      }
      /* subscript character (_) */
      if (N == 95) { 
	PSDumpRotSegment (f, segment, &Nseg);
	SetRotFont (currentname, (int)(0.8*currentsize));
	currentfont = GetRotFontData (&currentscale);
	Yoff = -0.5*currentscale*dY;
	fprintf (f, "0 %d rmoveto\n", Yoff);
	YoffBase += Yoff;
	PSSetFont (f, currentname, currentsize);
	continue;
      }
      /* end super/sub script (|) */
      if (N == 124) {
	PSDumpRotSegment (f, segment, &Nseg);
	SetRotFont (currentname, basesize);
	currentfont = GetRotFontData (&currentscale);
	fprintf (f, "0 %d rmoveto\n", -YoffBase);
	YoffBase = 0;
	PSSetFont (f, currentname, currentsize);
	continue;
      }
      /* escape char (\) */
      if (N == 92) {
	code = TRUE;
	continue;
      } 
      /* begin paren (insert \) */
      if (N == 40) {
	code = FALSE;
	segment[Nseg] = 92;
	Nseg ++;
	CHECK_REALLOCATE (segment, char, NSEG, Nseg, 64);
      }
      /* end paren (insert \) */
      if (N == 41) {
	code = FALSE;
	segment[Nseg] = 92;
	Nseg ++;
	CHECK_REALLOCATE (segment, char, NSEG, Nseg, 64);
      }
      /* font change character (&) */
      if (N == 38) {
	PSDumpRotSegment (f, segment, &Nseg);
	if (string[i+1] == 'h') {
	  SetRotFont ("helvetica", currentsize);
	  currentfont = GetRotFontData (&currentscale);
	  PSSetFont (f, currentname, currentsize);
	}
	if (string[i+1] == 't') {
	  SetRotFont ("times", currentsize);
	  currentfont = GetRotFontData (&currentscale);
	  PSSetFont (f, currentname, currentsize);
	}
	if (string[i+1] == 'c') {
	  SetRotFont ("courier", currentsize);
	  currentfont = GetRotFontData (&currentscale);
	  PSSetFont (f, currentname, currentsize);
	}
	if (string[i+1] == 's') {
	  SetRotFont ("symbol", currentsize);
	  currentfont = GetRotFontData (&currentscale);
	  PSSetFont (f, currentname, currentsize);
	}
	i++;
	continue;
      }
    }
    code = FALSE;
    segment[Nseg] = N;
    Nseg ++;
    CHECK_REALLOCATE (segment, char, NSEG, Nseg, 64);
  }
  PSDumpRotSegment (f, segment, &Nseg);
  fprintf (f, "stroke grestore\n");
  free (segment);
  SetRotFont (basename, basesize);
}

void PSDumpRotSegment (FILE *f, char *segment, int *Nseg) {
  segment[*Nseg] = 0;
  fprintf (f, "(%s) show\n", segment);
  bzero (segment, *Nseg);
  *Nseg = 0;
}

void PSSetFont (FILE *f, char *name, int size) {
  if (!strcmp (name, "times")) 
    fprintf (f, "/Times-Roman findfont %d scalefont setfont\n", size);
  if (!strcmp (name, "helvetica")) 
    fprintf (f, "/Helvetica findfont %d scalefont setfont\n", size);
  if (!strcmp (name, "courier")) 
    fprintf (f, "/Courier findfont %d scalefont setfont\n", size);
  if (!strcmp (name, "symbol")) 
    fprintf (f, "/Symbol findfont %d scalefont setfont\n", size);
}



  /* test cross hair
  fprintf (f, "%d %d %d %d L\n", x-10, y, x+10, y);
  fprintf (f, "%d %d %d %d L\n", x, y-10, x, y+10);
  */
