Description: Apply several updates and fixes to T1lib
 Incorporation of all patches and updates to T1lib as of Debian revision
 5.1.2-4 (2014-01-20), including fixes for CVE-2010-2642, CVE-2011-1552,
 -1553, and -1554.  Subsequent fixes also merged.
Origin: vendor, http://snapshot.debian.org/archive/debian/20140121T035726Z/pool/main/t/t1lib/t1lib_5.1.2-4.diff.gz
Forwarded: not-needed
Last-Update: 2024-07-06
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: grace/T1lib/t1lib/.dependencies
===================================================================
--- grace.orig/T1lib/t1lib/.dependencies
+++ grace/T1lib/t1lib/.dependencies
@@ -1,33 +1,34 @@
-parseAFM.lo: parseAFM.c parseAFM.h
+parseAFM.lo: parseAFM.c parseAFM.h t1base.h t1misc.h
 t1aaset.lo: t1aaset.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h t1types.h \
- t1extern.h t1misc.h t1aaset.h t1set.h t1load.h t1finfo.h t1base.h \
- t1outline.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1aaset.h \
+ t1set.h t1load.h t1finfo.h t1base.h t1outline.h
 t1afmtool.lo: t1afmtool.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h \
- ../type1/blues.h t1types.h t1extern.h t1misc.h t1finfo.h t1base.h \
- t1set.h t1load.h t1afmtool.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h ../type1/blues.h t1types.h sysconf.h t1extern.h \
+ t1misc.h t1finfo.h t1base.h t1set.h t1load.h t1afmtool.h
 t1base.lo: t1base.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h sysconf.h \
- t1base.h t1types.h t1global.h t1misc.h t1env.h t1delete.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h sysconf.h t1base.h t1types.h t1global.h t1misc.h \
+ t1env.h t1delete.h
 t1delete.lo: t1delete.c ../type1/types.h parseAFM.h ../type1/objects.h \
  ../type1/spaces.h ../type1/util.h ../type1/fontfcn.h t1types.h \
- t1extern.h t1misc.h t1delete.h t1load.h t1finfo.h t1base.h
+ sysconf.h t1extern.h t1misc.h t1delete.h t1load.h t1finfo.h t1base.h
 t1enc.lo: t1enc.c ../type1/ffilest.h ../type1/types.h ../type1/Xstuff.h \
  ../type1/fontmisc.h ../type1/fontstruct.h ../type1/font.h \
  ../type1/fsmasks.h ../type1/fontfile.h ../type1/fontxlfd.h parseAFM.h \
  ../type1/objects.h ../type1/spaces.h ../type1/util.h \
- ../type1/fontfcn.h ../type1/regions.h t1types.h t1extern.h t1misc.h \
- t1enc.h t1env.h t1base.h t1finfo.h
+ ../type1/fontfcn.h ../type1/paths.h ../type1/regions.h t1types.h \
+ sysconf.h t1extern.h t1misc.h t1enc.h t1env.h t1base.h t1finfo.h
 t1env.lo: t1env.c ../type1/types.h parseAFM.h ../type1/objects.h \
  ../type1/spaces.h ../type1/util.h ../type1/fontfcn.h \
  ../type1/fontmisc.h sysconf.h t1types.h t1extern.h t1misc.h t1env.h \
@@ -36,41 +37,44 @@ t1finfo.lo: t1finfo.c ../type1/ffilest.h
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h t1types.h \
- t1extern.h t1misc.h t1finfo.h t1base.h t1set.h t1load.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1finfo.h \
+ t1base.h t1set.h t1load.h
 t1load.lo: t1load.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/blues.h \
- ../type1/regions.h t1types.h t1extern.h t1misc.h t1load.h t1env.h \
- t1set.h t1base.h t1finfo.h t1afmtool.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/blues.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1load.h \
+ t1env.h t1set.h t1base.h t1finfo.h t1afmtool.h
 t1outline.lo: t1outline.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h \
- ../type1/paths.h t1types.h t1extern.h t1misc.h t1set.h t1load.h \
- t1finfo.h t1base.h t1outline.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1set.h \
+ t1load.h t1finfo.h t1base.h t1outline.h
 t1set.lo: t1set.c ../type1/ffilest.h ../type1/types.h ../type1/Xstuff.h \
  ../type1/fontmisc.h ../type1/fontstruct.h ../type1/font.h \
  ../type1/fsmasks.h ../type1/fontfile.h ../type1/fontxlfd.h parseAFM.h \
  ../type1/objects.h ../type1/spaces.h ../type1/util.h \
- ../type1/fontfcn.h ../type1/regions.h t1types.h t1extern.h t1misc.h \
- t1set.h t1load.h t1finfo.h t1base.h
+ ../type1/fontfcn.h ../type1/paths.h ../type1/regions.h t1types.h \
+ sysconf.h t1extern.h t1misc.h t1set.h t1load.h t1finfo.h t1base.h
 t1subset.lo: t1subset.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h t1types.h \
- t1extern.h t1misc.h t1finfo.h t1base.h t1subset.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1finfo.h \
+ t1base.h t1delete.h t1subset.h
 t1trans.lo: t1trans.c ../type1/ffilest.h ../type1/types.h \
  ../type1/Xstuff.h ../type1/fontmisc.h ../type1/fontstruct.h \
  ../type1/font.h ../type1/fsmasks.h ../type1/fontfile.h \
  ../type1/fontxlfd.h parseAFM.h ../type1/objects.h ../type1/spaces.h \
- ../type1/util.h ../type1/fontfcn.h ../type1/regions.h t1types.h \
- t1extern.h t1misc.h t1trans.h t1base.h
+ ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1trans.h \
+ t1base.h
 t1x11.lo: t1x11.c ../type1/types.h parseAFM.h ../type1/objects.h \
- ../type1/spaces.h ../type1/util.h ../type1/fontfcn.h \
- ../type1/regions.h t1types.h t1extern.h t1misc.h t1set.h t1aaset.h \
- t1load.h t1finfo.h t1x11.h t1base.h
+ ../type1/spaces.h ../type1/util.h ../type1/fontfcn.h ../type1/paths.h \
+ ../type1/regions.h t1types.h sysconf.h t1extern.h t1misc.h t1set.h \
+ t1aaset.h t1load.h t1finfo.h t1x11.h t1base.h
Index: grace/T1lib/t1lib/parseAFM.c
===================================================================
--- grace.orig/T1lib/t1lib/parseAFM.c
+++ grace/T1lib/t1lib/parseAFM.c
@@ -199,7 +199,9 @@ static char *token(stream)
     idx = 0;
     
     while (ch != EOF && ch != ' ' && ch != CR  && ch != LF &&
-	   ch != CTRL_Z && ch != '\t' && ch != ':' && ch != ';'){
+	   ch != CTRL_Z && ch != '\t' && ch != ':' && ch != ';'
+     && idx < (MAX_NAME -1))
+    {
       ident[idx++] = ch;
       ch = fgetc(stream);
     } /* while */
@@ -235,7 +237,7 @@ static char *linetoken(stream)
     while ((ch = fgetc(stream)) == ' ' || ch == '\t' ); 
     
     idx = 0;
-    while (ch != EOF && ch != CR  && ch != LF && ch != CTRL_Z) 
+    while (ch != EOF && ch != CR  && ch != LF && ch != CTRL_Z && idx < (MAX_NAME - 1)) 
     {
         ident[idx++] = ch;
         ch = fgetc(stream);
Index: grace/T1lib/t1lib/t1aaset.c
===================================================================
--- grace.orig/T1lib/t1lib/t1aaset.c
+++ grace/T1lib/t1lib/t1aaset.c
@@ -2,11 +2,11 @@
   ----- File:        t1aaset.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
                      Subsampling based on code by Raph Levien (raph@acm.org)
-  ----- Date:        2001-04-01
+  ----- Date:        2007-12-21
   ----- Description: This file is part of the t1-library. It contains
                      functions for antialiased setting of characters
 		     and strings of characters.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2007.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -52,6 +52,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 #include "t1types.h"
@@ -803,10 +804,10 @@ GLYPH *T1_AASetChar( int FontID, char ch
   if ((pFontBase->t1lib_flags & T1_AA_CACHING)) {
     if (transform==NULL){
       /* if size/aa is not existent we create it */
-      if ((font_ptr=QueryFontSize( FontID, size, T1aa_level))==NULL){
+      if ((font_ptr=T1int_QueryFontSize( FontID, size, T1aa_level))==NULL){
 	/* We create the required size struct and leave the rest
 	   for T1_SetChar() */
-	font_ptr=CreateNewFontSize( FontID, size, T1aa_level);
+	font_ptr=T1int_CreateNewFontSize( FontID, size, T1aa_level);
 	if (font_ptr==NULL){
 	  T1_errno=T1ERR_ALLOC_MEM;
 	  T1aa_level=savelevel;
@@ -962,11 +963,21 @@ GLYPH *T1_AASetChar( int FontID, char ch
   offset=0;
   target_ptr=aaglyph.bits;
   
-  /* We must check for n_vert==1 because the computation above is not
-     valid in this case */
-  if (n_vert==1)
-    v_start=v_start < v_end ? v_start : v_end;
+  /* We must check for n_vert==1 because then both v_start and v_end could / will
+     affect the same AA scan line. Because I'm forgetful, a reminder:
 
+          v_end |   000000000000000000000
+	        |   111111111111111111111  ^ 
+		Y   111111111111111111111  |
+                    000000000000000000000  | v_start
+
+     In order to count the v_end from bottom to top, we express it as (T1aa_level-v_end).
+     The number of rows to take into account is then v_start-(T1aa_level-v_end).
+  */
+  if (n_vert==1) {
+    v_start=v_start - (T1aa_level - v_end);
+  }
+  
   ptr = glyph->bits;
   for (i = 0; i < n_vert; i++) {
     if (i==0)
@@ -1184,10 +1195,12 @@ GLYPH *T1_AASetString( int FontID, char
   offset=0;
   target_ptr=aastring_glyph.bits;
   
-  /* We must check for n_vert==1 because the computation above is not
-     valid in this case */
-  if (n_vert==1)
-    v_start=v_start < v_end ? v_start : v_end;
+  /* We must check for n_vert==1 because then both v_start and v_end could / will
+     affect the same AA scan line. 
+  */
+  if (n_vert==1) {
+    v_start=v_start - (T1aa_level - v_end);
+  }
   
   ptr = glyph->bits;
   for (i = 0; i < n_vert; i++) {
@@ -1219,6 +1232,220 @@ GLYPH *T1_AASetString( int FontID, char
 
 
 
+/* T1_AASetRect(): Raster a rectangle, whose size is given in charspace units.
+   The resulting glyph does not cause any escapement. */
+GLYPH* T1_AASetRect( int FontID, float size,
+		     float width, float height, T1_TMATRIX *transform)
+{
+  GLYPH *glyph;   /* pointer to bitmap glyph */
+  static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
+  long asc, dsc, ht, wd;
+  long i;
+  long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
+  long v_start, v_end;
+  char *target_ptr;
+  long offset;
+  char *ptr;
+  int y;
+  long lsb, aalsb, aahstart;
+  int memsize;
+  LONG paddedW;
+  int savelevel;
+  
+
+  /* Reset character glyph, if necessary */
+  if (aaglyph.bits!=NULL){
+    free(aaglyph.bits);
+    aaglyph.bits=NULL;
+  }
+  aaglyph.metrics.leftSideBearing=0;
+  aaglyph.metrics.rightSideBearing=0;
+  aaglyph.metrics.advanceX=0;
+  aaglyph.metrics.advanceY=0;
+  aaglyph.metrics.ascent=0;
+  aaglyph.metrics.descent=0;
+  aaglyph.pFontCacheInfo=NULL;
+  aaglyph.bpp=T1aa_bpp;
+
+
+  /* Check for smart antialiasing */
+  savelevel=T1aa_level;
+  if (T1aa_SmartOn){
+    if (size>=T1aa_smartlimit2) {
+      T1aa_level=T1_AA_NONE;
+    }
+    else if (size>=T1aa_smartlimit1) {
+      T1aa_level=T1_AA_LOW;
+    }
+    else {
+      T1aa_level=T1_AA_HIGH;
+    }
+  }
+
+
+  /* First, call routine to rasterize character, all error checking is
+     done in this function: */ 
+  if ((glyph=T1_SetRect( FontID, T1aa_level*size, width, height, transform))==NULL){
+    /* restore level */
+    T1aa_level=savelevel;
+    return(NULL); /* An error occured */
+  }
+  
+  /* In case there are no black pixels, we simply set the dimensions and
+     then return */
+  if ( glyph->bits == NULL) {
+    aaglyph.bits=NULL;
+    aaglyph.metrics.leftSideBearing=0;
+    aaglyph.metrics.rightSideBearing=0;
+    aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
+    aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
+    aaglyph.metrics.ascent=0;
+    aaglyph.metrics.descent=0;
+    aaglyph.pFontCacheInfo=NULL;
+    /* restore level and return */
+    T1aa_level=savelevel;
+    return(&aaglyph);
+  }
+
+  /* Get dimensions of bitmap: */
+  asc=glyph->metrics.ascent;
+  dsc=glyph->metrics.descent;
+  lsb=glyph->metrics.leftSideBearing;
+  ht=asc-dsc;
+  wd=glyph->metrics.rightSideBearing-lsb;
+  
+  if (T1aa_level==T1_AA_NONE){
+    /* we only convert bitmap to bytemap */
+    aaglyph=*glyph;
+    aaglyph.bpp=T1aa_bpp;
+    /* Compute scanline length and such */
+    n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
+    /* Allocate memory for glyph */
+    memsize = n_horz_pad*ht*8;
+    /*    aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */
+    aaglyph.bits = (char *)malloc(memsize*sizeof( char));
+    if (aaglyph.bits == NULL) {
+      T1_errno=T1ERR_ALLOC_MEM;
+      /* restore level */
+      T1aa_level=savelevel;
+      return(NULL);
+    }
+    paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
+    ptr=glyph->bits;
+    target_ptr=aaglyph.bits;
+    for (i = 0; i < ht; i++) {
+      T1_DoLine ( wd, paddedW, ptr, target_ptr );
+      ptr += paddedW;
+      target_ptr += n_horz_pad;
+    }
+    /* restore level */
+    T1aa_level=savelevel;
+    return(&aaglyph);
+  }
+  
+
+  /* Set some looping parameters for subsampling */
+  if (lsb<0){
+    aalsb=lsb/T1aa_level-1;
+    aahstart=T1aa_level+(lsb%T1aa_level);
+  }
+  else{
+    aalsb=lsb/T1aa_level;
+    aahstart=lsb%T1aa_level;
+  }
+  
+  /* The horizontal number of steps: */
+  n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
+  /* And the padded value */
+  n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
+
+  /* vertical number of steps: */
+  if (asc % T1aa_level){ /* not aligned */
+    if ( asc > 0){
+      n_asc=asc/T1aa_level+1;
+      v_start=asc % T1aa_level;
+    }
+    else{
+      n_asc=asc/T1aa_level;
+      v_start=T1aa_level + (asc % T1aa_level); 
+    }
+  }
+  else{
+    n_asc=asc/T1aa_level;
+    v_start=T1aa_level;
+  }
+  if (dsc % T1aa_level){ /* not aligned */
+    if ( dsc < 0){
+      n_dsc=dsc/T1aa_level-1;
+      v_end=-(dsc % T1aa_level);
+    }
+    else{
+      n_dsc=dsc/T1aa_level;
+      v_end=T1aa_level - (dsc % T1aa_level);
+    }
+  }
+  else{
+    n_dsc=dsc/T1aa_level;
+    v_end=T1aa_level;
+  }
+  /* the total number of lines: */
+  n_vert=n_asc-n_dsc;
+  
+  /* Allocate memory for glyph */
+  memsize = n_horz_pad*n_vert;
+
+  /* Note: we allocate 12 bytes more than necessary */
+  aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
+  if (aaglyph.bits == NULL) {
+    T1_errno=T1ERR_ALLOC_MEM;
+    /* restore level */
+    T1aa_level=savelevel;
+    return(NULL);
+  }
+  
+
+  paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
+  offset=0;
+  target_ptr=aaglyph.bits;
+  
+  /* We must check for n_vert==1 because then both v_start and v_end could / will
+     affect the same AA scan line. 
+  */
+  if (n_vert==1) {
+    v_start=v_start - (T1aa_level - v_end);
+  }
+
+  ptr = glyph->bits;
+  for (i = 0; i < n_vert; i++) {
+    if (i==0)
+      y=v_start;
+    else if (i==n_vert-1)
+      y=v_end;
+    else
+      y=T1aa_level;
+    T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
+    ptr += y * paddedW;
+    target_ptr += n_horz_pad;
+  }
+  
+  /* .. and set them in aaglyph */
+  aaglyph.metrics.leftSideBearing=aalsb;
+  aaglyph.metrics.rightSideBearing=aalsb + n_horz;
+  aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
+  aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
+  aaglyph.metrics.ascent=n_asc;
+  aaglyph.metrics.descent=n_dsc;
+  aaglyph.pFontCacheInfo=NULL;
+
+  /* restore level */
+  T1aa_level=savelevel;
+
+  return(&aaglyph);
+
+}
+
+
+
 /* T1_AASetGrayValues(): Sets the byte values that are put into the
    pixel position for the respective entries:
    Returns 0 if successfull.
@@ -1230,7 +1457,7 @@ int T1_AASetGrayValues(unsigned long whi
 		       unsigned long black)
 {
   
-  if (CheckForInit()){
+  if (T1_CheckForInit()){
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1259,7 +1486,7 @@ int T1_AAHSetGrayValues( unsigned long *
 {
   int i;
   
-  if (CheckForInit()){
+  if (T1_CheckForInit()){
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1288,7 +1515,7 @@ int T1_AAHSetGrayValues( unsigned long *
 int T1_AANSetGrayValues( unsigned long bg, unsigned long fg)
 {
   
-  if (CheckForInit()){
+  if (T1_CheckForInit()){
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1313,7 +1540,7 @@ int T1_AAGetGrayValues( long *pgrayvals)
 {
   int i;
   
-  if (CheckForInit()) {
+  if (T1_CheckForInit()) {
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1332,14 +1559,14 @@ int T1_AAGetGrayValues( long *pgrayvals)
 
 
 
-/* Get the current setting of graylevels for 2x antialiasing. The 17
+/* Get the current setting of graylevels for 4x antialiasing. The 17
    values are stored at address pgrayvals in order from background to
    foreground */
 int T1_AAHGetGrayValues( long *pgrayvals) 
 {
   int i;
 
-  if (CheckForInit()) {
+  if (T1_CheckForInit()) {
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1350,20 +1577,20 @@ int T1_AAHGetGrayValues( long *pgrayvals
   }
 
   for ( i=0; i<17; i++) { /* bg (i=0)  to fg (i=16) */
-    pgrayvals[i]=gv[i];
+    pgrayvals[i]=gv_h[i];
   }
   return( 0);
 }
 
 
 
-/* Get the current setting of graylevels for 2x antialiasing. The 2
+/* Get the current setting of graylevels for no antialiasing. The 2
    values are stored at address pgrayvals in order from background to
    foreground */
 int T1_AANGetGrayValues( long *pgrayvals) 
 {
 
-  if (CheckForInit()) {
+  if (T1_CheckForInit()) {
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1372,8 +1599,8 @@ int T1_AANGetGrayValues( long *pgrayvals
     T1_errno=T1ERR_INVALID_PARAMETER;
     return(-1);
   }
-  pgrayvals[0]=gv[0]; /* background */
-  pgrayvals[1]=gv[1]; /* foreground */
+  pgrayvals[0]=gv_n[0]; /* background */
+  pgrayvals[1]=gv_n[1]; /* foreground */
   return( 0);
 }
 
@@ -1385,7 +1612,7 @@ int T1_AANGetGrayValues( long *pgrayvals
 int  T1_AASetBitsPerPixel( int bpp)
 {
   
-  if (CheckForInit()){
+  if (T1_CheckForInit()){
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -1425,7 +1652,7 @@ int T1_AAGetBitsPerPixel( void)
 int T1_AASetLevel( int level)
 {
   
-   if (CheckForInit()){
+   if (T1_CheckForInit()){
      T1_errno=T1ERR_OP_NOT_PERMITTED;
      return(-1);
    }
@@ -1606,10 +1833,12 @@ GLYPH *T1_AAFillOutline( T1_OUTLINE *pat
   offset=0;
   target_ptr=aaglyph.bits;
   
-  /* We must check for n_vert==1 because the computation above is not
-     valid in this case */
-  if (n_vert==1)
-    v_start=v_start < v_end ? v_start : v_end;
+  /* We must check for n_vert==1 because then both v_start and v_end could / will
+     affect the same AA scan line.
+  */
+  if (n_vert==1) {
+    v_start=v_start - (T1aa_level - v_end);
+  }
 
   ptr = glyph->bits;
   for (i = 0; i < n_vert; i++) {
Index: grace/T1lib/t1lib/t1aaset.h
===================================================================
--- grace.orig/T1lib/t1lib/t1aaset.h
+++ grace/T1lib/t1lib/t1aaset.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1aaset.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2003-01-02
   ----- Description: This file is part of the t1-library. It contains
                      definitions and declarations for t1set.c.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -32,6 +32,9 @@ GLYPH *T1_AASetChar( int FontID, char ch
 GLYPH *T1_AASetString( int FontID, char *string, int len,
 		       long spaceoff, int modflag,
 		       float size, T1_TMATRIX *transform);
+GLYPH* T1_AASetRect( int FontID, float size,
+		     float width, float height,
+		     T1_TMATRIX *transform);
 int T1_AASetGrayValues( unsigned long white,
 			unsigned long gray75,
 			unsigned long gray50,
@@ -57,6 +60,9 @@ extern GLYPH *T1_AASetChar( int FontID,
 extern GLYPH *T1_AASetString( int FontID, char *string, int len,
 			      long spaceoff, int modflag,
 			      float size, T1_TMATRIX *transform);
+extern GLYPH* T1_AASetRect( int FontID, float size,
+			  float width, float height,
+			  T1_TMATRIX *transform);
 extern int T1_AASetGrayValues( unsigned long white,
 			       unsigned long gray75,
 			       unsigned long gray50,
Index: grace/T1lib/t1lib/t1afmtool.c
===================================================================
--- grace.orig/T1lib/t1lib/t1afmtool.c
+++ grace/T1lib/t1lib/t1afmtool.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1afmtool.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2007-12-23
   ----- Description: This file is part of the t1-library. It contains
                      functions for generating a fallback set of afm data
 		     from type 1 font files.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2007.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -52,6 +52,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 #include "../type1/blues.h"
 
@@ -89,6 +90,13 @@ FontInfo *T1_GenerateAFMFallbackInfo( in
   char **charnames;
   int nochars=0;
   FontInfo *pAFMData;
+
+  /* When generaing fallback info, we accumulate a font bounding box that
+     could be useful when the font's definition is missing or trivial. */
+  int acc_llx=0;
+  int acc_lly=0;
+  int acc_urx=0;
+  int acc_ury=0;
   
   
   /* We return to this if something goes wrong deep in the rasterizer */
@@ -103,7 +111,7 @@ FontInfo *T1_GenerateAFMFallbackInfo( in
   
 
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     sprintf( err_warn_msg_buf,
 	     "Can't generate AFM Info from Font %d (invalid ID)\n", FontID);
     T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf,
@@ -236,6 +244,21 @@ FontInfo *T1_GenerateAFMFallbackInfo( in
 	pAFMData->cmi[i].charBBox.ury =0;
       }
       pAFMData->cmi[i].ligs=NULL;
+
+      /* Accumulate bounding box of font */
+      if ( pAFMData->cmi[i].charBBox.llx < acc_llx ) {
+	acc_llx=pAFMData->cmi[i].charBBox.llx;
+      }
+      if ( pAFMData->cmi[i].charBBox.lly < acc_lly ) {
+	acc_lly=pAFMData->cmi[i].charBBox.lly;
+      }
+      if ( pAFMData->cmi[i].charBBox.urx > acc_urx ) {
+	acc_urx=pAFMData->cmi[i].charBBox.urx;
+      }
+      if ( pAFMData->cmi[i].charBBox.ury > acc_ury ) {
+	acc_ury=pAFMData->cmi[i].charBBox.ury;
+      }
+      
       /* We are done with area, so get rid of it. Solves the REALLY
 	 HUGE memory leak */
       KillRegion (area);
@@ -246,6 +269,24 @@ FontInfo *T1_GenerateAFMFallbackInfo( in
 	   nochars, FontID);
   T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf,
 	       T1LOG_STATISTIC);
+
+  /* Check whether the bounding box we computed could be better than that
+     specified in the font file itself. Id so, we overwrite it. */
+  if ( pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[0].data.integer == 0   &&
+       pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[1].data.integer == 0   &&
+       pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[2].data.integer == 0   &&
+       pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[3].data.integer == 0 ) {
+    pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[0].data.integer = acc_llx;  
+    pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[1].data.integer = acc_lly;  
+    pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[2].data.integer = acc_urx;  
+    pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[3].data.integer = acc_ury;
+    
+    sprintf( err_warn_msg_buf,
+	     "Substituted accumulated FontBBox [%d,%d,%d,%d] for trivial FontBBox of font %d!",
+	     acc_llx, acc_lly, acc_urx, acc_ury, FontID);
+    T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf,
+		 T1LOG_WARNING);
+  }
   
   /* make sure to free S */
   if (S) {
@@ -281,7 +322,7 @@ int T1_WriteAFMFallbackFile( int FontID)
   
 
   /* Check for valid font */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     sprintf( err_warn_msg_buf,
 	     "Warning: Invalid FontID, font %d not loaded!",
 	     FontID);
Index: grace/T1lib/t1lib/t1base.c
===================================================================
--- grace.orig/T1lib/t1lib/t1base.c
+++ grace/T1lib/t1lib/t1base.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1base.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-03
+  ----- Date:        2005-05-17
   ----- Description: This file is part of the t1-library. It contains basic
                      routines to initialize the data structures used
 		     by the t1-library.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -50,11 +50,12 @@
 
 #include "../type1/ffilest.h" 
 #include "../type1/types.h"
-#include "parseAFM.h" 
+#include "parseAFM.h"
 #include "../type1/objects.h"
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -66,8 +67,66 @@
 #include "t1delete.h"
 
 
+static int test_for_t1_file( char *buffer );
 static int T1_pad=0;
 
+/* A fix for Encoding Vector problem. Initialization / Deinitialization
+   is now done in T1_InitLib() / T1-CloseLib. */
+extern boolean Init_BuiltInEncoding( void);
+extern psobj *StdEncArrayP;
+
+static const char* T1errmsg[] = {
+  "",                                                          /*                              -10 */
+  "",                                                          /*                              -9  */
+  "",                                                          /*                              -8  */
+  "",                                                          /*                              -7  */
+  "",                                                          /*                              -6  */
+  "Attempt to Load Multiple Master Font",                      /* T1ERR_SCAN_FONT_FORMAT       -5  */
+  "Type 1 Font File Open Error",                               /* T1ERR_SCAN_FILE_OPEN_ERR     -4  */
+  "Virtual Memory Exceeded",                                   /* T1ERR_SCAN_OUT_OF_MEMORY     -3  */
+  "Syntactical Error Scanning Font File",                      /* T1ERR_SCAN_ERROR             -2  */
+  "Premature End of Font File Encountered",                    /* T1ERR_SCAN_FILE_EOF          -1  */
+  "",                                                          /*                               0  */
+  "Path Construction Error",                                   /* T1ERR_PATH_ERROR              1  */
+  "Font is Corrupt",                                           /* T1ERR_PARSE_ERROR             2  */
+  "Rasterization Aborted",                                     /* T1ERR_TYPE1_ABORT             3  */
+  "",                                                          /*                               4  */
+  "",                                                          /*                               5  */
+  "",                                                          /*                               6  */
+  "",                                                          /*                               7  */
+  "",                                                          /*                               8  */
+  "",                                                          /*                               9  */
+  "Font ID Invalid in this Context",                           /* T1ERR_INVALID_FONTID          10 */
+  "Invalid Argument in Function Call",                         /* T1ERR_INVALID_PARAMETER       11 */
+  "Operation not Permitted",                                   /* T1ERR_OP_NOT_PERMITTED        12 */
+  "Memory Allocation Error",                                   /* T1ERR_ALLOC_MEM               13 */
+  "Error Opening File",                                        /* T1ERR_FILE_OPEN_ERR           14 */
+  "Unspecified T1Lib Error",                                   /* T1ERR_UNSPECIFIED             15 */
+  "Missing AFM Data",                                          /* T1ERR_NO_AFM_DATA             16 */
+  "X11 Interface Error",                                       /* T1ERR_X11                     17 */
+  "Missing Component of Composite Character"                   /* T1ERR_COMPOSITE_CHAR          18 */
+  "Error Scanning Encoding File",                              /* T1ERR_SCAN_ENCODING           19 */
+  "",                                                          /*                               20 */
+};
+
+
+/* T1_StrError(): Return an error message corresponding to the value of
+   t1err. */
+const char *T1_StrError( int t1err) 
+{
+  int errind;
+
+  errind = t1err + 10;
+
+  if ( errind < 0 )
+    errind = 0;
+  if ( errind > 29 )
+    errind = 0;
+  
+  return T1errmsg[errind];
+}
+
+
 
 /* This function is to be called by the user to initialize
    the font mechanism */
@@ -80,8 +139,12 @@ void *T1_InitLib( int log)
   char *logfilepath=NULL;
   char *envlogreq=NULL;
   int  usrforcelog=0;
-  
-  
+
+  /* Check against multiple initialization. */
+  if ( T1_Up != 0 ) {
+    T1_errno=T1ERR_OP_NOT_PERMITTED;
+    return NULL;
+  }
   
   /* Reset T1_errno */
   T1_errno=0;
@@ -223,7 +286,12 @@ void *T1_InitLib( int log)
 		   T1LOG_WARNING);
   }
   
-
+  /* Initialize builtin Standard Encoding */
+  if ( !(Init_BuiltInEncoding()) ) {
+      T1_PrintLog( "T1_InitLib()", "Unable initialize internal StandardEncoding!",
+		   T1LOG_ERROR);
+  }
+  
   /* Set the default encoding to the fonts' internal encoding */
   pFontBase->default_enc=NULL;
   
@@ -255,14 +323,31 @@ void *T1_InitLib( int log)
     if (result>-1)
       pFontBase->no_fonts+=result;
     i++;
-    
   }
-  if (result == 0){
+  if ( (result == 0) && (i != 0)){
     T1_PrintLog( "T1_InitLib()", "No fonts from Font Database File(s) found (T1_errno=%d)",
 		 T1LOG_ERROR, T1_errno);
     return(NULL);
   }
 
+  result=0;
+  /* Read XLFD fontdatabase(s) */
+  i=0;
+  while (T1_FDBXLFD_ptr[i]!=NULL) {
+    if ((result=intT1_scanFontDBaseXLFD(T1_FDBXLFD_ptr[i]))==-1){
+      T1_PrintLog( "T1_InitLib()", "Fatal error scanning XLFD Font Database File %s",
+		   T1LOG_WARNING, T1_FDB_ptr[i]);
+    }
+    if (result>-1)
+      pFontBase->no_fonts+=result;
+    i++;
+  }
+  if ( (result == 0) && (i != 0)){
+    T1_PrintLog( "T1_InitLib()", "No fonts from XLFD Font Database File(s) found (T1_errno=%d)",
+		 T1LOG_ERROR, T1_errno);
+    return(NULL);
+  }
+
   /* Initialize the no_fonts... values */
   pFontBase->no_fonts_ini=pFontBase->no_fonts;
   pFontBase->no_fonts_limit=pFontBase->no_fonts;
@@ -284,7 +369,7 @@ void *T1_InitLib( int log)
    - initializes an array that allows to acces these names by an
      index number, the font_ID
    - returns -1 on fatal error and the number of fonts located
-     successfullly
+     successfully
    */
 int intT1_scanFontDBase( char *filename)
 {
@@ -295,7 +380,6 @@ int intT1_scanFontDBase( char *filename)
   int nofonts=0;
   FONTPRIVATE* fontarrayP=NULL;
   
-  
 #ifndef O_BINARY
 #  define O_BINARY 0x0
 #endif
@@ -408,13 +492,139 @@ int intT1_scanFontDBase( char *filename)
 }
 
 
+/* intT1_scanFontDBaseXLFD():
+   - opens the file with the font definitions,
+   - reads the number of fonts defined and saves this in FontBase,
+   - allocates memory for all the filenames of the Type1 files
+   - tests for .pfa und .pfb files and saves the name found
+   - initializes an array that allows to acces these names by an
+     index number, the font_ID
+   - returns -1 on fatal error and the number of fonts located
+     successfully.
+
+     This function is identical to intT1_scanFontDBase() with the
+     difference that it expects the database file to be in XLFD format,
+     that is, the font's name comes in the first place stead of in
+     the last.
+   */
+int intT1_scanFontDBaseXLFD( char *filename)
+{
+  int fd;
+  int filesize, i, j, l, m;
+  int found=0, located=0;
+  char *filebuffer;
+  int nofonts=0;
+  FONTPRIVATE* fontarrayP=NULL;
+  
+#ifndef O_BINARY
+#  define O_BINARY 0x0
+#endif
+
+  if ((fd=open( filename, O_RDONLY | O_BINARY))<3){
+    T1_PrintLog( "intT1_scanFontDBaseXLFD()", "XLFD Font Database File %s not found!",
+		 T1LOG_WARNING, filename);
+    T1_errno=T1ERR_FILE_OPEN_ERR;
+    return(-1);
+  }
+
+  /* Get the file size */
+  filesize=lseek( fd, 0, 2);
+  /* Reset fileposition to start */
+  lseek (fd, 0, 0); 
+
+  if ((filebuffer=(char *)malloc(filesize*sizeof(char)
+				 )) == NULL){
+    T1_PrintLog(  "intT1_scanFontDBaseXLFD()",
+		  "Couldn't allocate memory for loading XLFD font database file %s",
+		  T1LOG_ERROR, filename);
+    T1_errno=T1ERR_ALLOC_MEM;
+    return(-1);
+  }
+  
+  i=read( fd, filebuffer, filesize);
+  close(fd);   /* Close XLFD font database file */
+   
+  i=j=l=m=0;
+  
+  while (i<filesize) {
+    if (filebuffer[i]=='\n'){ /* We are at the end of line */
+      if (j==0) {  /* Read the first line as the number of fonts */
+	filebuffer[i]=0;
+	sscanf( &filebuffer[0], "%d", &nofonts);
+	filebuffer[i]='\n';  /* Because it gives a better feeling */
+	/* (Re)Allocate memory for 'no_fonts' structures: */ 
+	if ((FontBase.pFontArray=(FONTPRIVATE *)
+	     realloc( FontBase.pFontArray, (FontBase.no_fonts+nofonts)*sizeof(FONTPRIVATE))) == NULL) {
+	  T1_PrintLog( "inT1_scanFontDBaseXLFD()",
+		       "Failed to allocate memory for FONTPRIVATE-area while scanning %s",
+		       T1LOG_ERROR, filename);
+	  T1_errno=T1ERR_ALLOC_MEM;
+	  return(-1);
+	}
+	/* setup pointer to newly allocated area and do a reset */
+	fontarrayP=&(FontBase.pFontArray[FontBase.no_fonts]);
+	memset(fontarrayP, 0, nofonts*sizeof(FONTPRIVATE));
+	located=1; /* In  order to increment m */
+      }
+      else {       /* We are in the second or higher line */
+	/* l indexes the beginning of the line */
+	while (isspace((int)filebuffer[l])){
+	  l++;
+	}
+	/* We are at the first printable character of a line; 
+	   scan the first white space terminated string as font
+	   file name. */
+	sscanf( &(filebuffer[l]), "%s", &(linebuf[0]));
+	/* We print error string before testing because after the call
+	   to test_for_t1_file() filename is substituted by an emty
+	   string if the file was not found: */
+	sprintf( err_warn_msg_buf, "Type 1 Font file %s.[pfa/pfb] not found (FontID=%d, SearchPath=%s)",
+		 linebuf, m-1, T1_GetFileSearchPath(T1_PFAB_PATH));
+	if ((test_for_t1_file( &linebuf[0]))){
+	  T1_PrintLog( "intT1_scanFontDBase()", err_warn_msg_buf, T1LOG_WARNING);
+	  located=0;
+	}
+	else{
+	  /* linebuf contains now the valid Type1 filename; let's
+	     now copy this string into the appropriate place in the
+	     FONTPRIVATE-struct: */
+	  found++;
+	  located=1;
+	  if ((fontarrayP[m-1].pFontFileName=(char *)
+	       calloc( strlen( &linebuf[0])+1, sizeof(char))) == NULL){
+	    T1_PrintLog( "intT1_scanFontDBaseXLFD()",
+			 "Failed to allocate memory for Filename %s (FontID=%d)",
+			 T1LOG_ERROR, &linebuf[0], m-1);
+	    T1_errno=T1ERR_ALLOC_MEM;
+	    return(-1);
+	  }
+	  strcpy( fontarrayP[m-1].pFontFileName, &linebuf[0]);
+	}
+      }
+      j++; /* Advance line counter */
+      if ((located))
+	m++;
+      /* Store index to new line */
+      l = i + 1;
+    }
+    if (j>nofonts) /* to ignore especially white space at end */
+      break;
+    i++;   /* Step further in file position */
+  }
+  /* Return the memory for file reading */
+  free(filebuffer); 
+  
+  return( found);
+}
+
+
 /* T1_CloseLib(): Close the library and free all associated memory */
 int T1_CloseLib( void)
 {
 
   int i, j, error=0;
 
-  if (T1_Up){
+  if ( T1_Up != 0 ) {
     for (i=pFontBase->no_fonts; i; i--){
       /* Free filename only if not NULL and if the font is physical!
 	 Do it before removing the font since the physical information
@@ -445,6 +655,12 @@ int T1_CloseLib( void)
     else
       error=1;
 
+    /* Get rid of internal StandardEncoding vector */
+    if ( StdEncArrayP != NULL ) {
+      free( StdEncArrayP);
+      StdEncArrayP = NULL;
+    }
+
     /* Free search paths */
     intT1_FreeSearchPaths();
 
@@ -617,9 +833,9 @@ void T1_SetLogLevel( int level)
 
 
 
-/* CheckForInit(): If no initialization of font mechanism has been
+/* T1_CheckForInit(): If no initialization of font mechanism has been
    done, return -1, indicating an error. */
-int CheckForInit(void)
+int T1_CheckForInit(void)
 {
   if(T1_Up)
     return(0);
@@ -630,14 +846,14 @@ int CheckForInit(void)
 
 
 
-/* CheckForFontID(): Checks the font mechanism concerning the specified
+/* T1_CheckForFontID(): Checks the font mechanism concerning the specified
    ID. It returns:
                    0  if font belonging to FontID has not yet been loaded
 		   1  if font belonging to FontID has already been loaded
 		   -1 if FontID is an invalid specification or t1lib not
 		      initialized
 		   */
-int CheckForFontID( int FontID)
+int T1_CheckForFontID( int FontID)
 {
 
   /* FontID is invalid */
@@ -656,7 +872,7 @@ int CheckForFontID( int FontID)
 /* test_for_t1_file returns 0 if a file "name.pfa" or "name.pfb"
    was found. Else, -1 is returned. If successful, buffer contains the
    found filename string */
-int test_for_t1_file( char *buffer )
+static int test_for_t1_file( char *buffer )
 {
   int i=0;
   char *FullName;
@@ -704,9 +920,9 @@ int test_for_t1_file( char *buffer )
 char *T1_GetFontFileName( int FontID)
 {
 
-  static char filename[T1_MAXPATHLEN+1];
+  static char filename[MAXPATHLEN+1];
   
-  if (CheckForInit())return(NULL);
+  if (T1_CheckForInit())return(NULL);
 
   /* Check first for valid FontID */
   if ((FontID<0) || (FontID>FontBase.no_fonts)){
@@ -733,7 +949,7 @@ char *T1_GetFontFileName( int FontID)
 int T1_SetAfmFileName( int FontID, char *afm_name)
 {
 
-  if (CheckForFontID(FontID)!=0){
+  if (T1_CheckForFontID(FontID)!=0){
     /* Operation may not be applied because FontID is invalid
        or font is loaded */
     T1_errno=T1ERR_INVALID_FONTID;
@@ -767,9 +983,9 @@ int T1_SetAfmFileName( int FontID, char
 char *T1_GetAfmFileName( int FontID)
 {
 
-  static char filename[T1_MAXPATHLEN+1];
+  static char filename[MAXPATHLEN+1];
   
-  if (CheckForInit())return(NULL);
+  if (T1_CheckForInit())return(NULL);
 
   /* Check first for valid FontID */
   if ((FontID<0) || (FontID>FontBase.no_fonts)){
@@ -788,10 +1004,11 @@ char *T1_GetAfmFileName( int FontID)
 
 
   
-/* T1_Get_no_fonts(): Return the number of declared fonts */
-int  T1_Get_no_fonts(void)
+/* T1_GetNoFonts(): Return the number of declared fonts */
+int  T1_GetNoFonts(void)
 {
-  if (CheckForInit())return(-1);
+  if (T1_CheckForInit())
+    return(-1);
   return(FontBase.no_fonts);
 }
 
@@ -806,11 +1023,11 @@ int T1_SetDeviceResolutions( float x_res
 
   int i;
   
-  if (CheckForInit())
+  if (T1_CheckForInit())
     ;   /* Not initialized -> no size dependent data -> OK */
   else
     /* Check if size-dependent data is existent */
-    for ( i=T1_Get_no_fonts(); i; i--)
+    for ( i=T1_GetNoFonts(); i; i--)
       if (pFontBase->pFontArray[i-1].pFontSizeDeps!=NULL){
 	T1_errno=T1ERR_OP_NOT_PERMITTED;
 	return(-1); /* There's is size dependent data for a font */
@@ -862,7 +1079,7 @@ int T1_CopyFont( int FontID)
   
   
   /* Check for a valid source font */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -1017,99 +1234,6 @@ int T1_GetBitmapPad( void)
 
 
 
-/* bin_dump(): Print a binary dump of a byte, short and
-   long variable (used for debug purposes only): */
-void bin_dump_c(unsigned char value, char space_flag)
-{
-  int i,j;
-  
-  for (i=0;i<=7;i++){
-    if ((j=((value)>>i)&0x01))
-      printf("X");
-    else
-      printf(".");
-  }
-  if (space_flag)
-    printf(" ");
-
-}
-
-void bin_dump_s(unsigned short value, char space_flag)
-{
-  int i,j;
-
-  if (T1_CheckEndian()){
-    for (i=8;i<=15;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-    for (i=0;i<=7;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-  }
-  else{
-    for (i=0;i<=15;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-  }
-  if (space_flag)
-    printf(" ");
-  
-}
-
-void bin_dump_l(unsigned long value, char space_flag)
-{
-  int i,j;
-  
-  if (T1_CheckEndian()){
-    for (i=24;i<=31;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-    for (i=16;i<=23;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-    for (i=8;i<=15;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-    for (i=0;i<=7;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-  }
-  else{
-    for (i=0;i<=31;i++){
-      if ((j=((value)>>i)&0x01))
-	printf("X");
-      else
-	printf(".");
-    }
-  }
-  if (space_flag)
-    printf(" ");
-
-}
-
-
-
 /* CheckEndian(): Checks whether the current machine is of little or big
    endian architecture. This is important for concatenating bitmaps.
    Function returns 0 if LittleEndian and 1 if BigEndian representation
@@ -1163,11 +1287,11 @@ extern void T1_SetRasterFlags( int flags
 char *T1_GetFontFilePath( int FontID)
 {
 
-  static char filepath[T1_MAXPATHLEN+1];
+  static char filepath[MAXPATHLEN+1];
   char *FileNamePath=NULL;
   
   /* is initialzed? */
-  if (CheckForInit()) {
+  if (T1_CheckForInit()) {
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -1202,13 +1326,13 @@ char *T1_GetFontFilePath( int FontID)
 char *T1_GetAfmFilePath( int FontID)
 {
   
-  static char filepath[T1_MAXPATHLEN+1];
+  static char filepath[MAXPATHLEN+1];
   char *FontFileName;
   char *AFMFilePath;
   int i, j;
   
   /* is initialized? */
-  if ((CheckForInit())) {
+  if ((T1_CheckForInit())) {
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -1261,13 +1385,16 @@ char *T1_GetAfmFilePath( int FontID)
     filepath[i+4]='\0';
   }
   /* Get full path of the afm file (The case of a full path name
-     name specification is valid */
+     name specification is valid) */
   if ((AFMFilePath=intT1_Env_GetCompletePath( filepath, T1_AFM_ptr)) == NULL) {
     return NULL;
   }
+  
   strcpy( filepath, AFMFilePath);
   free( AFMFilePath);
   
   return( filepath);
   
 }
+
+
Index: grace/T1lib/t1lib/t1base.h
===================================================================
--- grace.orig/T1lib/t1lib/t1base.h
+++ grace/T1lib/t1lib/t1base.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1base.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-03
+  ----- Date:        2002-05-16
   ----- Description: This file is part of the t1-library. It contains
                      declarations and definitions for t1base.c
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -29,21 +29,18 @@
 
 void *T1_InitLib( int log);
 int intT1_scanFontDBase( char *filename);
+int intT1_scanFontDBaseXLFD( char *filename);
 int T1_CloseLib( void);
 int T1_AddFont( char *fontfilename);
 void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...);
 void T1_SetLogLevel( int level);
-int CheckForInit(void);
-int CheckForFontID( int FontID);
-int test_for_t1_file( char *buffer );
+int T1_CheckForInit(void);
+int T1_CheckForFontID( int FontID);
 char *T1_GetFontFileName( int FontID);
-int  T1_Get_no_fonts(void);
+int  T1_GetNoFonts(void);
 int T1_SetDeviceResolutions( float x_res, float y_res);
 int T1_CopyFont( int FontID);
 int T1_QueryX11Support( void);
-void bin_dump_c(unsigned char value, char space_flag);
-void bin_dump_s(unsigned short value, char space_flag);
-void bin_dump_l(unsigned long value, char space_flag);
 int T1_CheckEndian(void);
 int T1_SetBitmapPad( int pad);
 int T1_GetBitmapPad( void);
@@ -53,6 +50,7 @@ char *T1_GetAfmFileName( int FontID);
 int T1_SetAfmFileName( int FontId, char *afm_name);
 char *T1_GetFontFilePath( int FontID);
 char *T1_GetAfmFilePath( int FontID);
+const char *T1_StrError( int t1err);
 
 extern int T1_Type1OperatorFlags;
 
@@ -60,21 +58,18 @@ extern int T1_Type1OperatorFlags;
 
 extern void *T1_InitLib( int log);
 extern int intT1_scanFontDBase( char *filename);
+extern int intT1_scanFontDBaseXLFD( char *filename);
 extern int T1_CloseLib( void);
 extern int T1_AddFont( char *fontfilename);
 extern void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...);
 extern void T1_SetLogLevel( int level);
-extern int CheckForInit(void);
-extern int CheckForFontID( int FontID);
-extern int test_for_t1_file( char *buffer );
+extern int T1_CheckForInit(void);
+extern int T1_CheckForFontID( int FontID);
 extern char *T1_GetFontFileName( int FontID);
-extern int  T1_Get_no_fonts(void);
+extern int  T1_GetNoFonts(void);
 extern int T1_SetDeviceResolutions( float x_res, float y_res);
 extern int T1_QueryX11Support( void);
 extern int T1_CopyFont( int FontID);
-extern void bin_dump_c(unsigned char value, char space_flag);
-extern void bin_dump_s(unsigned short value, char space_flag);
-extern void bin_dump_l(unsigned long value, char space_flag);
 extern int T1_CheckEndian(void);
 extern int T1_SetBitmapPad( int pad);
 extern int T1_GetBitmapPad( void);
@@ -84,5 +79,6 @@ extern char *T1_GetAfmFileName( int Font
 extern int T1_SetAfmFileName( int FontId, char *afm_name);
 extern char *T1_GetFontFilePath( int FontID);
 extern char *T1_GetAfmFilePath( int FontID);
+extern const char *T1_StrError( int t1err);
 
 #endif
Index: grace/T1lib/t1lib/t1delete.c
===================================================================
--- grace.orig/T1lib/t1lib/t1delete.c
+++ grace/T1lib/t1lib/t1delete.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1delete.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-06-03
+  ----- Date:        2002-12-02
   ----- Description: This file is part of the t1-library. It contains
                      functions for giving free previously allocated
 		     memory areas and similar things.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2002. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -76,7 +76,7 @@ int T1_DeleteSize( int FontID, float siz
   for ( j=0; j<4; j++){
     antialias=level[j];
     /* Check if size exists; if not, return 1 */
-    if ((ptr=QueryFontSize( FontID, size, antialias))!=NULL){
+    if ((ptr=T1int_QueryFontSize( FontID, size, antialias))!=NULL){
       /* We have to remove a size-> */
       jobs++;
       /* Get pointers to structure which is before/after  the structure
@@ -140,17 +140,17 @@ int T1_DeleteAllSizes( int FontID)
   
   FONTSIZEDEPS *ptr;
   
-  if (CheckForFontID(FontID)!=1)
+  if (T1_CheckForFontID(FontID)!=1)
     return(-1);
   
   /* Start deleting at the end of the linked list: */ 
   sizecount=0;
-  if ((ptr=GetLastFontSize( FontID))==NULL){
+  if ((ptr=T1int_GetLastFontSize( FontID))==NULL){
     /* There has not been any size dependent data: */
     return(0);
   }
 
-  while (((ptr=GetLastFontSize(FontID)) != NULL)){
+  while (((ptr=T1int_GetLastFontSize(FontID)) != NULL)){
     currsize=ptr->size;
     T1_DeleteSize( FontID, currsize);
     sizecount++;
@@ -198,12 +198,12 @@ int T1_DeleteFont( int FontID)
   int result;
 
   
-  if (CheckForFontID(FontID)==-1){  /* Invalid ID */
+  if (T1_CheckForFontID(FontID)==-1){  /* Invalid ID */
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);   
   }
   
-  if (CheckForFontID(FontID)==0)   /* Font is not loaded */
+  if (T1_CheckForFontID(FontID)==0)   /* Font is not loaded */
     return(0);   
 
   /* Memory freeing must be done hierachical, start with size dependent
Index: grace/T1lib/t1lib/t1enc.c
===================================================================
--- grace.orig/T1lib/t1lib/t1enc.c
+++ grace/T1lib/t1lib/t1enc.c
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1enc.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-18
+  ----- Date:        2005-05-01
   ----- Description: This file is part of the t1-library. It contains
                      functions encoding handling at runtime.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -50,6 +50,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -424,7 +425,6 @@ static int TryT1LibEncoding( char *lineb
   /* Check if exactly 256 characters have been defined, if not,
      return NULL: */
   if (charname_count!=256){
-    T1_errno=T1ERR_UNSPECIFIED;
     return( -1);
   }
 
@@ -534,7 +534,7 @@ static char **ScanEncodingFile( char *Fi
   }
   
   if ( cnsize<0) {
-    /* T1_errno is already set from the respective function */
+    T1_errno=T1ERR_SCAN_ENCODING;
     if ( charnames!=NULL) {
       free(charnames); 
     }
@@ -629,7 +629,7 @@ int T1_ReencodeFont( int FontID, char **
   
   
   /* First, check for valid font ID residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -694,6 +694,7 @@ int T1_ReencodeFont( int FontID, char **
       }
     }
     /* Update kerning table */
+    pFontBase->pFontArray[FontID].KernMapSize=0;
     k=pFontBase->pFontArray[FontID].pAFMData->numOfPairs;
     if (k>0){ /* i.e., there are any pairs */
       /* OK, it does not suffice to alloc numOfPairs METRICS_ENTRYs, because
@@ -754,7 +755,7 @@ int T1_ReencodeFont( int FontID, char **
 int T1_SetDefaultEncoding( char **encoding)
 {
   
-  if (CheckForInit()){
+  if (T1_CheckForInit()){
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
@@ -772,7 +773,7 @@ char *T1_GetEncodingScheme( int FontID)
   static char enc_scheme[256];
   
   /* First, check for valid font ID residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
Index: grace/T1lib/t1lib/t1env.c
===================================================================
--- grace.orig/T1lib/t1lib/t1env.c
+++ grace/T1lib/t1lib/t1env.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1env.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-11-12
+  ----- Date:        2007-12-22
   ----- Description: This file is part of the t1-library. It implements
                      the reading of a configuration file and path-searching
 		     of type1-, afm- and encoding files.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2007.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -74,6 +74,7 @@ static int pfab_no=-1;
 static int afm_no=-1;
 static int enc_no=-1;
 static int fdb_no=-1;
+static int fdbxlfd_no=-1;
 
 static char path_sep_char='\0';
 static char path_sep_string[2];
@@ -91,6 +92,7 @@ static char T1_afm[]="sys$disk:[]";
 static char T1_enc[]="sys$disk:[]";
 #endif
 char T1_fdb[]="FontDataBase";
+char T1_fdbxlfd[]="";  /* By default, we do not search XLFD databases. */
 
 
 /* keywords recognized in config file */
@@ -98,6 +100,7 @@ static const char enc_key[]="ENCODING";
 static const char pfab_key[]="TYPE1";
 static const char afm_key[]="AFM";
 static const char fdb_key[]="FONTDATABASE";
+static const char fdbxlfd_key[]="FONTDATABASEXLFD";  
 
 
 /* qstrncpy(): Copy bytes from srcP to to destP. srcP is count bytes long
@@ -164,6 +167,12 @@ void intT1_SetupDefaultSearchPaths( void
     strcpy(T1_FDB_ptr[0],T1_fdb);
     fdb_no=0;
   }
+
+  if (fdbxlfd_no==-1) {
+    /* The XLFD font data base defaults to be empty */
+    T1_FDBXLFD_ptr=(char**) calloc( 1, sizeof(char*));
+    fdbxlfd_no=0;
+  }
 }
 
 
@@ -177,39 +186,53 @@ void intT1_FreeSearchPaths( void)
   if (T1_PFAB_ptr!=NULL) {
     while (T1_PFAB_ptr[i]!=NULL) {
       free(T1_PFAB_ptr[i]);
-      T1_PFAB_ptr[i]=NULL;
+      T1_PFAB_ptr[i++]=NULL;
     }
     free( T1_PFAB_ptr);
+    T1_PFAB_ptr=NULL;
   }
   i=0;
   if (T1_AFM_ptr!=NULL) {
     while (T1_AFM_ptr[i]!=NULL) {
       free(T1_AFM_ptr[i]);
-      T1_AFM_ptr[i]=NULL;
+      T1_AFM_ptr[i++]=NULL;
     }
     free( T1_AFM_ptr);
+    T1_AFM_ptr=NULL;
   }
   i=0;
   if (T1_ENC_ptr!=NULL) {
     while (T1_ENC_ptr[i]!=NULL) {
       free(T1_ENC_ptr[i]);
-      T1_ENC_ptr[i]=NULL;
+      T1_ENC_ptr[i++]=NULL;
     }
     free( T1_ENC_ptr);
+    T1_ENC_ptr=NULL;
   }
   i=0;
   if (T1_FDB_ptr!=NULL) {
     while (T1_FDB_ptr[i]!=NULL) {
       free(T1_FDB_ptr[i]);
-      T1_FDB_ptr[i]=NULL;
+      T1_FDB_ptr[i++]=NULL;
     }
     free( T1_FDB_ptr);
+    T1_FDB_ptr=NULL;
+  }
+  i=0;
+  if (T1_FDBXLFD_ptr!=NULL) {
+    while (T1_FDBXLFD_ptr[i]!=NULL) {
+      free(T1_FDBXLFD_ptr[i]);
+      T1_FDBXLFD_ptr[i++]=NULL;
+    }
+    free( T1_FDBXLFD_ptr);
+    T1_FDBXLFD_ptr=NULL;
   }
   /* indicate t1lib non-initialized */
   pfab_no=-1;
   afm_no=-1;
   enc_no=-1;
   fdb_no=-1;
+  fdbxlfd_no=-1;
   
   return;
 }
@@ -242,7 +265,7 @@ int intT1_ScanConfigFile( void)
   env_str=getenv(ENV_CONF_STRING);
   linecnt=1;
 
-  if (env_str==NULL) {
+  if (!env_str) {
     /* environment variable not set, try to open default file
        in user's home directory and afterwards global config file */
     if ((usershome=getenv("HOME"))!=NULL) {
@@ -285,7 +308,7 @@ int intT1_ScanConfigFile( void)
       }
       else{
 	sprintf( err_warn_msg_buf, "Using %s as Configfile (global)",
-		 cnffilepath);
+		 globalcnffilepath);
 	T1_PrintLog( "ScanConfigFile()", err_warn_msg_buf, T1LOG_STATISTIC);
       }
     }
@@ -358,7 +381,7 @@ int intT1_ScanConfigFile( void)
       idestP=&enc_no;
       curr_key=(char*)enc_key;
     }
-    else if (strncmp( "TYPE1", &linebuf[j], 5)==0) {
+    else if (strncmp( pfab_key, &linebuf[j], 5)==0) {
       /* setup target */
       destP=&T1_PFAB_ptr;
       idestP=&pfab_no;
@@ -370,6 +393,23 @@ int intT1_ScanConfigFile( void)
       idestP=&afm_no;
       curr_key=(char*)afm_key;
     }
+    else if (strncmp( fdbxlfd_key, &linebuf[j], 16)==0) {
+      /* The handling here is somewhat specific. XLFD font database
+	 specifications may coexist with standard font database
+	 specification. However, if the standard font database is
+	 the default value, an existing XLFD specification clears
+	 this default value. Let this precede the standard fdb because
+	 otherwise, this code would never be reached. */
+      if (fdb_no==0) { /* default paths are currently setup, get rid of them */
+	free(T1_FDB_ptr[0]);
+	T1_FDB_ptr[0]=NULL;
+      }
+      
+      /* setup target */
+      destP=&T1_FDBXLFD_ptr;
+      idestP=&fdbxlfd_no;
+      curr_key=(char*)fdbxlfd_key;
+    }
     else if (strncmp( fdb_key, &linebuf[j], 12)==0) {
       /* setup target */
       destP=&T1_FDB_ptr;
@@ -386,7 +426,10 @@ int intT1_ScanConfigFile( void)
     if (ignoreline==0) { 
       /* Check for an explicitly assigned value */
       if (*idestP==0) { /* default paths are currently setup, get rid of them */
-	free((*destP)[0]);
+	if ((*destP)[0]!=NULL) {
+	  free((*destP)[0]);
+	  (*destP)[0]=NULL;
+	}
       }
       else { /* append to existing paths */
 	T1_PrintLog( "ScanConfigFile()",
@@ -558,7 +601,7 @@ char *intT1_Env_GetCompletePath( char *F
     /* cut a trailing directory separator */
     j=strlen(pathbuf);
     if (pathbuf[j-1]==DIRECTORY_SEP_CHAR)
-      pathbuf[j--]='\0';
+      pathbuf[--j]='\0';
     /* Add the directory separator: */
 #ifdef VMS
     { char *p= strrchr(pathbuf, DIRECTORY_SEP_CHAR);
@@ -567,7 +610,24 @@ char *intT1_Env_GetCompletePath( char *F
     } 
 #endif 
     strcat( pathbuf, DIRECTORY_SEP);
-    /* And finally the filename: */
+    /* And finally the filename.
+       The following is fix against a vulnerability given by passing in
+       large filenames, cf.:
+
+           http://www.securityfocus.com/bid/25079
+
+       or
+
+           http://packetstormsecurity.nl/0707-advisories/t1lib.txt
+
+       If current pathbuf + StrippedName + 1 byte for NULL is bigger than
+       pathbuf log a warning and try next pathbuf */
+    if ( strlen(pathbuf) + strlen(StrippedName) + 1 > sizeof(pathbuf) ) {
+      T1_PrintLog( "intT1_Env_GetCompletePath()", "Omitting suspicious long candidate path in order to prevent buffer overflow.",
+		   T1LOG_WARNING);
+      i++;
+      continue;
+    }
     strcat( pathbuf, StrippedName);
     
     /* Check for existence of the path: */
@@ -620,7 +680,7 @@ int T1_SetFileSearchPath( int type, char
 
   /* We do not allow to change the searchpath if the database already
      contains one or more entries. */
-  if (T1_Get_no_fonts()>0){
+  if (T1_GetNoFonts()>0){
     sprintf( err_warn_msg_buf, "Path %s not set, database is not empty",
 	     pathname);
     T1_PrintLog( "T1_SetFileSearchPath()", err_warn_msg_buf,
@@ -769,15 +829,14 @@ int T1_AddToFileSearchPath( int pathtype
 {
   int i;
   int pathlen;
-  char* newpath;
+  char* newpath = NULL;
   int nofonts;
   
   
-  
   if (pathname==NULL)
     return(-1);
 
-  nofonts=T1_Get_no_fonts();
+  nofonts=T1_GetNoFonts();
   
   pathlen=strlen(pathname);
   
@@ -895,6 +954,11 @@ int T1_AddToFileSearchPath( int pathtype
     }
     T1_ENC_ptr[enc_no]=NULL;
   }
+  
+  /* Copy new path to where it belongs ... */
+  if (newpath)
+    strcpy(newpath, pathname);
+  
   return(0);
   
 }
@@ -953,7 +1017,7 @@ int T1_SetFontDataBase( char *filename)
   fdb_no=1;
 
   /* Load database immediately if t1lib already is initailzed */
-  if (CheckForInit()==0) {
+  if (T1_CheckForInit()==0) {
     if ((result=intT1_scanFontDBase(T1_FDB_ptr[0]))==-1) {
       T1_PrintLog( "T1_AddFontDataBase()", "Fatal error scanning Font Database File %s (T1_errno=%d)",
 		   T1LOG_WARNING, T1_FDB_ptr[0], T1_errno);
@@ -1011,7 +1075,7 @@ int T1_AddFontDataBase( int mode, char *
   }
   /* Insert the new database. If t1lib is already initialzed, the database can only
      be appended. Otherwise. prepending is also possible.*/
-  if ((mode & T1_PREPEND_PATH) && (CheckForInit()!=0) ) { /* prepend */
+  if ((mode & T1_PREPEND_PATH) && (T1_CheckForInit()!=0) ) { /* prepend */
     i=fdb_no-2;
     while (i>=0) {
       T1_FDB_ptr[i+1]=T1_FDB_ptr[i];
@@ -1022,7 +1086,7 @@ int T1_AddFontDataBase( int mode, char *
   }
   else { /* append */
     T1_FDB_ptr[fdb_no-1]=newpath;
-    if (CheckForInit()==0) {
+    if (T1_CheckForInit()==0) {
       if ((result=intT1_scanFontDBase(T1_FDB_ptr[fdb_no-1]))==-1) {
 	T1_PrintLog( "T1_AddFontDataBase()", "Fatal error scanning Font Database File %s (T1_errno=%d)",
 		     T1LOG_WARNING, T1_FDB_ptr[fdb_no-1], T1_errno);
@@ -1036,5 +1100,144 @@ int T1_AddFontDataBase( int mode, char *
   return result;
   
 }
+
+
+
+/* T1_SetFontDataBaseXLFD(): Set a new name for the XLFD font database. It
+   replaces the default name (which is empty and any names specified
+   previously with this function.
+   Return value: 0 if OK, and -1 if filename not valid or an allocation
+   error occurred */
+int T1_SetFontDataBaseXLFD( char *filename)
+{
+  int pathlen;
+  int i;
+  int result=0;
+  
+  
+  /* check filename */
+  if (filename==NULL) {
+    T1_errno=T1ERR_INVALID_PARAMETER;
+    return -1;
+  }
+
+  /* this function must be called before any font is in the database, that is, usually,
+     before initialization! */
+  if ( pFontBase!=NULL && pFontBase->no_fonts>0) {
+    T1_errno=T1ERR_OP_NOT_PERMITTED;
+    return -1;
+  }
+
+  
+  pathlen=strlen(filename)+1;
+  /* Throw away a possibly existing font database-statement */
+  if (fdbxlfd_no==-1) {  
+    T1_FDBXLFD_ptr=NULL; /* realloc() will do a malloc() */
+  }
+  else { 
+    /* throw away current paths */
+    i=0;
+    while (T1_FDBXLFD_ptr[i]!=NULL) {
+      free (T1_FDBXLFD_ptr[i++]);
+    }
+  }
+
+  if ((T1_FDBXLFD_ptr=(char**)realloc( T1_FDBXLFD_ptr, 2*sizeof(char*)))==NULL) {
+    T1_errno=T1ERR_ALLOC_MEM;
+    return -1;
+  }
+  
+  if ((T1_FDBXLFD_ptr[0]=(char*)malloc(pathlen*sizeof(char)))==NULL) {
+    T1_errno=T1ERR_ALLOC_MEM;
+    return -1;
+  }
+  strcpy( T1_FDBXLFD_ptr[0], filename);
+  T1_FDBXLFD_ptr[1]=NULL;
+  fdb_no=1;
+
+  /* Load XLFD database immediately if t1lib already is initailzed */
+  if (T1_CheckForInit()==0) {
+    if ((result=intT1_scanFontDBaseXLFD(T1_FDBXLFD_ptr[0]))==-1) {
+      T1_PrintLog( "T1_AddFontDataBaseXLFD()", "Fatal error scanning XLFD Font Database File %s (T1_errno=%d)",
+		   T1LOG_WARNING, T1_FDBXLFD_ptr[0], T1_errno);
+    }
+    if (result>-1)
+      pFontBase->no_fonts+=result;
+    result=pFontBase->no_fonts;
+  }
+  return result;
+  
+}
+
+
+/* T1_AddFontDataBaseXLFD(): Add a new XLFD font database file to the list. If
+   the lib is already initialzed, then the new database is immediately loaded.
+   Otherwise it is simply appended to the list and loaded at the time of
+   initialization.
+   Returns: -1    an error occured
+             0    successfully inserted but not loaded because lib not initilized
+	     n>0  the highest defined FontID
+*/
+int T1_AddFontDataBaseXLFD( int mode, char *filename) 
+{
+  int i;
+  int pathlen;
+  int result=0;
+  char* newpath;
+  
+  
+  if (filename==NULL) {
+    T1_errno=T1ERR_INVALID_PARAMETER;
+    return(-1);
+  }
+  
+  pathlen=strlen(filename);
+  
+  /* Allocate memory for string */
+  if ((newpath=(char*)malloc( (pathlen+1)*sizeof(char)))==NULL)  {
+    T1_errno=T1ERR_ALLOC_MEM;
+    return(-1);
+  }
+  strcpy( newpath, filename);
+  /* Check for and handle the existing path configuration */
+  if (fdb_no==0) {   /* defauls setup, free the path */
+    free( T1_FDB_ptr[0]);
+  }
+  if (fdbxlfd_no==-1) {  /* not initialized! */
+    fdbxlfd_no=0;
+    T1_FDBXLFD_ptr=NULL; /* realloc() will do the malloc()! */
+  }
+  
+  if ((T1_FDBXLFD_ptr=(char**)realloc( T1_FDBXLFD_ptr, (++fdbxlfd_no+1)*sizeof(char*)))==NULL) {
+    T1_errno=T1ERR_ALLOC_MEM;
+    return(-1);
+  }
+  /* Insert the new database. If t1lib is already initialzed, the database can only
+     be appended. Otherwise. prepending is also possible.*/
+  if ((mode & T1_PREPEND_PATH) && (T1_CheckForInit()!=0) ) { /* prepend */
+    i=fdbxlfd_no-2;
+    while (i>=0) {
+      T1_FDBXLFD_ptr[i+1]=T1_FDBXLFD_ptr[i];
+      i--;
+    }
+    T1_FDBXLFD_ptr[0]=newpath;
+    result=0;
+  }
+  else { /* append */
+    T1_FDBXLFD_ptr[fdbxlfd_no-1]=newpath;
+    if (T1_CheckForInit()==0) {
+      if ((result=intT1_scanFontDBaseXLFD(T1_FDBXLFD_ptr[fdbxlfd_no-1]))==-1) {
+	T1_PrintLog( "T1_AddFontDataBase()", "Fatal error scanning Font Database File %s (T1_errno=%d)",
+		     T1LOG_WARNING, T1_FDBXLFD_ptr[fdbxlfd_no-1], T1_errno);
+      }
+      if (result>-1)
+	pFontBase->no_fonts+=result;
+      result=pFontBase->no_fonts;
+    }
+  }
+  T1_FDBXLFD_ptr[fdbxlfd_no]=NULL;
+  return result;
+  
+}
 
 
Index: grace/T1lib/t1lib/t1env.h
===================================================================
--- grace.orig/T1lib/t1lib/t1env.h
+++ grace/T1lib/t1lib/t1env.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1env.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-09-26
+  ----- Date:        2005-05-16
   ----- Description: This file is part of the t1-library. It contains
                      declarations and definitions for t1env.c
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -37,6 +37,8 @@ int T1_AddToFileSearchPath( int pathtype
 char *T1_GetFileSearchPath( int type);
 int T1_SetFontDataBase( char *filename);
 int T1_AddFontDataBase( int mode, char *filename);
+int T1_SetFontDataBaseXLFD( char *filename);
+int T1_AddFontDataBaseXLFD( int mode, char *filename);
 
 #else
 
@@ -49,6 +51,8 @@ extern int T1_AddToFileSearchPath( int p
 extern char *T1_GetFileSearchPath( int type);
 extern int T1_SetFontDataBase( char *filename);
 extern int T1_AddFontDataBase( int mode, char *filename);
+extern int T1_SetFontDataBaseXLFD( char *filename);
+extern int T1_AddFontDataBaseXLFD( int mode, char *filename);
 
 #endif
 
Index: grace/T1lib/t1lib/t1extern.h
===================================================================
--- grace.orig/T1lib/t1lib/t1extern.h
+++ grace/T1lib/t1lib/t1extern.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1extern.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-03
+  ----- Date:        2005-05-16
   ----- Description: This file is part of the t1-library. It contains
                      external declarations used by the t1-library.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -89,6 +89,7 @@ extern char **T1_PFAB_ptr;
 extern char **T1_AFM_ptr;
 extern char **T1_ENC_ptr;
 extern char **T1_FDB_ptr;
+extern char **T1_FDBXLFD_ptr;
 
 /* We use a uchar buffer for error and warning messages: */
 extern char err_warn_msg_buf[1024];
Index: grace/T1lib/t1lib/t1finfo.c
===================================================================
--- grace.orig/T1lib/t1lib/t1finfo.c
+++ grace/T1lib/t1lib/t1finfo.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1finfo.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-06-10
+  ----- Date:        2005-05-01
   ----- Description: This file is part of the t1-library. It contains
                      functions for accessing afm-data and some other
 		     fontinformation data.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -51,6 +51,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -89,7 +90,7 @@ int T1_GetKerning( int FontID, char char
   
 
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0);
   }
@@ -131,7 +132,7 @@ int T1_GetCharWidth( int FontID, char ch
   uchar1=(unsigned char) char1;
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0);
   }
@@ -195,7 +196,7 @@ BBox T1_GetCharBBox( int FontID, char ch
   uchar1=(unsigned char) char1;
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NullBBox);
   }
@@ -228,7 +229,7 @@ BBox T1_GetCharBBox( int FontID, char ch
 		   pFontBase->pFontArray[FontID].pFontEnc,
 		   (int) uchar1, &mode,
 		   pFontBase->pFontArray[FontID].pType1Data,
-		   DO_RASTER);
+		   DO_RASTER,0.0f);
     /* Read out bounding box */
     ResultBox.llx =area->xmin;
     ResultBox.urx =area->xmax;
@@ -273,7 +274,7 @@ BBox T1_GetCharBBox( int FontID, char ch
    is not yet loaded into memory. or an invalid ID has been specified. */
 float T1_GetUnderlinePosition( int FontID)
 {
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -288,7 +289,7 @@ float T1_GetUnderlinePosition( int FontI
    is not yet loaded into memory. or an invalid ID has been specified. */
 float T1_GetUnderlineThickness( int FontID)
 {
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -302,7 +303,7 @@ float T1_GetUnderlineThickness( int Font
    is not yet loaded into memory. or an invalid ID has been specified. */
 float T1_GetItalicAngle( int FontID)
 {
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -317,7 +318,7 @@ float T1_GetItalicAngle( int FontID)
    is not yet loaded into memory. or an invalid ID has been specified. */
 int T1_GetIsFixedPitch( int FontID)
 {
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -334,7 +335,7 @@ char *T1_GetFontName( int FontID)
 {
   static char fontname[MAXPSNAMELEN];
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -356,7 +357,7 @@ char *T1_GetFullName( int FontID)
 {
   static char fullname[MAXPSNAMELEN];
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -378,7 +379,7 @@ char *T1_GetFamilyName( int FontID)
 {
   static char familyname[MAXPSNAMELEN];
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -400,7 +401,7 @@ char *T1_GetWeight( int FontID)
 {
   static char weight[128];
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -422,7 +423,7 @@ char *T1_GetVersion( int FontID)
 {
   static char version[2048];
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -444,7 +445,7 @@ char *T1_GetNotice( int FontID)
 {
   static char notice[2048];
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -469,7 +470,7 @@ char *T1_GetCharName( int FontID, char c
   char *c1;
   
 
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -518,7 +519,7 @@ int T1_QueryLigs( int FontID,  char char
   int i,j;
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -600,7 +601,7 @@ int T1_GetEncodingIndex( int FontID, cha
   psobj *objptr;
   
   
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -654,7 +655,7 @@ int *T1_GetEncodingIndices( int FontID,
   static int indices[257];
 
   
-  if (CheckForFontID(FontID)!=1) {
+  if (T1_CheckForFontID(FontID)!=1) {
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   }
@@ -711,7 +712,7 @@ int T1_GetStringWidth( int FontID, char
   ustring=(unsigned char *) string;
   
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0);
@@ -733,52 +734,76 @@ int T1_GetStringWidth( int FontID, char
   else        /* use value given on command line */
     no_chars=len;
 
-  /* Allocate room for temporary arrays of kerning and width arrays: */
-  kern_pairs=(int *)calloc(no_chars -1, sizeof(int));
-  if (kern_pairs==NULL){
-    T1_errno=T1ERR_ALLOC_MEM;
-    return(0);
-  }
-  charwidths=(int *)calloc(no_chars, sizeof(int));
-  if (charwidths==NULL){
-    T1_errno=T1ERR_ALLOC_MEM;
-    return(0);
-  }
+  switch (no_chars) {
+    case 0:
+      /* Empty string has width 0 */
+      stringwidth=0;
+      break;
+
+    case 1:
+      /* Width of string with 1 character is the width of that character.
+         If the character is a space, adjust by the value of spaceoff.
+         */
+      stringwidth=T1_GetCharWidth(FontID,ustring[0]);
+      if (ustring[0]==pFontBase->pFontArray[FontID].space_position)
+        stringwidth+=spaceoff;
+      break;
+
+    default:
+      /* Two or more characters.  Add widths of characters and adjust by
+         the adjustment widths for any kerning pairs.  For spaces, use the
+         width of the space character in the font adjusted by the value of
+         spaceoff.
+         */
+    
+      /* Allocate room for temporary arrays of kerning and width arrays: */
+      kern_pairs=(int *)calloc(no_chars -1, sizeof(int));
+      if (kern_pairs==NULL){
+        T1_errno=T1ERR_ALLOC_MEM;
+        return(0);
+      }
+      charwidths=(int *)calloc(no_chars, sizeof(int));
+      if (charwidths==NULL){
+        T1_errno=T1ERR_ALLOC_MEM;
+        return(0);
+      }
   
-  /* If kerning is requested, get kerning amounts and fill the array: */
-  if (kerning){
-    for (i=0; i<no_chars -1; i++){
-      kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]);
-    }
-  }
+      /* If kerning is requested, get kerning amounts and fill the array: */
+      if (kerning){
+        for (i=0; i<no_chars -1; i++){
+          kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]);
+        }
+      }
   
-  /* Compute the correct spacewidth value (in charspace units): */
-  spacewidth=T1_GetCharWidth(FontID,pFontBase->pFontArray[FontID].space_position)+spaceoff;
+      /* Compute the correct spacewidth value (in charspace units): */
+      spacewidth=T1_GetCharWidth(FontID,pFontBase->pFontArray[FontID].space_position)+spaceoff;
   
-  /* Fill the width-array:  */
-  for (i=0; i<no_chars; i++){
-    if (ustring[i]==pFontBase->pFontArray[FontID].space_position)
-      charwidths[i]=(int)spacewidth;
-    else
-      charwidths[i]=T1_GetCharWidth(FontID,ustring[i]);
-  }
+      /* Fill the width-array:  */
+      for (i=0; i<no_chars; i++){
+        if (ustring[i]==pFontBase->pFontArray[FontID].space_position)
+          charwidths[i]=(int)spacewidth;
+        else
+          charwidths[i]=T1_GetCharWidth(FontID,ustring[i]);
+      }
   
-  /* Accumulate width: */
-  stringwidth=0;
-  for (i=0; i<no_chars-1; i++){
-    stringwidth += kern_pairs[i];
-  }
-  for (i=0; i<no_chars; i++){
-    stringwidth += charwidths[i];
-  }
+      /* Accumulate width: */
+      stringwidth=0;
+      for (i=0; i<no_chars-1; i++){
+        stringwidth += kern_pairs[i];
+      }
+      for (i=0; i<no_chars; i++){
+        stringwidth += charwidths[i];
+      }
   
-  /* free memory: */
-  free( charwidths);
-  free( kern_pairs);
+      /* free memory: */
+      free( charwidths);
+      free( kern_pairs);
+
+      break;
+  }
 
   /* .. and return result: */
   return( stringwidth);
-
 }
 
     
@@ -808,7 +833,7 @@ BBox T1_GetStringBBox( int FontID, char
 
   
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NullBBox);
@@ -902,7 +927,7 @@ METRICSINFO T1_GetMetricsInfo( int FontI
 
 
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(metrics);
@@ -977,7 +1002,7 @@ BBox T1_GetFontBBox( int FontID)
   struct ps_obj *obj;
 
   /* return Null-box if font not loaded */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(outbox);
   }
@@ -1019,7 +1044,7 @@ char **T1_GetAllCharNames( int FontID)
   int bufmemsize=0;
   
   /* return NULL if font not loaded */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( NULL);
   }
@@ -1077,7 +1102,7 @@ int T1_GetNoKernPairs( int FontID)
 {
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( -1);
   }
@@ -1116,7 +1141,7 @@ int T1_GetNoCompositeChars( int FontID)
 {
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( -1);
   }
@@ -1151,7 +1176,7 @@ int T1_QueryCompositeChar( int FontID, c
   uchar1=char1;
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( -2);
   }
@@ -1184,7 +1209,7 @@ T1_COMP_CHAR_INFO *T1_GetCompCharData( i
   unsigned char uchar1;
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( cci);
   }
@@ -1253,7 +1278,7 @@ T1_COMP_CHAR_INFO *T1_GetCompCharDataByI
   int i;
   
   /* Check whether font is loaded: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( cci);
   }
@@ -1312,7 +1337,7 @@ int T1_IsInternalChar( int FontID, char
   int len, i, j;
   
   /* return NULL if font not loaded */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return( -1);
   }
Index: grace/T1lib/t1lib/t1global.h
===================================================================
--- grace.orig/T1lib/t1lib/t1global.h
+++ grace/T1lib/t1lib/t1global.h
@@ -1,7 +1,7 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1global.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2005-05-16
   ----- Description: This file is part of the t1-library. It contains
                      global declarations used by the t1-library.
   ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
@@ -99,6 +99,7 @@ char** T1_PFAB_ptr=NULL;
 char** T1_AFM_ptr=NULL;
 char** T1_ENC_ptr=NULL;
 char** T1_FDB_ptr=NULL;
+char** T1_FDBXLFD_ptr=NULL;
 
 /* We use a uchar buffer for error and warning messages: */
 char err_warn_msg_buf[1024];
Index: grace/T1lib/t1lib/t1lib.h
===================================================================
--- grace.orig/T1lib/t1lib/t1lib.h
+++ grace/T1lib/t1lib/t1lib.h
@@ -1,12 +1,12 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1lib.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-03
+  ----- Date:        2004-12-19
   ----- Description: This file is part of the t1-library. It must be
                      included by the user of the t1lib. It contains
 		     function declarations and some basic data types, the
 		     user must deal with.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2004.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -38,6 +38,15 @@
 extern "C" {
 #endif
 
+/* Version information filled in by configure */
+#define T1LIB_VERSION            5
+#define T1LIB_REVISION           1
+#define T1LIB_PATCHLEVEL         2
+#define T1LIB_VERSIONSTRING      "5.1.2"
+
+/* Data Type information filled in by configure. */
+typedef short T1_int16;
+typedef int T1_int32;
 
 /* the data structure which contains the character bitmap description */
 typedef struct
@@ -165,6 +174,7 @@ extern int T1_errno;
 #define T1ERR_NO_AFM_DATA             16
 #define T1ERR_X11                     17
 #define T1ERR_COMPOSITE_CHAR          18
+#define T1ERR_SCAN_ENCODING           19
 
 
 /* Flags to control the rasterizer */
@@ -182,14 +192,14 @@ extern int T1_errno;
 /* definitions for outline handling */
 #define   FRACTBITS     16   /* number of fractional bits in 'fractpel'      */
 /* From/to conversion of pels/fractpels */
-#define   T1_TOPATHPOINT(p)      (((long)p)<<FRACTBITS)
+#define   T1_TOPATHPOINT(p)      (((T1_int32)p)<<FRACTBITS)
 #define   PPHALF                 (1<<(FRACTBITS-1))
 #define   T1_NEARESTPOINT(fp)    (((fp)+PPHALF)>>FRACTBITS)
 
 /* A fractional point */
 typedef struct {
-  long x;
-  long y;
+  T1_int32 x;
+  T1_int32 y;
 } T1_PATHPOINT;
 
 
@@ -264,17 +274,13 @@ extern int T1_CloseLib( void);
 extern int T1_AddFont( char *fontfilename);
 extern void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...);
 extern void T1_SetLogLevel( int level);
-extern int CheckForInit(void);
-extern int CheckForFontID( int FontID);
-extern int test_for_t1_file( char *buffer );
+extern int T1_CheckForInit(void);
+extern int T1_CheckForFontID( int FontID);
 extern char *T1_GetFontFileName( int FontID);
-extern int  T1_Get_no_fonts(void);
+extern int  T1_GetNoFonts(void);
 extern int T1_SetDeviceResolutions( float x_res, float y_res);
 extern int T1_CopyFont( int FontID);
 extern int T1_QueryX11Support( void);
-extern void bin_dump_c(unsigned char value);
-extern void bin_dump_s(unsigned short value);
-extern void bin_dump_l(unsigned long value);
 extern int T1_CheckEndian(void);
 extern int T1_SetBitmapPad( int pad);
 extern int T1_GetBitmapPad( void);
@@ -284,6 +290,7 @@ extern char *T1_GetAfmFileName( int Font
 extern int T1_SetAfmFileName( int FontId, char *afm_name);
 extern char *T1_GetFontFilePath( int FontID);
 extern char *T1_GetAfmFilePath( int FontID);
+extern const char *T1_StrError( int t1err);
 
 /* from t1delete.c */
 extern int T1_DeleteSize( int FontID, float size);
@@ -345,10 +352,7 @@ extern int T1_IsInternalChar( int FontID
 
 /* from t1load.c */
 extern int T1_LoadFont( int FontID);
-extern int openFontMetricsFile( int FontID);
-extern void *CreateNewFontSize( int FontID, float size, int aa);
-extern void *GetLastFontSize( int FontID);
-extern void *QueryFontSize( int FontID, float size, int aa);
+extern void *T1_QueryFontSize( int FontID, float size, int aa);
 
 /* from t1set.c */
 extern GLYPH *T1_SetChar( int FontID, char charcode, 
@@ -356,6 +360,9 @@ extern GLYPH *T1_SetChar( int FontID, ch
 extern GLYPH *T1_SetString( int FontID, char *string, int len,
 			    long spaceoff, int modflag,
 			    float size, T1_TMATRIX *transform);
+extern GLYPH* T1_SetRect( int FontID, float size,
+			  float width, float height,
+			  T1_TMATRIX *transform);
 extern GLYPH *T1_CopyGlyph(GLYPH *glyph);
 extern void T1_DumpGlyph( GLYPH *glyph);
 extern GLYPH *T1_ConcatGlyphs( GLYPH *glyph1, GLYPH *glyph2,
@@ -384,6 +391,12 @@ extern T1_TMATRIX *T1_ExtendVMatrix( T1_
 extern T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix,
 				       double cxx, double cyx,
 				       double cxy, double cyy);
+extern int T1_StrokeFont( int FontID, int dostroke);
+extern int T1_SetStrokeFlag( int FontID);
+extern int T1_ClearStrokeFlag( int FontID);
+extern int T1_GetStrokeMode( int FontID);
+extern int T1_SetStrokeWidth( int FontID, float strokewidth);
+extern float T1_GetStrokeWidth( int FontID);
 
 
 /* from t1aaset.c */
@@ -392,6 +405,9 @@ extern GLYPH *T1_AASetChar( int FontID,
 extern GLYPH *T1_AASetString( int FontID, char *string, int len,
 			      long spaceoff, int modflag,
 			      float size, T1_TMATRIX *transform);
+extern GLYPH* T1_AASetRect( int FontID, float size,
+			    float width, float height,
+			    T1_TMATRIX *transform);
 extern int T1_AASetGrayValues(unsigned long white,
 			      unsigned long gray75,
 			      unsigned long gray50,
Index: grace/T1lib/t1lib/t1libx.h
===================================================================
--- /dev/null
+++ grace/T1lib/t1lib/t1libx.h
@@ -0,0 +1,93 @@
+/*--------------------------------------------------------------------------
+  ----- File:        t1libx.h
+  ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
+  ----- Date:        2003-01-02
+  ----- Description: This file is part of the t1-library. It must be
+                     included by the user of the t1lib. It contains
+		     function declarations for the X11 wrapper.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003.
+                     As of version 0.5, t1lib is distributed under the
+		     GNU General Public Library Lincense. The
+		     conditions can be found in the files LICENSE and
+		     LGPL, which should reside in the toplevel
+		     directory of the distribution.  Please note that 
+		     there are parts of t1lib that are subject to
+		     other licenses:
+		     The parseAFM-package is copyrighted by Adobe Systems
+		     Inc.
+		     The type1 rasterizer is copyrighted by IBM and the
+		     X11-consortium.
+  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
+  ----- Credits:     I want to thank IBM and the X11-consortium for making
+                     their rasterizer freely available.
+		     Also thanks to Piet Tutelaers for his ps2pk, from
+		     which I took the rasterizer sources in a format
+		     independent from X11.
+                     Thanks to all people who make free software living!
+--------------------------------------------------------------------------*/
+
+
+#ifndef T1LIBX_H_INCLUDED
+
+#define T1LIBX_H_INCLUDED
+
+
+#ifndef _XLIB_H_
+#include <X11/Xlib.h>
+#endif
+
+
+#define T1LIB_X11_SUPPORT
+
+/* For paint mode of X-rastering functions */
+#define T1_OPAQUE              0x1
+#define T1_TRANSPARENT         0x0
+
+
+/* type definitions, needed by the user: */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+/* from t1x11.c */
+extern int T1_SetX11Params( Display *display,
+			    Visual *visual,
+			    unsigned int depth,
+			    Colormap colormap);
+extern GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x, int y,
+			   int FontID, char charcode,
+			   float size, T1_TMATRIX *transform);
+extern GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x, int y,
+			     int FontID, char *string, int len,
+			     long spaceoff, int modflag,
+			     float size, T1_TMATRIX *transform);
+extern GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+			   int FontID, float size,
+			   float width, float height,
+			   T1_TMATRIX *transform);
+extern GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x, int y,
+			     int FontID, char charcode,
+			     float size, T1_TMATRIX *transform);
+extern GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x, int y,
+			       int FontID, char *string, int len,
+			       long spaceoff, int modflag,
+			       float size, T1_TMATRIX *transform);
+extern GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+			     int FontID, float size,
+			     float width, float height,
+			     T1_TMATRIX *transform);
+extern int T1_ComputeAAColorsX( unsigned long fg,
+				unsigned long bg,
+				int nolevels);
+extern int T1_GetDepthOfDrawable( Drawable drawable);
+extern void T1_LogicalPositionX( int pos_switch);
+extern XImage *T1_XImageFromGlyph( GLYPH *pglyph);
+
+  
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* T1LIBX_H_INCLUDED */
Index: grace/T1lib/t1lib/t1load.c
===================================================================
--- grace.orig/T1lib/t1lib/t1load.c
+++ grace/T1lib/t1lib/t1load.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1load.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-03
+  ----- Date:        2007-12-23
   ----- Description: This file is part of the t1-library. It contains
                      functions for loading fonts  and for managing size
 		     dependent data.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2007. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -30,6 +30,15 @@
 
 #define ANSI_REALLOC_VM  
 
+/* Note: On some systems, like e.g. my Linux box, realloc() frequently returns
+         the identical pointer, if the memory chunk is *decreased* in size. As
+	 a consequence, pointer shifting (as implemented below) would never
+	 actually appear. The following definition enforces pointer shifting,
+	 and hence allows to check pointer shifting on every system. Do not
+	 activate this, it is meant for testing only!
+*/
+/* #define ANSI_REALLOC_ENFORCE_POINTERSHIFTING */
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -53,6 +62,7 @@
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
 #include "../type1/blues.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -77,7 +87,7 @@ extern char not_def[];            /* for
 
 int T1_LoadFont( int FontID)
 {
-  int i, j, k, l, m;
+  int i, j, k, l, m, n;
   char *FileName, *FileNamePath;
   int mode;  /* This is used by the type1-library for error reporting */   
   char *charname;
@@ -100,13 +110,13 @@ int T1_LoadFont( int FontID)
   int char1, char2;
   
   
-  if (CheckForInit()){
+  if (T1_CheckForInit()){
     T1_errno=T1ERR_OP_NOT_PERMITTED;
     return(-1);
   }
   
 
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i==1)
     return(0);      /* Font already loaded */
   if (i==-1){
@@ -150,6 +160,40 @@ int T1_LoadFont( int FontID)
   free(FileNamePath);
 
   
+  /* Set some default for FontBBox and Encoding if the font does not provide
+     correct data. Strictly taken, these fonts do not adhere to the Type1
+     specification. However, it is easy to work around and find reasonable
+     defaults. This solution has been proposed by the Debian community (see
+     http://bugs.debian.org/313236). */
+  /* 1. FontBBox. We set default values of 0 which is recommended by Adobe
+     in cases where the font does not make use of the SEAC primitive. Later on,
+     if AFM fallback info is computed, these settings might be overwritten with
+     meaningful values. */
+  if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP == NULL) {
+    if ((pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP =  
+	 (psobj *)vm_alloc(4 * sizeof(psobj))) == NULL) {
+      T1_PrintLog( "T1_LoadFont()", "Error allocating memory for fontbbox objects (FontID=%d)", 
+		   T1LOG_ERROR, FontID);
+      T1_errno=T1ERR_ALLOC_MEM;
+      return(-1);
+    }
+    for (n = 0; n < 4; n++) {
+      pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[n].type = OBJ_INTEGER;
+      pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[n].len = 0;
+      pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[n].data.integer = 0;
+    }
+    T1_PrintLog( "T1_LoadFont()", "Missing FontBBox, adding a trivial one in order to avoid crashes (FontID=%d)", 
+		 T1LOG_WARNING, FontID);
+  }
+  /* 2. Encoding. In this case, we simply fallback to Standard Encoding. */
+  if (pFontBase->pFontArray[FontID].pFontEnc == NULL && 
+      pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP == NULL) {
+    pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.valueP = (char *) StdEncArrayP;
+    T1_PrintLog( "T1_LoadFont()", "Missing, invalid  or undefined Encoding, setting up Standard Encoding in order to avoid crashes (FontID=%d)", 
+		 T1LOG_WARNING, FontID);
+  }
+  
+  
   /* Store the base address of virtual memory and realloc in order not
      to waste too much memory: */
   pFontBase->pFontArray[FontID].vm_base=vm_base; 
@@ -158,7 +202,12 @@ int T1_LoadFont( int FontID)
   /* Get size of VM, ... */
   tmp_size=((unsigned long)vm_used - (unsigned long)vm_base); 
   /* ... realloc to that size ... */
-  tmp_ptr=(char *)realloc(vm_base,  tmp_size); 
+#ifdef ANSI_REALLOC_ENFORCE_POINTERSHIFTING
+  tmp_ptr=(char *)malloc( tmp_size);
+  memcpy( tmp_ptr, vm_base, tmp_size);
+#else
+  tmp_ptr=(char *)realloc(vm_base,  tmp_size);
+#endif
   /* ... and shift all pointers refering to that area */
   if (tmp_ptr > vm_base){
     shift= (unsigned long)tmp_ptr - (unsigned long)vm_base;
@@ -211,24 +260,18 @@ int T1_LoadFont( int FontID)
       }
       /* The encoding needs special treatment: */
       if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_ENCODING){
-	/* If a builtin encoding is used, it is sufficient to shift the pointer
-	   to the Encoding since the character-namestrings of builtin encodings
-	   are static and thus located on the heap.
-	   For font-specific encoding, character-namestrings reside in VM and
-	   thus each entry has to be shifted. 
-	   Caution: We still have to shift the builtin encoding-pointer, since
-	   they also point to are located in VM: */
-	ldummy=(long)StdEncArrayP;
-	ldummy +=shift;
-	StdEncArrayP=(psobj *)ldummy;
-	ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP;
-	ldummy +=shift;
-	pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy;
+	/* If builtin StandardEncoding is used, we do nothing here. Standard Encoding
+	   is now located once for all fonts on the heap. For font-specific encodings
+	   we have to move all pointers appropriately, because this is entirely located
+	   in VM */
 	if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP
-	    == StdEncArrayP){ /* Font uses builtin standard encoding */
+	    == StdEncArrayP){ /* Font uses builtin StandardEncoding */
 	  ;
 	} 
 	else{ /* Font-specific encoding */ 
+	  ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP;
+	  ldummy +=shift;
+	  pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy;
 	  for (k=0; k<256; k++){
 	    ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP[k].data.arrayP;
 	    /* The ".notdef" is also static and may not be shifted (Thanks, Derek ;) */
@@ -346,24 +389,18 @@ int T1_LoadFont( int FontID)
       }
       /* The encoding needs special treatment: */
       if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_ENCODING){
-	/* If a builtin encoding is used, it is sufficient to shift the pointer
-	   to the Encoding since the character-namestrings of builtin encodings
-	   are static and thus located on the heap.
-	   For font-specific encoding, character-namestrings reside in VM and
-	   thus each entry has to be shifted. 
-	   Caution: We still have to shift the builtin encoding-pointer, since
-	   they also point to are located in VM: */
-	ldummy=(long)StdEncArrayP;
-	ldummy -=shift;
-	StdEncArrayP=(psobj *)ldummy;
-	ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP;
-	ldummy -=shift;
-	pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy;
+	/* If builtin StandardEncoding is used, we do nothing here. Standard Encoding
+	   is now located once for all fonts on the heap. For font-specific encodings
+	   we have to move all pointers appropriately, because this is entirely located
+	   in VM */
 	if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP
-	     == StdEncArrayP){ /* Font uses builtin encoding */
+	    == StdEncArrayP){ /* Font uses builtin StandardEncoding */
 	  ;
 	} 
 	else{ /* Font-specific encoding */ 
+	  ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP;
+	  ldummy -=shift;
+	  pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy;
 	  for (k=0; k<256; k++){
 	    ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP[k].data.arrayP;
 	    /* The ".notdef" is also static and may not be shifted (Thanks, Derek ;) */
@@ -436,6 +473,11 @@ int T1_LoadFont( int FontID)
 	     (unsigned long)vm_base);
     T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG);
   }
+#ifdef ANSI_REALLOC_ENFORCE_POINTERSHIFTING
+  /* If pointer shifting had been enforced by allocating from
+     scratch using malloc() free the previous vm. */
+  free( vm_base);
+#endif
 #endif
     
   /* Generate a message how much VM the current font consumes */
@@ -608,6 +650,7 @@ int T1_LoadFont( int FontID)
     }
     /* We now create an encoding-specific kerning table which will speed up
        looking for kerning pairs! */
+    pFontBase->pFontArray[FontID].KernMapSize=0;
     /* First, get number of defined kerning pairs: */
     k=pFontBase->pFontArray[FontID].pAFMData->numOfPairs;
     if (k>0){ /* i.e., there are any pairs */
@@ -850,7 +893,7 @@ static int openFontMetricsFile( int Font
 
 
 
-/* CreateNewFontSize( FontID, size): Create a new size "size" of font
+/* T1int_CreateNewFontSize( FontID, size): Create a new size "size" of font
    "FontID" and allocate all data necessary for this. The data
    structure is connected to the linked list of FontSizeDeps for this
    font. Returns a pointer to the newly created FontSizeDeps-struct
@@ -863,7 +906,7 @@ static int openFontMetricsFile( int Font
    2:     low-antialiased bytemaps are stored in this struct
    4:     high-antialiased bytemaps are stored in this struct
    */
-FONTSIZEDEPS *CreateNewFontSize( int FontID, float size, int aa)
+FONTSIZEDEPS *T1int_CreateNewFontSize( int FontID, float size, int aa)
 {
 
   FONTSIZEDEPS *pFontSizeDeps, *pPrev;
@@ -872,7 +915,7 @@ FONTSIZEDEPS *CreateNewFontSize( int Fon
   /* First, get to the last font size in the linked list for this font.
      The following routine returns the address of the last struct in the
      linked list of FONTSIZEDEPS or NULL if none exists. */
-  pFontSizeDeps=GetLastFontSize( FontID);
+  pFontSizeDeps=T1int_GetLastFontSize( FontID);
   pPrev=pFontSizeDeps;
   
   
@@ -939,10 +982,10 @@ FONTSIZEDEPS *CreateNewFontSize( int Fon
   
 
 
-/* QueryFontSize( FontID, size, aa): Search if a requested size of font
+/* T1_QueryFontSize( FontID, size, aa): Search if a requested size of font
    FontID is already existing. If so, it returns a pointer to the
    respective FontSizeDeps-structure,  otherwise NULL is returned: */
-FONTSIZEDEPS *QueryFontSize( int FontID, float size, int aa)
+FONTSIZEDEPS *T1int_QueryFontSize( int FontID, float size, int aa)
 {
   
   FONTSIZEDEPS *link_ptr;
@@ -967,10 +1010,10 @@ FONTSIZEDEPS *QueryFontSize( int FontID,
   
 }
 
-/* FONTSIZEDEPS *GetLastFontSize( FontID): Get the address of the
+/* FONTSIZEDEPS *T1int_GetLastFontSize( FontID): Get the address of the
    last struct in the linked list of FontSizeDeps or NULL if there is
    no existing size dependent data. */
-FONTSIZEDEPS *GetLastFontSize( int FontID)
+FONTSIZEDEPS *T1int_GetLastFontSize( int FontID)
 {
   FONTSIZEDEPS *link_ptr, *result_ptr;
   
Index: grace/T1lib/t1lib/t1load.h
===================================================================
--- grace.orig/T1lib/t1lib/t1load.h
+++ grace/T1lib/t1lib/t1load.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1load.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2002-12-02
   ----- Description: This file is part of the t1-library. It contains
                      declarations and definitions for t1load.c.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2002. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -30,9 +30,9 @@
 
 int T1_LoadFont( int FontID);
 static int openFontMetricsFile( int FontID, int open_sloppy);
-FONTSIZEDEPS *CreateNewFontSize( int FontID, float size, int aa);
-FONTSIZEDEPS *GetLastFontSize( int FontID);
-FONTSIZEDEPS *QueryFontSize( int FontID, float size, int aa);
+FONTSIZEDEPS *T1int_CreateNewFontSize( int FontID, float size, int aa);
+FONTSIZEDEPS *T1int_GetLastFontSize( int FontID);
+FONTSIZEDEPS *T1int_QueryFontSize( int FontID, float size, int aa);
 int fontfcnA( char *env, int *mode, psfont *Font_Ptr);
 static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2);
 extern char *vm_base; /* from fontfcn.c in initfont()! */
@@ -41,8 +41,8 @@ extern char *vm_used; /* from fontfcn.c
 #else
 
 extern int T1_LoadFont( int FontID);
-extern FONTSIZEDEPS *CreateNewFontSize( int FontID, float size, int aa);
-extern FONTSIZEDEPS *GetLastFontSize( int FontID);
-extern FONTSIZEDEPS *QueryFontSize( int FontID, float size, int aa);
+extern FONTSIZEDEPS *T1int_CreateNewFontSize( int FontID, float size, int aa);
+extern FONTSIZEDEPS *T1int_GetLastFontSize( int FontID);
+extern FONTSIZEDEPS *T1int_QueryFontSize( int FontID, float size, int aa);
 
 #endif
Index: grace/T1lib/t1lib/t1misc.h
===================================================================
--- grace.orig/T1lib/t1lib/t1misc.h
+++ grace/T1lib/t1lib/t1misc.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1misc.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-10-03
+  ----- Date:        2004-11-27
   ----- Description: This file is part of the t1-library. It contains
                      some miscellaneous definitions.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2004.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -55,7 +55,13 @@
 
 /* The maximum length of a PostScript name of a font: */
 #define MAXPSNAMELEN 256
-#define T1_MAXPATHLEN   1024
+#ifndef MAXPATHLEN
+#    ifdef PATH_MAX
+#        define MAXPATHLEN   PATH_MAX
+#    else
+#        define MAXPATHLEN   4096
+#    endif
+#endif
 
 /* The default resolution used by the library */
 #define DEFAULT_RES           72.0
@@ -71,7 +77,7 @@
 #if defined(VMS)
 # define DIRECTORY_SEP        "]"
 # define DIRECTORY_SEP_CHAR   ']'
-#elif defined(MSDOS) | defined(_WIN32) | defined(__EMX__) | defined(_MSC_VER)
+#elif defined(MSDOS) | defined(_WIN32) | defined(_MSC_VER)
 # define DIRECTORY_SEP        "\\"
 # define DIRECTORY_SEP_CHAR   '\\'
 #else
@@ -176,6 +182,7 @@
 #define T1ERR_NO_AFM_DATA             16
 #define T1ERR_X11                     17
 #define T1ERR_COMPOSITE_CHAR          18
+#define T1ERR_SCAN_ENCODING           19
 
 
 /* The info_flags meaning */
@@ -183,9 +190,10 @@
 #define AFM_SLOPPY_SUCCESS        (short)0x0002
 #define AFM_SELFGEN_SUCCESS       (short)0x0004
 #define USES_STANDARD_ENCODING    (short)0x0008
+#define RASTER_STROKED            (short)0x0010
+#define CACHE_STROKED             (short)0x0020
 #define FONT_NOCACHING            (short)0x0100
 
-
 #ifndef PI
 #define PI 3.1415927
 #endif
Index: grace/T1lib/t1lib/t1outline.c
===================================================================
--- grace.orig/T1lib/t1lib/t1outline.c
+++ grace/T1lib/t1lib/t1outline.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1outline.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-05-27
+  ----- Date:        2005-05-01
   ----- Description: This file is part of the t1-library. It contains
                      functions for getting glyph outline descriptions of
 		     strings and characters.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -52,8 +52,8 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
-#include "../type1/regions.h"
 #include "../type1/paths.h"
+#include "../type1/regions.h"
 
 
 #include "t1types.h"
@@ -121,7 +121,7 @@ T1_OUTLINE *T1_GetCharOutline( int FontI
 
   
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i==-1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
@@ -141,8 +141,8 @@ T1_OUTLINE *T1_GetCharOutline( int FontI
   
   /* font is now loaded into memory =>
      Check for size: */
-  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
-    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
+  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
+    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
     if (font_ptr==NULL){
       T1_errno=T1ERR_ALLOC_MEM;
       return(NULL);
@@ -175,7 +175,7 @@ T1_OUTLINE *T1_GetCharOutline( int FontI
 				       fontarrayP->pFontEnc,
 				       ucharcode, &mode,
 				       fontarrayP->pType1Data,
-				       DO_NOT_RASTER);
+				       DO_NOT_RASTER,0.0f);
   KillSpace (Current_S);
 
   return((T1_OUTLINE *)charpath);
@@ -224,7 +224,7 @@ T1_OUTLINE *T1_GetStringOutline( int Fon
   ustring=(unsigned char*)string;
   
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i==-1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
@@ -250,8 +250,8 @@ T1_OUTLINE *T1_GetStringOutline( int Fon
   
   /* font is now loaded into memory =>
      Check for size: */
-  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
-    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
+  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
+    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
     if (font_ptr==NULL){
       T1_errno=T1ERR_ALLOC_MEM;
       return(NULL);
@@ -326,7 +326,7 @@ T1_OUTLINE *T1_GetStringOutline( int Fon
 					       no_chars, &mode,
 					       fontarrayP->pType1Data,
 					       kern_pairs, spacewidth,
-					       DO_NOT_RASTER);
+					       DO_NOT_RASTER,0.0f);
   KillSpace (Current_S);
   
   /* In all cases, free memory for kerning pairs */
@@ -378,7 +378,7 @@ T1_OUTLINE *T1_GetMoveOutline( int FontI
 
 
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i==-1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
@@ -398,8 +398,8 @@ T1_OUTLINE *T1_GetMoveOutline( int FontI
   
   /* font is now loaded into memory =>
      Check for size: */
-  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
-    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
+  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
+    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
     if (font_ptr==NULL){
       T1_errno=T1ERR_ALLOC_MEM;
       return(NULL);
Index: grace/T1lib/t1lib/t1outline.h
===================================================================
--- grace.orig/T1lib/t1lib/t1outline.h
+++ grace/T1lib/t1lib/t1outline.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1outline.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-05-27
+  ----- Date:        2002-10-18
   ----- Description: This file is part of the t1-library. It contains
                      definitions and declarations for t1outline.c.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2002. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -72,13 +72,15 @@ extern struct region *fontfcnB(int FontI
 			       struct XYspace *S, char **ev,
 			       unsigned char index, int *mode,
 			       psfont *Font_Ptr,
-			       int do_raster);
+			       int do_raster,
+			       float strokewidth);
 extern struct region *fontfcnB_string( int FontID, int modflag,
 				       struct XYspace *S, char **ev,
 				       unsigned char *string, int no_chars,
 				       int *mode, psfont *Font_Ptr,
 				       int *kern_pairs, long spacewidth,
-				       int do_raster);
+				       int do_raster,
+				       float strokewidth);
 extern struct region *fontfcnB_ByName( int FontID, int modflag,
 				       struct XYspace *S,
 				       char *charname,
Index: grace/T1lib/t1lib/t1set.c
===================================================================
--- grace.orig/T1lib/t1lib/t1set.c
+++ grace/T1lib/t1lib/t1set.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1set.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-05-27
+  ----- Date:        2005-05-01
   ----- Description: This file is part of the t1-library. It contains
                      functions for setting characters and strings of
 		     characters.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -52,6 +52,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -76,6 +77,12 @@
 extern char *t1_get_abort_message( int number);
 extern struct region *Interior(struct segment *path, int fillrule);
 extern unsigned T1_AA_TYPE32 T1aa_bg;          /* white value */
+
+
+static void T1_ComputeLineParameters( int FontID, int width,
+				      int mode, float size,
+				      int *startx, int *endx,
+				      int *starty, int *endy);
   
   
 
@@ -90,6 +97,99 @@ static int l_shift=32;
 
 
 
+/* bin_dump(): Print a binary dump of a byte, short and
+   long variable (used for debug purposes only): */
+static void bin_dump_c(unsigned char value, char space_flag)
+{
+  int i,j;
+  
+  for (i=0;i<=7;i++){
+    if ((j=((value)>>i)&0x01))
+      printf("X");
+    else
+      printf(".");
+  }
+  if (space_flag)
+    printf(" ");
+
+}
+
+static void bin_dump_s(unsigned short value, char space_flag)
+{
+  int i,j;
+
+  if (T1_CheckEndian()){
+    for (i=8;i<=15;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+    for (i=0;i<=7;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+  }
+  else{
+    for (i=0;i<=15;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+  }
+  if (space_flag)
+    printf(" ");
+  
+}
+
+static void bin_dump_l(unsigned long value, char space_flag)
+{
+  int i,j;
+  
+  if (T1_CheckEndian()){
+    for (i=24;i<=31;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+    for (i=16;i<=23;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+    for (i=8;i<=15;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+    for (i=0;i<=7;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+  }
+  else{
+    for (i=0;i<=31;i++){
+      if ((j=((value)>>i)&0x01))
+	printf("X");
+      else
+	printf(".");
+    }
+  }
+  if (space_flag)
+    printf(" ");
+
+}
+
+
+
 /* T1_SetChar(...): Generate the bitmap for a character */
 GLYPH *T1_SetChar( int FontID, char charcode, float size,
 		   T1_TMATRIX *transform)
@@ -98,9 +198,11 @@ GLYPH *T1_SetChar( int FontID, char char
   int mode;
   struct region *area;
   struct XYspace *Current_S;
-  int cache_flag=1;
-  int rot_flag=0;
+  int cache_flag    = 1;
+  int rot_flag      = 0;
   unsigned char ucharcode;
+  float strokewidth = 0.0f;
+  volatile int strokeextraflag = 0;
   
   
   FONTSIZEDEPS *font_ptr;
@@ -145,7 +247,7 @@ GLYPH *T1_SetChar( int FontID, char char
   glyph.bpp=1;  
   
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i==-1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
@@ -181,18 +283,42 @@ GLYPH *T1_SetChar( int FontID, char char
     rot_flag=0;
     cache_flag=1;
   }
+  
+  /* handle stroking stuff */
+  if ( pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) {
+    /* Stroking requested. If caching is not desired, clear cache_flag.
+       Otherwise, leave it unaffected. */
+    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) == 0 ) {
+      /* filled glyphs are cached, indicate that character is to be rendered
+	 on the fly and not to be cached */
+      strokeextraflag = 1;
+      cache_flag = 0;
+    }
+    strokewidth = pFontBase->pFontArray[FontID].StrokeWidth;
+  }
+  else {
+    /* filling requested. */
+    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) {
+      /* stroked glyphs are cached, indicate that character is to be rendered
+	 on the fly and not to be cached */
+      strokeextraflag = 1;
+      cache_flag = 0;
+    }
+    strokewidth = 0.0f;
+  }
+  
   /* font is now loaded into memory =>
      Check for size: */
-  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
-    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
+  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
+    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
     if (font_ptr==NULL){
       T1_errno=T1ERR_ALLOC_MEM;
       return(NULL);
     }
   }
   else {/* size is already existent in cache */
-    /* If no rotation, try to get character from cache */
-    if (rot_flag==0){
+    /* If no rotation and no noncached stroking , try to get character from cache */
+    if ( (rot_flag==0) && (strokeextraflag==0) ) {
       /* we don't use the .bits entry to check because in newer releases
 	 also white glyphs (bits=NULL) are allowed. Rather, we check
 	 whether bpp > 0! */
@@ -240,7 +366,8 @@ GLYPH *T1_SetChar( int FontID, char char
 		 fontarrayP->pFontEnc,
 		 ucharcode, &mode,
 		 fontarrayP->pType1Data,
-		 DO_RASTER);
+		 DO_RASTER,
+		 strokewidth);
   KillSpace (Current_S);
 
   /* fill the glyph-structure */
@@ -355,6 +482,8 @@ GLYPH *T1_SetString( int FontID, char *s
   static int lastno_chars=0;
   float factor;
   long spacewidth;       /* This is given to fontfcnb_string() */
+  float strokewidth = 0.0f;
+  volatile int strokeextraflag = 0;
   
   
   FONTSIZEDEPS *font_ptr;
@@ -467,7 +596,7 @@ GLYPH *T1_SetString( int FontID, char *s
   cache_flag=0;
   
   /* First, check for a correct ID */
-  i=CheckForFontID(FontID);
+  i=T1_CheckForFontID(FontID);
   if (i==-1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
@@ -507,10 +636,33 @@ GLYPH *T1_SetString( int FontID, char *s
     cache_flag=0;
   }
   
+  /* handle stroking stuff */
+  if ( pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) {
+    /* Stroking requested. If caching is not desired, clear cache_flag.
+       Otherwise, leave it unaffected. */
+    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) == 0 ) {
+      /* filled glyphs are cached, indicate that character is to be rendered
+	 on the fly and not to be cached */
+      strokeextraflag = 1;
+      cache_flag = 0;
+    }
+    strokewidth = pFontBase->pFontArray[FontID].StrokeWidth;
+  }
+  else {
+    /* filling requested. */
+    if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) {
+      /* stroked glyphs are cached, indicate that character is to be rendered
+	 on the fly and not to be cached */
+      strokeextraflag = 1;
+      cache_flag = 0;
+    }
+    strokewidth = 0.0f;
+  }
+  
   /* font is now loaded into memory =>
      Check for size: */
-  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
-    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
+  if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
+    font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
     if (font_ptr==NULL){
       T1_errno=T1ERR_ALLOC_MEM;
       return(NULL);
@@ -583,7 +735,7 @@ GLYPH *T1_SetString( int FontID, char *s
      */
   /* First, ensure that all needed characters are in the Cache; if not,
      generate them */
-  if ((rot_flag==0)){
+  if ( (rot_flag==0) && (strokeextraflag==0) ){
     overallwidth=0;
     for (i=0; i<no_chars; i++) {
       currchar= &(font_ptr->pFontCache[ustring[i]]);
@@ -597,7 +749,8 @@ GLYPH *T1_SetString( int FontID, char *s
 			 fontarrayP->pFontEnc,
 			 ustring[i], &mode,
 			 fontarrayP->pType1Data,
-			 DO_RASTER);
+			 DO_RASTER,
+			 strokewidth);
 
 	  /* fill the glyph-structure */
 	  if (mode > 0) {
@@ -969,6 +1122,9 @@ GLYPH *T1_SetString( int FontID, char *s
 	endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8));
 	Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8)
 				    + (start / 8));
+	if (!Target_c) {
+	  continue;
+	}
 	j=middle;
 	if (j == 0)
 	  *Target_c++ |= startmask & endmask;
@@ -994,6 +1150,9 @@ GLYPH *T1_SetString( int FontID, char *s
 	endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8));
 	Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8)
 				    + (start / 8));
+	if (!Target_c) {
+	  continue;
+	}
 	j=middle;
 	if (j == 0)
 	  *Target_c++ |= startmask & endmask;
@@ -1019,6 +1178,9 @@ GLYPH *T1_SetString( int FontID, char *s
 	endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8));
 	Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8)
 				    + (start / 8));
+	if (!Target_c) {
+	  continue;
+	}
 	j=middle;
 	if (j == 0)
 	  *Target_c++ |= startmask & endmask;
@@ -1055,7 +1217,8 @@ GLYPH *T1_SetString( int FontID, char *s
 			ustring, no_chars, &mode,
 			fontarrayP->pType1Data,
 			kern_pairs, spacewidth,
-			DO_RASTER);
+			DO_RASTER,
+			strokewidth);
   KillSpace (Current_S);
   
   /* In all cases, free memory for kerning pairs */
@@ -1378,10 +1541,10 @@ void T1_DumpGlyph( GLYPH *glyph)
 
 /* This function will essentially return the bounding box of the
    line-rule */
-void T1_ComputeLineParameters( int FontID, int mode,
-			       int width, float size,
-			       int *startx, int *endx,
-			       int *starty, int *endy)
+static void T1_ComputeLineParameters( int FontID, int mode,
+				      int width, float size,
+				      int *startx, int *endx,
+				      int *starty, int *endy)
 {
   float position=0.0, thickness=0.0;
   int startx1, startx2, endx1, endx2;
@@ -1902,3 +2065,185 @@ GLYPH *T1_FillOutline( T1_OUTLINE *path,
   
   
 }
+
+
+/* T1_SetRect(): Raster a rectangle, whose size is given in charspace units.
+   The resulting glyph does not cause any escapement. */
+GLYPH* T1_SetRect( int FontID, float size,
+		   float width, float height, T1_TMATRIX *transform)
+{
+  int i;
+  int mode;
+  struct region *area;
+  struct XYspace *Current_S;
+  float strokewidth = 0.0f;
+  
+  FONTSIZEDEPS *font_ptr;
+  FONTPRIVATE  *fontarrayP;
+  
+  volatile int memsize=0;
+  LONG h,w;
+  LONG paddedW;
+
+  static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1};
+
+
+  /* We return to this if something goes wrong deep in the rasterizer */
+  if ((i=setjmp( stck_state))!=0) {
+    T1_errno=T1ERR_TYPE1_ABORT;
+    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
+	     t1_get_abort_message( i));
+    T1_PrintLog( "T1_SetRect()", err_warn_msg_buf,
+	       T1LOG_ERROR);
+    return( NULL);
+  }
+
+  font_ptr = NULL;
+  
+  /* Reset character glyph, if necessary */
+  if (glyph.bits!=NULL){
+    free(glyph.bits);
+    glyph.bits=NULL;
+  }
+  glyph.metrics.leftSideBearing=0;
+  glyph.metrics.rightSideBearing=0;
+  glyph.metrics.advanceX=0;
+  glyph.metrics.advanceY=0;
+  glyph.metrics.ascent=0;
+  glyph.metrics.descent=0;
+  glyph.pFontCacheInfo=NULL;
+  glyph.bpp=1;  
+  
+  /* First, check for a correct ID. */
+  i=T1_CheckForFontID(FontID);
+  if ( i == -1 ) {
+    return NULL;
+  }
+  /* if necessary load font into memory */
+  if ( i == 0 )
+    if ( T1_LoadFont( FontID) )
+      return NULL;
+
+  /* Check for valid size */
+  if (size<=0.0){
+    T1_errno=T1ERR_INVALID_PARAMETER;
+    return(NULL);
+  }
+
+  /* Assign padding value */
+  T1_pad=pFontBase->bitmap_pad;
+  if (pFontBase->endian)
+    T1_byte=1;
+  else
+    T1_byte=0;
+  T1_wordsize=T1_pad;
+
+  if ( i > 0 ) {
+    /* FontID identifies a valid font */
+    fontarrayP = &(pFontBase->pFontArray[FontID]);
+    
+    /* Check for size and create it if necessary */
+    if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
+      font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS);
+      if (font_ptr==NULL){
+	T1_errno=T1ERR_ALLOC_MEM;
+	return(NULL);
+      }
+    }
+    
+    /* handle stroking stuff */
+    if ( fontarrayP->info_flags & RASTER_STROKED) {
+      strokewidth = pFontBase->pFontArray[FontID].StrokeWidth;
+    }
+    else {
+      strokewidth = 0.0f;
+    }
+  }
+  else {
+    fontarrayP = NULL;
+    strokewidth = 0.0f;
+  }
+  
+  
+  /* Setup an appropriate charspace matrix. Note that the rasterizer
+     assumes vertical values with inverted sign! Transformation should
+     create a copy of the local charspace matrix which then still has
+     to be made permanent. */
+  if ( transform != NULL ) {
+    Current_S = (struct XYspace *) 
+      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
+				 transform->cxx, - transform->cxy,
+				 transform->cyx, - transform->cyy),
+		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
+  }
+  else{
+    Current_S = (struct XYspace *)
+      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
+				1.0, 0.0, 0.0, -1.0),
+		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
+  }
+  
+  mode=0;
+  area=fontfcnRect( width,
+		    height,
+		    Current_S,
+		    &mode,
+		    DO_RASTER,
+		    strokewidth);
+  KillSpace (Current_S);
+  
+  /* fill the glyph-structure */
+  if ( mode > 0 ) {
+    sprintf( err_warn_msg_buf, "fontfcnRect() set mode=%d", mode);
+    T1_PrintLog( "T1_SetRect()", err_warn_msg_buf, T1LOG_WARNING);
+    T1_errno=mode;
+    return(NULL);
+  }
+  if ( area == NULL ) {
+    T1_PrintLog( "T1_SetRect()", "area=NULL returned by fontfcnRect()", T1LOG_WARNING);
+    T1_errno=mode;
+    return(NULL);
+  }
+  h = area->ymax - area->ymin;
+  w = area->xmax - area->xmin;
+
+  paddedW = PAD(w, T1_pad);
+  
+  if (h > 0 && w > 0) {
+    memsize = h * paddedW / 8 + 1;
+    /* This is for the users copy of the character, for security-reasons
+       the original pointer to the cache area is not used. The entry glyph.bits
+       is free'ed every time this function is called: */
+    glyph.bits = (char *)malloc(memsize*sizeof( char));
+    if ( glyph.bits == NULL ) {
+      T1_errno=T1ERR_ALLOC_MEM;
+      /* make sure to get rid of 'area' before leaving! */
+      KillRegion (area);
+      return(NULL);
+    }
+  }
+  else {
+    h = w = 0;
+    area->xmin = area->xmax = 0;
+    area->ymin = area->ymax = 0;
+  }
+
+  /* Assign metrics */
+  glyph.metrics.leftSideBearing  = area->xmin;
+  glyph.metrics.advanceX   = NEARESTPEL(area->ending.x - area->origin.x);
+  glyph.metrics.advanceY   = - NEARESTPEL(area->ending.y - area->origin.y);
+  glyph.metrics.rightSideBearing = area->xmax;
+  glyph.metrics.descent          = - area->ymax;
+  glyph.metrics.ascent           = - area->ymin;
+
+  
+  if (h > 0 && w > 0) {
+    (void) memset(glyph.bits, 0, memsize);
+    fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize );
+  }
+  
+  /* make sure to get rid of 'area' before leaving! */
+  KillRegion (area);
+  
+  return(&glyph);
+}
Index: grace/T1lib/t1lib/t1set.h
===================================================================
--- grace.orig/T1lib/t1lib/t1set.h
+++ grace/T1lib/t1lib/t1set.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1set.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-05-27
+  ----- Date:        2003-01-02
   ----- Description: This file is part of the t1-library. It contains
                      definitions and declarations for t1set.c.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -32,16 +32,15 @@ GLYPH *T1_SetChar( int FontID, char char
 GLYPH *T1_SetString( int FontID, char *string, volatile int len,
 		     long spaceoff, int modflag,
 		     float size, T1_TMATRIX *transform);
+GLYPH* T1_SetRect( int FontID, float size,
+		   float width, float height,
+		   T1_TMATRIX *transform);
 void fill(char *dest, int h, int w,
 	  struct region *area, int byte, int bit,
 	  int wordsize);
 void fillrun(char *p, pel x0, pel x1, int bit);
 GLYPH *T1_CopyGlyph(GLYPH *glyph);
 void T1_DumpGlyph( GLYPH *glyph);
-void T1_ComputeLineParameters( int FontID, int width,
-			       int mode, float size,
-			       int *startx, int *endx,
-			       int *starty, int *endy);
 GLYPH *T1_ConcatGlyphs( GLYPH *glyph1, GLYPH *glyph2,
 			int x_off, int y_off, int modflag);
 void T1_DumpGlyph( GLYPH *glyph);
@@ -55,6 +54,9 @@ extern GLYPH *T1_SetChar( int FontID, ch
 extern GLYPH *T1_SetString( int FontID, char *string, volatile int len,
 			    long spaceoff, int modflag,
 			    float size, T1_TMATRIX *transform);
+extern GLYPH* T1_SetRect( int FontID, float size,
+			  float width, float height,
+			  T1_TMATRIX *transform);
 extern void fill(char *dest, int h, int w,
 		 struct region *area, int byte, int bit,
 		 int wordsize);
@@ -73,15 +75,24 @@ extern struct region *fontfcnB(int FontI
 			       struct XYspace *S, char **ev,
 			       unsigned char index, int *mode,
 			       psfont *Font_Ptr,
-			       int do_raster);
+			       int do_raster,
+			       float strokewidth);
 extern struct region *fontfcnB_string( int FontID, int modflag,
 				       struct XYspace *S, char **ev,
 				       unsigned char *string, int no_chars,
 				       int *mode, psfont *Font_Ptr,
 				       int *kern_pairs, long spacewidth,
-				       int do_raster);
+				       int do_raster,
+				       float strokewidth);
 extern struct region *fontfcnB_ByName( int FontID, int modflag,
 				       struct XYspace *S,
 				       char *charname,
 				       int *mode, psfont *Font_Ptr,
 				       int do_raster);
+extern struct region* fontfcnRect( float width,
+				   float height,
+				   struct XYspace* S,
+				   int* mode,
+				   int do_raster,
+				   float strokewidth);
+
Index: grace/T1lib/t1lib/t1subset.c
===================================================================
--- grace.orig/T1lib/t1lib/t1subset.c
+++ grace/T1lib/t1lib/t1subset.c
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1subset.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-09-09
+  ----- Date:        2005-05-01
   ----- Description: This file is part of the t1-library. It contains
                      functions for subsetting type 1 fonts.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -50,6 +50,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -58,6 +59,7 @@
 #include "t1finfo.h"
 #include "t1misc.h"
 #include "t1base.h"
+#include "t1delete.h"
 #include "t1subset.h"
 
 /* Segment header for pfb-files (reminder):
@@ -81,6 +83,7 @@
 #define SEGMENT_EOF         3
 
 
+extern psobj *StdEncArrayP;       /* For accessing StandardEncoding */
 
 static char *charstringP;
 static int  charstringL;
@@ -194,8 +197,6 @@ static int make_pfb_segment_header( char
 
 
 
-/* A function for reading a Type 1 font file. eexec-decryption
-   is done on the fly.  */
 char *T1_SubsetFont( int FontID,
 		     char *mask,
 		     unsigned int flags,
@@ -222,6 +223,7 @@ char *T1_SubsetFont( int FontID,
   char *csdone;  /* stores which charstrings already have been written */
   int currstring_no=0;
   char *charnameP;
+  char charnamebuf[257];
   unsigned char cipher;
   char rdstring[3];
   char ndstring[3];
@@ -236,6 +238,8 @@ char *T1_SubsetFont( int FontID,
   int m=0;
   int n=0;
   int o=0;
+  int p=0;
+  
   
   int notdefencoded=0;
   int stdenc=0;
@@ -245,11 +249,17 @@ char *T1_SubsetFont( int FontID,
   int encrypt=1;      /* 1=ASCII-hex, 2=Binary, 0=None (for debugging) */
   int dindex=0;
   int nocharstrings=0;
+  char encmask[256];  /* Mask after resolving composite characters */
+  T1_COMP_CHAR_INFO* cci = NULL;
 
+  /* variables for checking SEAC's */
+  int qs_num = 0;
+  unsigned char qs_piece1 = 0;
+  unsigned char qs_piece2 = 0;
   
   
   /* Otherwise we would get invalid accesses later */
-  if (CheckForFontID(FontID)!=1) {
+  if (T1_CheckForFontID(FontID)!=1) {
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   } 
@@ -262,13 +272,81 @@ char *T1_SubsetFont( int FontID,
     return(NULL);
   } 
 
+  /* Reset resulting encoding mask */ 
   for ( j=0; j<256; j++) {
-    if (mask[j]!=0) {
-      nocharstrings++;
-    }
+    encmask[j] = 0;
   }
+  
+  /* Build encmask, a mask, where all required elementary character
+     definitions required are tagged. Font internal SEAC definitions
+     are evaluated at first priority, and as a fallback, also user
+     specified composite character data is taken into account.
+  */
+  for ( j=0; j<256; j++) {
+    if ( mask[j] != 0 ) {
+      /* In any case, tag slot j itself */
+      encmask[j] |= 0x01;
+      /* Now check against correctly defined SEAC (Standard
+	 Encoding Accented Character). */
+      if ( (qs_num = T1int_QuerySEAC( FontID, 
+				      j,
+				      &qs_piece1,
+				      &qs_piece2
+				      )) > 1 ) {
+	/* We have a SEAC --> reserve 2 additional slots, 
+	   the basechar and the accent. The index numbers in this case
+	   always refer to to StandardEncoding, which is not necessarily
+	   the font's current encoding. We indicate this by using bit 2
+	   0x2 inverse sign. */
+	encmask[qs_piece1] |= 0x2;
+	encmask[qs_piece2] |= 0x2;
+      }
+      else {
+	/* OK, it is no a SEAC, but we still check against AFM composite character
+	   data definition. This is non-standard, but we give the user the chance
+	   to access all single character definitions in order construct arbitrary
+	   composite characters. */
+	if ( cci != NULL ) {
+	  T1_FreeCompCharData( cci);
+	}
+	cci = T1_GetCompCharData( FontID, j);
+	
+	if ( (cci != NULL) && (cci->numPieces > 1) ) {
+	  /* Tag all components that are required to construct
+	     the composite character j. */
+	  for ( p=0; p<cci->numPieces; p++) {
+	    encmask[cci->pieces[p].piece] |= 0x1;
+	  }
+	}
+      }
+    } /* if ( mask[j] != 0 ) */
+  } /* for ...  mask */ 
 
 
+  /* Inspect encmask, get number of atomic charstrings and check for
+     ".notdef" being encoded. */
+  for ( j=0; j<256; j++) {
+    if ( (encmask[j] & 0x01) != 0 ) {
+      ++nocharstrings;
+      /* Obtain name from current encoding */
+      charnameP=T1_GetCharName( FontID, j);
+    }
+    if ( (encmask[j] & 0x02) != 0 ) {
+      ++nocharstrings;
+      /* Obtain name from StandardEncoding */
+      strncpy( charnamebuf, (StdEncArrayP[j]).data.nameP, (StdEncArrayP[j]).len);
+      charnamebuf[StdEncArrayP[j].len] = '\0';
+      charnameP=charnamebuf;
+    }
+    if ( encmask[j] != 0 ) {
+      
+      if ( strcmp(charnameP, ".notdef") == 0 ) {
+	notdefencoded=1;
+      }
+    }
+  }
+  
+
   /* adjust encrypting type according to flags. Default is ASCII-hex
      encryption because the output may be verbatim inserted into a
      PostScript-file. */
@@ -312,6 +390,7 @@ char *T1_SubsetFont( int FontID,
        ensure that "eexec" does not get split between two reads.
        Otherwise, decryption would not be started. */
     retval=T1Gets(&(filebuf[i]), 1025, ifp);
+    
     i+=retval;
     if ( (dindex==0) && (T1GetDecrypt()>0) ) {
       dindex=i-retval; /* from this point on we have decrypted bytes */
@@ -319,12 +398,27 @@ char *T1_SubsetFont( int FontID,
 	       dindex);
       T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf,
 		   T1LOG_DEBUG);
-    }  
+    }
+    
+    /* Encoding handling follows.
+       Note: If the font file defines StandardEncoding (as we will check shortly),
+             but the font has been reencoded by t1lib, we enforce reencoding
+	     in any case so that all characters are accessible eventually in
+	     the subset.
+     */
+    if ( pFontBase->pFontArray[FontID].pFontEnc != NULL ) {
+      T1_PrintLog( "T1_SubsetFont()", "Font is reencoded by t1lib, enforcing Reencoding of subset",
+		   T1LOG_DEBUG);
+      /* Set flag to enforce reenocde in case of StandardEncoding */
+      flags |= T1_SUBSET_FORCE_REENCODE;
+      /* Reset flag to enforce reenocde in case of StandardEncoding */
+      flags &= ~T1_SUBSET_SKIP_REENCODE;
+    }
     
-    /* Encoding handling */
     if (strstr( &(filebuf[i-retval]), "/Encoding")!=NULL) {
       if (strstr( &(filebuf[i-retval]), "StandardEncoding")!=NULL) {
 	stdenc=1;
+
 	if ((flags & T1_SUBSET_FORCE_REENCODE)!=0) {
 	  /* we ignore the current line ... */
 	  i-=retval;
@@ -341,8 +435,11 @@ char *T1_SubsetFont( int FontID,
 	}
       }
       else {
-	/* The encoding is explicitly defined in the font file. We skip the
-	   whole definition unless reencoding should be skipped. */
+	/* The encoding is explicitly defined in the font file. We skip copying 
+	   the whole definition because we will reencode the subset later, unless
+	   reencoding should be skipped by means of the flag settings. If the font
+	   has been reencoded by t1lib, we enforce reencoding in order to ensure
+	   that all characters in the subset will be accessible (see above). */
 	stdenc=0;
 	retval=T1Gets(&(filebuf[i]), 1025, ifp);
 	i+=retval;
@@ -370,19 +467,22 @@ char *T1_SubsetFont( int FontID,
       }
       
       /* At this point, if required, the actual encoding definition
-	 follows  */
+	 follows. */
       if ( reencode!=0) {
 	k=0;
+
+	/* Write actually required encoding slots. We only encode the
+	   characters required from the current fonts encoding. Characters
+	   from StandardEncoding required by composite chars are not encoded. */
 	for ( j=0; j<256; j++) {
-	  if (mask[j]!=0) {
+	  if ( (encmask[j] & 0x01) !=0 ) {
 	    charnameP=T1_GetCharName( FontID, j);
 	    i+=sprintf( &(filebuf[i]), "dup %d /%s put\n", j,
 			charnameP);
 	    k++;
-	    if (strcmp(charnameP, ".notdef")==0)
-	      notdefencoded=1;
 	  }
 	}
+
 	/* finish encoding definition */
 	i+=sprintf( &(filebuf[i]), "readonly def\n");
 	sprintf( err_warn_msg_buf, "Encoded %d characters",
@@ -394,7 +494,7 @@ char *T1_SubsetFont( int FontID,
       
     } /* end of    if (...encoding handling...)    */
 
-    /* Extract the names are used for the charstring definitions.
+    /* Extract the names that are used for the charstring definitions.
        We will later need them! */
     if (strstr( &(filebuf[i-retval]), "/RD")!=NULL) {
       sprintf( rdstring, "RD");
@@ -416,12 +516,14 @@ char *T1_SubsetFont( int FontID,
 	       i-dindex);
       T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf,
 		   T1LOG_DEBUG);
+
       /* if .notdef is not in the encoding mask, we have to reserve
 	 room for the additional charstring .notdef. Note that still
 	 nocharstrings is an upper bound estimation, which is reached
 	 in cases where no characters are encoded more than one time. */
-      if (notdefencoded==0)
-	nocharstrings++;
+      if ( notdefencoded == 0 ) {
+	nocharstrings++; 
+      }
       
       i+=sprintf( &(filebuf[i]), "2 index /CharStrings %d dict dup begin\n",
 		  nocharstrings);
@@ -461,11 +563,20 @@ char *T1_SubsetFont( int FontID,
   /* Now, step through the specifier matrix and write only the
      necessary charstrings. */
   for ( j=0; j<256; j++) {
-    if (mask[j]!=0) {
-      charnameP=T1_GetCharName( FontID, j);
+    if (encmask[j]!=0) {
+      if ( (encmask[j] & 0x01) != 0 ) {
+	/* Obtain name from current encoding */
+	charnameP=T1_GetCharName( FontID, j);
+      }
+      else {
+	/* Obtain name from StandardEncoding */
+	strncpy( charnamebuf, (StdEncArrayP[j]).data.nameP, (StdEncArrayP[j]).len);
+	charnamebuf[StdEncArrayP[j].len] = '\0';
+	charnameP=charnamebuf;
+      }
       if ((currstring_no=locateCharString( FontID, charnameP))==0) {
-	/* This is mysterious, but causes no harm because .notdef
-	   will be substituted */
+	/* Atomic character not found. This is mysterious, but causes no harm
+	   because .notdef will be substituted */
 	sprintf( err_warn_msg_buf, "Could not locate CS ""%s"" for index %d",
 		 charnameP, j);
 	T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf,
@@ -481,8 +592,8 @@ char *T1_SubsetFont( int FontID,
 	i+=sprintf( &(filebuf[i]), " %s\n", ndstring);
 	csdone[currstring_no-1]=1;
 	sprintf( err_warn_msg_buf,
-		 "Processing of CS ""%s"" for index %d successful (len=%d bytes, line=%d bytes)",
-		 charnameP, j, charstringL, i-k);
+		 "Processing of CS ""%s"" for index %d (EncMaskFlag=0x%X) successful (len=%d bytes, line=%d bytes)",
+		 charnameP, j, encmask[j], charstringL, i-k);
 	T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf,
 		     T1LOG_DEBUG);
       }
@@ -494,8 +605,17 @@ char *T1_SubsetFont( int FontID,
       }
     }
   }
-  if (csdone!=NULL)
+
+  /* Get rid of temporary data */
+  if (csdone!=NULL) {
     free( csdone);
+    csdone = NULL;
+  }
+  if ( cci != NULL ) {
+    free( cci);
+    cci = NULL;
+  }
+
   /* All charstrings are written. Some PostScript code follows */
   i+=sprintf( &(filebuf[i]),
 	      "end\nend\nreadonly put\nnoaccess put\ndup /FontName get exch definefont pop\nmark currentfile closefile\n");
@@ -639,7 +759,7 @@ char *T1_SubsetFont( int FontID,
 	     tr_len);
     T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf,
 		 T1LOG_DEBUG);
-    l+=sprintf( &(trailerbuf[l]), linebuf); /* contains the PostScript trailer */
+    l+=sprintf( &(trailerbuf[l]), "%s", linebuf); /* contains the PostScript trailer */
   }
   
   /* compute size of output file */
@@ -785,7 +905,7 @@ char *T1_GetCharString( int FontID, char
 
   static char *charstring=NULL;
   
-  if (CheckForFontID(FontID)!=1) {
+  if (T1_CheckForFontID(FontID)!=1) {
     T1_errno=T1ERR_INVALID_FONTID;
     return(NULL);
   } 
@@ -826,7 +946,7 @@ char *T1_GetCharString( int FontID, char
 int T1_GetlenIV( int FontID)
 {
   
-  if (CheckForFontID(FontID)!=1) {
+  if (T1_CheckForFontID(FontID)!=1) {
     T1_errno=T1ERR_INVALID_FONTID;
     return( -2);
   } 
Index: grace/T1lib/t1lib/t1subset.h
===================================================================
--- grace.orig/T1lib/t1lib/t1subset.h
+++ grace/T1lib/t1lib/t1subset.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1subset.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2004-12-02
   ----- Description: This file is part of the t1-library. It contains
                      declarations and definitions for t1subset.c.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2004. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -49,6 +49,12 @@ extern int T1GetTrailer(char *string, in
 extern int T1Close( FILE *f);
 extern void T1io_reset( void);
 
+extern int T1int_QuerySEAC( int FontID, 
+			    unsigned char index,
+			    unsigned char* piece1,
+			    unsigned char* piece2
+			    );
+
 char *T1_SubsetFont( int FontID,
 		     char *mask,
 		     unsigned int flags,
Index: grace/T1lib/t1lib/t1trans.c
===================================================================
--- grace.orig/T1lib/t1lib/t1trans.c
+++ grace/T1lib/t1lib/t1trans.c
@@ -1,11 +1,11 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1trans.c 
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2005-05-01
   ----- Description: This file is part of the t1-library. It contains
                      functions for transforming fonts and setting
 		     line-parameters.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -51,6 +51,7 @@
 #include "../type1/spaces.h"
 #include "../type1/util.h"
 #include "../type1/fontfcn.h"
+#include "../type1/paths.h"
 #include "../type1/regions.h"
 
 
@@ -69,7 +70,7 @@ int T1_ExtendFont( int FontID, double ex
 {
   
   /* First, check for font residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -95,7 +96,7 @@ int T1_ExtendFont( int FontID, double ex
 double T1_GetExtend( int FontID)
 {
   /* First, check for font residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -115,7 +116,7 @@ int T1_SlantFont( int FontID, double sla
 {
   
   /* First, check for font residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -141,7 +142,7 @@ int T1_SlantFont( int FontID, double sla
 double T1_GetSlant( int FontID)
 {
   /* First, check for font residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -160,7 +161,7 @@ int T1_TransformFont( int FontID, T1_TMA
 {
   
   /* First, check for font residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -190,7 +191,7 @@ T1_TMATRIX T1_GetTransform( int FontID)
   T1_TMATRIX tmatrix={0.0, 0.0, 0.0, 0.0};
   
   /* First, check for font residing in memory: */
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(tmatrix);
   }
@@ -212,7 +213,7 @@ T1_TMATRIX T1_GetTransform( int FontID)
 int T1_SetLinePosition( int FontID, int linetype, float value)
 {
 
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -241,7 +242,7 @@ int T1_SetLinePosition( int FontID, int
 int T1_SetLineThickness( int FontID, int linetype, float value)
 {
 
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(-1);
   }
@@ -269,7 +270,7 @@ int T1_SetLineThickness( int FontID, int
 float T1_GetLinePosition( int FontID, int linetype)
 {
 
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -292,7 +293,7 @@ float T1_GetLinePosition( int FontID, in
 float T1_GetLineThickness( int FontID, int linetype)
 {
 
-  if (CheckForFontID(FontID)!=1){
+  if (T1_CheckForFontID(FontID)!=1){
     T1_errno=T1ERR_INVALID_FONTID;
     return(0.0);
   }
@@ -534,3 +535,169 @@ T1_TMATRIX *T1_TransformMatrix( T1_TMATR
 }
 
 
+
+/* T1_StrokeFont(): Switch the  font referenced by FontID to stroking
+   or filling. The stroked character will be cached and 
+   filled characters are no longer cached and vice versa.
+   This is only allowed if no size dependent data exists.
+   Of course, the font must already have been loaded.
+   Returns 0 for success and -1 otherwise.
+   */
+int T1_StrokeFont( int FontID, int dostroke)
+{
+  
+  /* First, check for font residing in memory: */
+  if ( T1_CheckForFontID( FontID) != 1 ) {
+    T1_errno = T1ERR_INVALID_FONTID;
+    return -1;
+  }
+  
+  /* Second, check whether size-dependent data exists: */
+  if ( pFontBase->pFontArray[FontID].pFontSizeDeps != NULL ) {
+    T1_errno = T1ERR_OP_NOT_PERMITTED;
+    return -1; 
+  }
+
+  if ( dostroke != 0 ) {
+    pFontBase->pFontArray[FontID].info_flags |= RASTER_STROKED;
+    pFontBase->pFontArray[FontID].info_flags |= CACHE_STROKED;
+  }
+  else {
+    pFontBase->pFontArray[FontID].info_flags &= ~RASTER_STROKED;
+    pFontBase->pFontArray[FontID].info_flags &= ~CACHE_STROKED;
+  }
+  
+
+  return 0;
+}
+
+
+
+/* T1_SetStrokeFlag(): Return the stroke flag for font FontID.
+   Return:  0                      flag has been set
+           -1                      flag could not be set 
+*/
+int T1_SetStrokeFlag( int FontID)
+{
+  /* First, check for font residing in memory: */
+  if ( T1_CheckForFontID(FontID) != 1 ) {
+    T1_errno = T1ERR_INVALID_FONTID;
+    return -1;
+  }
+  
+  /* Set stroke flag to true */
+  pFontBase->pFontArray[FontID].info_flags |= RASTER_STROKED;
+  
+  return 0;
+  
+}
+
+
+
+/* T1_ClearStrokeFlag(): Reset the stroke flag for font FontID.
+   Return:  0                      flag has been reset
+           -1                      flag could not be reset 
+*/
+int T1_ClearStrokeFlag( int FontID)
+{
+  /* First, check for font residing in memory: */
+  if ( T1_CheckForFontID(FontID) != 1 ) {
+    T1_errno = T1ERR_INVALID_FONTID;
+    return -1;
+  }
+
+  /* Reset stroke flag */
+  pFontBase->pFontArray[FontID].info_flags &= ~RASTER_STROKED;
+  
+  return 0;
+  
+}
+
+
+
+/* T1_GetStrokeMode(): Return the stroke flag for font FontID.
+   Return: -1                      if font is not loaded.
+	    0                      if flag is reset,
+	    1                      if stroking is enabled for this font,
+	    2                      if stroked characters are cached,
+	    3                      if stroking is enabled and stroked
+	                           characters are cached.
+*/
+int T1_GetStrokeMode( int FontID)
+{
+  int outval = 0;
+  
+  /* First, check for font residing in memory: */
+  if ( T1_CheckForFontID( FontID) != 1 ) {
+    T1_errno = T1ERR_INVALID_FONTID;
+    return -1;
+  }
+
+  if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) 
+    outval |= 0x02;
+  
+  if ( (pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) != 0 ) 
+    outval |= 0x01;
+  
+  return outval;
+    
+}
+
+
+
+/* T1_SetStrokeWidth(): Set the penwidth used when stroking font FontID.
+   Return  -1           If width could not be set.
+            0           if width has been set.
+ */
+int T1_SetStrokeWidth( int FontID, float strokewidth)
+{
+  /* First, check for font residing in memory: */
+  if ( T1_CheckForFontID( FontID) != 1 ) {
+    T1_errno = T1ERR_INVALID_FONTID;
+    return -1;
+  }
+
+  /* Second, check whether caching stroked characters is enabled
+     for this font and glyph data is already existing. In this case
+     the operation is forbidden, unless the previous non-zero value
+     is just restored! */
+  if ( ((pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0) &&
+       (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL) &&
+       (pFontBase->pFontArray[FontID].SavedStrokeWidth != strokewidth)
+       ) {
+    T1_errno = T1ERR_OP_NOT_PERMITTED;
+    return -1; 
+  }
+
+  /* OK, accept stroke width after ensuring a numerically meaningful
+     value */
+  if ( strokewidth < 0.0f ) {
+    T1_errno = T1ERR_INVALID_PARAMETER;
+    return -1;
+  }
+
+  pFontBase->pFontArray[FontID].StrokeWidth = strokewidth;
+  
+  if ( strokewidth != 0.0f )
+    pFontBase->pFontArray[FontID].SavedStrokeWidth = strokewidth;
+  
+  return 0;
+    
+}
+
+
+
+/* T1_GetStrokeWidth(): Get the penwidth used when stroking font FontID.
+   If 0.0 is returned, it might also indicate that the font is not loaded.
+*/
+float T1_GetStrokeWidth( int FontID)
+{
+  /* First, check for font residing in memory: */
+  if ( T1_CheckForFontID( FontID) != 1 ) {
+    T1_errno = T1ERR_INVALID_FONTID;
+    return 0.0f;
+  }
+
+  return pFontBase->pFontArray[FontID].StrokeWidth;  
+}
+
Index: grace/T1lib/t1lib/t1trans.h
===================================================================
--- grace.orig/T1lib/t1lib/t1trans.h
+++ grace/T1lib/t1lib/t1trans.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1trans.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-04-01
+  ----- Date:        2002-10-19
   ----- Description: This file is part of the t1-library. It contains
                      definitions and declarations fort t1trans.c
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2002. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -47,9 +47,17 @@ T1_TMATRIX *T1_ExtendVMatrix( T1_TMATRIX
 T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix,
 				double cxx, double cyx,
 				double cxy, double cyy);
+int T1_StrokeFont( int FontID, int dostroke);
+int T1_SetStrokeFlag( int FontID);
+int T1_ClearStrokeFlag( int FontID);
+int T1_GetStrokeMode( int FontID);
+int T1_SetStrokeWidth( int FontID, float strokewidth);
+float T1_GetStrokeWidth( int FontID);
+
 
 #else
 
+
 extern int T1_ExtendFont( int FontID, double extend);
 extern int T1_SlantFont( int FontID, double slant);
 extern int T1_TransformFont( int FontID, T1_TMATRIX *matrix);
@@ -70,6 +78,12 @@ extern T1_TMATRIX *T1_ExtendVMatrix( T1_
 extern T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix,
 				       double cxx, double cyx,
 				       double cxy, double cyy);
+extern int T1_StrokeFont( int FontID, int dostroke);
+extern int T1_SetStrokeFlag( int FontID);
+extern int T1_ClearStrokeFlag( int FontID);
+extern int T1_GetStrokeMode( int FontID);
+extern int T1_SetStrokeWidth( int FontID, float strokewidth);
+extern float T1_GetStrokeWidth( int FontID);
 
 #endif
 
Index: grace/T1lib/t1lib/t1types.h
===================================================================
--- grace.orig/T1lib/t1lib/t1types.h
+++ grace/T1lib/t1lib/t1types.h
@@ -1,10 +1,10 @@
 /*--------------------------------------------------------------------------
   ----- File:        t1types.h
   ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
-  ----- Date:        2001-06-04
+  ----- Date:        2004-12-09
   ----- Description: This file is part of the t1-library. It contains
                      type definitions used by the t1-library.
-  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001. 
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2004. 
                      As of version 0.5, t1lib is distributed under the
 		     GNU General Public Library Lincense. The
 		     conditions can be found in the files LICENSE and
@@ -28,6 +28,7 @@
 
 #define T1TYPES_H
 
+#include "sysconf.h"
 
 typedef struct
 {
@@ -74,6 +75,9 @@ typedef struct
   float OvrLnThick;
   float OvrStrkPos;
   float OvrStrkThick;
+  float StrokeWidth;
+  float SavedStrokeWidth;
+  
   unsigned short physical; /* This entry is used to decide, whether a
 			      font is associated with an own physical
 			      fontfile, or whether it has been created
@@ -144,7 +148,7 @@ typedef struct
 
 
 
-/* A data that makes most important information available to user. */
+/* A data type that makes most important information available to user. */
 typedef struct
 {
   int      width;       /* The glyph's width */
@@ -161,14 +165,14 @@ typedef struct
  
 #define   FRACTBITS     16   /* number of fractional bits in 'fractpel'      */
 /* From/to conversion of pels/fractpels */
-#define   T1_TOPATHPOINT(p)      (((long)p)<<FRACTBITS)
+#define   T1_TOPATHPOINT(p)      (((T1_AA_TYPE32)p)<<FRACTBITS)
 #define   PPHALF                 (1<<(FRACTBITS-1))
 #define   T1_NEARESTPOINT(fp)    (((fp)+PPHALF)>>FRACTBITS)
 
 /* A fractional point */
 typedef struct {
-  long x;
-  long y;
+  T1_AA_TYPE32 x;
+  T1_AA_TYPE32 y;
 } T1_PATHPOINT;
 
 
Index: grace/T1lib/t1lib/t1x11.c
===================================================================
--- /dev/null
+++ grace/T1lib/t1lib/t1x11.c
@@ -0,0 +1,1168 @@
+/*--------------------------------------------------------------------------
+  ----- File:        t1x11.c 
+  ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
+  ----- Date:        2005-05-01
+  ----- Description: This file is part of the t1-library. It contains
+                     functions for generating glyphs with data in
+		     X11-Pixmap format.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2005.
+                     As of version 0.5, t1lib is distributed under the
+		     GNU General Public Library Lincense. The
+		     conditions can be found in the files LICENSE and
+		     LGPL, which should reside in the toplevel
+		     directory of the distribution.  Please note that 
+		     there are parts of t1lib that are subject to
+		     other licenses:
+		     The parseAFM-package is copyrighted by Adobe Systems
+		     Inc.
+		     The type1 rasterizer is copyrighted by IBM and the
+		     X11-consortium.
+  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
+  ----- Credits:     I want to thank IBM and the X11-consortium for making
+                     their rasterizer freely available.
+		     Also thanks to Piet Tutelaers for his ps2pk, from
+		     which I took the rasterizer sources in a format
+		     independent from X11.
+                     Thanks to all people who make free software living!
+--------------------------------------------------------------------------*/
+  
+#define T1X11_C
+
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "../type1/types.h"
+#include "parseAFM.h" 
+#include "../type1/objects.h" 
+#include "../type1/spaces.h"  
+#include "../type1/util.h" 
+#include "../type1/fontfcn.h"
+#include "../type1/paths.h"
+#include "../type1/regions.h"
+
+#include "t1types.h"
+#include "t1extern.h"
+#include "t1set.h"
+#include "t1aaset.h"
+#include "t1load.h"
+#include "t1finfo.h"
+#include "t1misc.h"
+#include "t1x11.h"
+#include "t1base.h"
+
+
+
+#define T1GCMASK GCForeground | GCBackground 
+
+/* As a fall back */
+#ifndef T1_AA_TYPE16 
+#define T1_AA_TYPE16    short
+#endif
+#ifndef T1_AA_TYPE32 
+#define T1_AA_TYPE32    int
+#endif
+
+
+
+/* The three important X11 parameters t1lib has to deal with: */
+static Display  *T1_display=NULL;  /* Must be accessible from t1delete.c */
+static Visual   *T1_visual=NULL;
+static Colormap T1_colormap;
+static unsigned int T1_depth=0;
+static int T1_byte_order;
+static int lastlevel=0;
+static unsigned long oldfg_n=0, oldbg_n=0, oldfg_l=0, oldbg_l=0;
+static unsigned long oldfg_h=0, oldbg_h=0, oldfg=0, oldbg=0;
+
+
+extern int T1aa_SmartOn;        /* from t1aaset.c */
+extern float T1aa_smartlimit1;
+extern float T1aa_smartlimit2;
+
+
+
+static XColor aacolors[AAMAXPLANES];
+static unsigned long aapixels[AAMAXPLANES];
+
+
+/* The following parameter determines whether t1lib will use logical
+   positioning of chars and string (place the origin at specified
+   destination-point) or absolute positioning with respect to the
+   origin (upper left corner) of the generated bitmap/pixmap. */
+static int T1_lposition=1;
+
+
+
+/* T1_SetX11Params(): Set X11-parameters which t1lib has to know in order
+   to properly generate pixmaps from characters */
+int T1_SetX11Params( Display *display,
+		     Visual *visual,
+		     unsigned int depth,
+		     Colormap colormap)
+{
+
+  T1_display  =display;
+  T1_visual   =visual;
+  T1_depth    =depth;
+  T1_colormap =colormap;
+
+  if (T1_CheckEndian()==0)
+    T1_byte_order=0;
+  else
+    T1_byte_order=1;
+
+  /* For bug hunting: */
+  if (ImageByteOrder( T1_display)==0)
+    T1_PrintLog( "T1_SetX11Params()",
+		 "X-Server uses Little Endian data representation",
+		 T1LOG_DEBUG);
+  else
+    T1_PrintLog( "T1_SetX11Params()",
+		 "X-Server uses Big Endian data representation",
+		 T1LOG_DEBUG);
+  
+  return(0);
+}
+
+
+
+/* T1_SetCharX(): Generate an object of type GLYPH, i.e, a glyph with
+   a pixmap ID instead of a pointer to a bitmap: */
+
+GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		    int FontID, char charcode,
+		    float size, T1_TMATRIX *transform)
+{
+  GLYPH  *pglyph;
+  static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
+ 
+  int height, width;
+  Pixmap clipmask=0;
+  int opaque;
+  
+
+  xglyph.metrics.leftSideBearing=0;
+  xglyph.metrics.rightSideBearing=0;
+  xglyph.metrics.advanceX=0;
+  xglyph.metrics.advanceY=0;
+  xglyph.metrics.ascent=0;
+  xglyph.metrics.descent=0;
+  xglyph.pFontCacheInfo=NULL;
+  
+
+  opaque=mode;
+  
+  
+  if ((pglyph=T1_SetChar( FontID, charcode, size, transform))==NULL){
+    T1_PrintLog( "T1_SetCharX()",
+		 "T1_SetChar() returned NULL-pointer!",
+		 T1LOG_WARNING);
+    return(NULL);
+  }
+
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    xglyph=*pglyph;
+    return( &xglyph);
+  }
+  
+  width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
+  height=pglyph->metrics.ascent-pglyph->metrics.descent;
+  
+  
+  clipmask=XCreateBitmapFromData( T1_display,
+				  d,
+				  (char *)pglyph->bits,
+				  PAD(width, pFontBase->bitmap_pad),  
+				  height
+				  );
+				  
+  /* Correct position */
+  if (T1_lposition){
+    x_dest += pglyph->metrics.leftSideBearing;
+    y_dest -= pglyph->metrics.ascent;
+  }
+
+  if (opaque==0){
+    XSetClipMask(T1_display, gc, clipmask);
+    XSetClipOrigin(T1_display, gc, x_dest, y_dest);
+  }
+  
+  XCopyPlane( T1_display, clipmask, d, gc, 0, 0,
+	      width, height, x_dest, y_dest, 0x01);
+  
+  if (clipmask){
+    XFreePixmap( T1_display, clipmask);
+    clipmask=0;
+    XSetClipMask(T1_display, gc, None);
+    XSetClipOrigin(T1_display, gc, 0, 0);
+  }
+  
+  pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
+  xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
+  xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
+  xglyph.metrics.advanceX=pglyph->metrics.advanceX;
+  xglyph.metrics.advanceY=pglyph->metrics.advanceY;
+  xglyph.metrics.ascent=pglyph->metrics.ascent;
+  xglyph.metrics.descent=pglyph->metrics.descent;
+  xglyph.bpp=pglyph->bpp;
+  
+  return( &xglyph);
+  
+  
+}
+
+
+
+/* T1_SetStringX(...): Draw a string of characters into an X11 drawable */
+GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		      int FontID, char *string, int len, 
+		      long spaceoff, int modflag, float size,
+		      T1_TMATRIX *transform)
+{
+  GLYPH  *pglyph;
+  static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
+ 
+  int height, width;
+  Pixmap clipmask=0;
+  int opaque;
+  
+
+  xglyph.metrics.leftSideBearing=0;
+  xglyph.metrics.rightSideBearing=0;
+  xglyph.metrics.advanceX=0;
+  xglyph.metrics.advanceY=0;
+  xglyph.metrics.ascent=0;
+  xglyph.metrics.descent=0;
+  xglyph.pFontCacheInfo=NULL;
+  
+
+  opaque=mode;
+  
+
+  if ((pglyph=T1_SetString( FontID, string, len, 
+			    spaceoff, modflag, size,
+			    transform))==NULL){
+    T1_PrintLog( "T1_SetStringX()",
+		 "T1_SetString() returned NULL-pointer!",
+		 T1LOG_WARNING);
+    return(NULL);
+  }
+
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    xglyph=*pglyph;
+    return( &xglyph);
+  }
+
+  width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
+  height=pglyph->metrics.ascent-pglyph->metrics.descent;
+  
+  clipmask=XCreateBitmapFromData( T1_display,
+				  d,
+				  (char *)pglyph->bits,
+				  PAD(width, pFontBase->bitmap_pad), /* width */
+				  height
+				  );
+  
+  /* Correct position */
+  if (T1_lposition){
+    x_dest += pglyph->metrics.leftSideBearing;
+    y_dest -= pglyph->metrics.ascent;
+  }
+
+  if (opaque==0){
+    XSetClipMask(T1_display, gc, clipmask);
+    XSetClipOrigin(T1_display, gc, x_dest, y_dest);
+  }
+  
+  XCopyPlane( T1_display, clipmask, d, gc, 0, 0,
+	      width, height, x_dest, y_dest, 0x01);
+  
+  if (clipmask){
+    XFreePixmap( T1_display, clipmask);
+    clipmask=0;
+    XSetClipMask(T1_display, gc, None);
+    XSetClipOrigin(T1_display, gc, 0, 0);
+  }
+  
+  pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
+  xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
+  xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
+  xglyph.metrics.advanceX=pglyph->metrics.advanceX;
+  xglyph.metrics.advanceY=pglyph->metrics.advanceY;
+  xglyph.metrics.ascent=pglyph->metrics.ascent;
+  xglyph.metrics.descent=pglyph->metrics.descent;
+  xglyph.bpp=pglyph->bpp;
+  
+  return( &xglyph);
+  
+  
+}
+
+
+/* T1_SetRectX(): Draw a rectangle into an x11 drawable */
+
+GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		    int FontID, float size,
+		    float rwidth, float rheight,
+		    T1_TMATRIX *transform)
+{
+  GLYPH  *pglyph;
+  static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
+ 
+  int height, width;
+  Pixmap clipmask=0;
+  int opaque;
+  
+
+  xglyph.metrics.leftSideBearing=0;
+  xglyph.metrics.rightSideBearing=0;
+  xglyph.metrics.advanceX=0;
+  xglyph.metrics.advanceY=0;
+  xglyph.metrics.ascent=0;
+  xglyph.metrics.descent=0;
+  xglyph.pFontCacheInfo=NULL;
+  
+
+  opaque=mode;
+  
+  
+  if ((pglyph=T1_SetRect( FontID, size, rwidth, rheight, transform))==NULL){
+    T1_PrintLog( "T1_SetRectrX()",
+		 "T1_SetRect() returned NULL-pointer!",
+		 T1LOG_WARNING);
+    return(NULL);
+  }
+
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    xglyph=*pglyph;
+    return( &xglyph);
+  }
+  
+  width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
+  height=pglyph->metrics.ascent-pglyph->metrics.descent;
+  
+  
+  clipmask=XCreateBitmapFromData( T1_display,
+				  d,
+				  (char *)pglyph->bits,
+				  PAD(width, pFontBase->bitmap_pad),  
+				  height
+				  );
+				  
+  /* Correct position */
+  if (T1_lposition){
+    x_dest += pglyph->metrics.leftSideBearing;
+    y_dest -= pglyph->metrics.ascent;
+  }
+
+  if (opaque==0){
+    XSetClipMask(T1_display, gc, clipmask);
+    XSetClipOrigin(T1_display, gc, x_dest, y_dest);
+  }
+  
+  XCopyPlane( T1_display, clipmask, d, gc, 0, 0,
+	      width, height, x_dest, y_dest, 0x01);
+  
+  if (clipmask){
+    XFreePixmap( T1_display, clipmask);
+    clipmask=0;
+    XSetClipMask(T1_display, gc, None);
+    XSetClipOrigin(T1_display, gc, 0, 0);
+  }
+  
+  pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
+  xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
+  xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
+  xglyph.metrics.advanceX=pglyph->metrics.advanceX;
+  xglyph.metrics.advanceY=pglyph->metrics.advanceY;
+  xglyph.metrics.ascent=pglyph->metrics.ascent;
+  xglyph.metrics.descent=pglyph->metrics.descent;
+  xglyph.bpp=pglyph->bpp;
+  
+  return( &xglyph);
+  
+  
+}
+
+
+
+/* T1_AASetCharX(): Generate an object of type GLYPH, i.e, a glyph with
+   a pixmap ID instead of a pointer to a bitmap: */
+GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		      int FontID, char charcode,
+		      float size, T1_TMATRIX *transform)
+{
+  int j, k;
+
+  GLYPH  *pglyph;
+  XImage *ximage;
+
+  static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
+ 
+  int height, width, width_pad;
+  
+  XGCValues xgcvalues;
+  static unsigned long fg, bg;
+
+  Pixmap clipmask=0;
+  int clipmask_h, clipmask_v, line_off;
+  char *clipmask_ptr;
+  
+  int opaque;
+  
+
+	       
+  xglyph.metrics.leftSideBearing=0;
+  xglyph.metrics.rightSideBearing=0;
+  xglyph.metrics.advanceX=0;
+  xglyph.metrics.advanceY=0;
+  xglyph.metrics.ascent=0;
+  xglyph.metrics.descent=0;
+  xglyph.pFontCacheInfo=NULL;
+  
+
+  opaque=mode;
+  
+  xglyph.bpp=T1_depth;
+  
+  /* In order to be able to contruct the pixmap we need to know
+     foreground and background color as well the copy function */
+  XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues);
+  fg=xgcvalues.foreground;
+  bg=xgcvalues.background;
+  
+
+  /* At this point we must compute the colors that are needed to do
+     antialiasing between fore- and background. The following function
+     fills the static aacolors */
+  if (T1aa_SmartOn==0)
+    j=T1_AAGetLevel();
+  else if (size>=T1aa_smartlimit2)
+    j=1;
+  else if (size>=T1aa_smartlimit1)
+    j=2;
+  else
+    j=4;
+  if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){
+    switch ( j){
+    case 1:
+      if ( fg!=oldfg_n || bg!=oldbg_n){
+	oldfg_n=fg;
+	oldbg_n=bg;
+	/* computing colors is not necessary here */
+	T1_AANSetGrayValues( bg, fg);
+      }
+      break;
+    case 2:
+      if ( fg!=oldfg_l || bg!=oldbg_l){
+	T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
+	/*~derekn*/
+	/* If fg=bg, the clipmask will be messed up; in this case  */
+	/* we can arbitrarily change bg to get a correct clipmask. */
+	if (opaque == 0 && fg == bg)
+	  aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1;
+	oldfg_l=fg;
+	oldbg_l=bg;
+	T1_AASetGrayValues(aapixels[0],   /* white */
+			   aapixels[4],
+			   aapixels[8],
+			   aapixels[12],
+			   aapixels[16] ); /* black */
+      }
+      break;
+    case 4:
+      if ( fg!=oldfg_h || bg!=oldbg_h){
+	T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
+	/*~derekn*/
+	/* If fg=bg, the clipmask will be messed up; in this case  */
+	/* we can arbitrarily change bg to get a correct clipmask. */
+	if (opaque == 0 && fg == bg)
+	  aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1;
+	oldfg_h=fg;
+	oldbg_h=bg;
+	T1_AAHSetGrayValues( aapixels); 
+      }
+      break;
+    }
+    lastlevel=j;
+    oldfg=fg;
+    oldbg=bg;
+  }
+
+  if ((pglyph=T1_AASetChar( FontID, charcode, size,
+			    transform))==NULL){
+    T1_PrintLog( "T1_AASetCharX()",
+		 "T1_AASetChar() returned NULL-pointer!",
+		 T1LOG_WARNING);
+    return(NULL);
+  }
+
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    xglyph=*pglyph;
+    return( &xglyph);
+  }
+
+  width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
+  height=pglyph->metrics.ascent-pglyph->metrics.descent;
+  
+	       
+  /* Correct position */
+  if (T1_lposition){
+    x_dest += pglyph->metrics.leftSideBearing;
+    y_dest -= pglyph->metrics.ascent;
+  }
+
+  if (opaque==0){
+    clipmask_v=height;
+    clipmask_h=width;
+    width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp;
+    clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); 
+    if (clipmask_ptr==NULL){
+      T1_errno=T1ERR_ALLOC_MEM;
+      return(NULL);
+    }
+    /* Note: We pad the clipmask always to byte boundary */
+    if (pglyph->bpp==8)
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((char *)(pglyph->bits))[k*width_pad+j]!=bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    else if (pglyph->bpp==16)
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    else 
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    
+    clipmask=XCreateBitmapFromData( T1_display,
+				    d,
+				    (char *)clipmask_ptr,
+				    width,
+				    height
+				    );
+    free( clipmask_ptr);
+    XSetClipMask(T1_display, gc, clipmask);
+    XSetClipOrigin(T1_display, gc, x_dest, y_dest);
+
+  }
+  ximage=XCreateImage( T1_display,
+		       T1_visual,
+		       T1_depth, 
+		       ZPixmap, /* XYBitmap or XYPixmap */
+		       0, /* No offset */
+		       (char *)pglyph->bits,
+		       width,
+		       height,
+		       pFontBase->bitmap_pad,  
+		       0 /*PAD(width,8)/8*/  /* number of bytes per line */
+		       );
+  ximage->byte_order=T1_byte_order;
+  XPutImage(T1_display,
+	    d,
+	    gc,
+	    ximage,
+	    0,  
+	    0,  
+	    x_dest,  
+	    y_dest,  
+	    width,
+	    height
+	    );
+  XDestroyImage(ximage);
+  if (clipmask){
+    XFreePixmap( T1_display, clipmask);
+    clipmask=0;
+    XSetClipMask(T1_display, gc, None);
+    XSetClipOrigin(T1_display, gc, 0, 0);
+  }
+  
+  pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
+  xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
+  xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
+  xglyph.metrics.advanceX=pglyph->metrics.advanceX;
+  xglyph.metrics.advanceY=pglyph->metrics.advanceY;
+  xglyph.metrics.ascent=pglyph->metrics.ascent;
+  xglyph.metrics.descent=pglyph->metrics.descent;
+  xglyph.bpp=pglyph->bpp;
+  
+  return( &xglyph);
+  
+  
+}
+
+
+
+/* T1_AASetStringX(...): Draw a string of characters into an X11 drawable */
+GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+			int FontID, char *string, int len, 
+			long spaceoff, int modflag, float size,
+			T1_TMATRIX *transform)
+{
+  int  j, k;
+
+  GLYPH  *pglyph;
+  XImage *ximage;
+
+  
+  static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
+
+  int height, width, width_pad;
+  
+  XGCValues xgcvalues;
+  static unsigned long fg, bg;
+  
+
+  Pixmap clipmask=0;
+  int clipmask_h, clipmask_v, line_off;
+  char *clipmask_ptr;
+  
+  int opaque;
+  
+
+  xglyph.metrics.leftSideBearing=0;
+  xglyph.metrics.rightSideBearing=0;
+  xglyph.metrics.advanceX=0;
+  xglyph.metrics.advanceY=0;
+  xglyph.metrics.ascent=0;
+  xglyph.metrics.descent=0;
+  xglyph.pFontCacheInfo=NULL;
+  
+
+  opaque=mode;
+  
+  
+  /* In order to be able to contruct the pixmap we need to know
+     foreground and background color as well the copy function */
+  XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues);
+  fg=xgcvalues.foreground;
+  bg=xgcvalues.background;
+  
+  xglyph.bpp=T1_depth;
+  
+  /* At this point we must compute the colors that are needed to do
+     antialiasing between fore- and background. The following function
+     fills the static aacolors */
+  if (T1aa_SmartOn==0)
+    j=T1_AAGetLevel();
+  else if (size>=T1aa_smartlimit2)
+    j=1;
+  else if (size>=T1aa_smartlimit1)
+    j=2;
+  else
+    j=4;
+  if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){
+    switch ( j){
+    case 1:
+      if ( fg!=oldfg_n || bg!=oldbg_n){
+	oldfg_n=fg;
+	oldbg_n=bg;
+	/* computing colors is not necessary here */
+	T1_AANSetGrayValues( bg, fg);
+      }
+      break;
+    case 2:
+      if ( fg!=oldfg_l || bg!=oldbg_l){
+	T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
+	/*~derekn*/
+	/* If fg=bg, the clipmask will be messed up; in this case  */
+	/* we can arbitrarily change bg to get a correct clipmask. */
+	if (opaque == 0 && fg == bg)
+	  aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1;
+	oldfg_l=fg;
+	oldbg_l=bg;
+	T1_AASetGrayValues(aapixels[0],   /* white */
+			   aapixels[4],
+			   aapixels[8],
+			   aapixels[12],
+			   aapixels[16] ); /* black */
+      }
+      break;
+    case 4:
+      if ( fg!=oldfg_h || bg!=oldbg_h){
+	T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
+	/*~derekn*/
+	/* If fg=bg, the clipmask will be messed up; in this case  */
+	/* we can arbitrarily change bg to get a correct clipmask. */
+	if (opaque == 0 && fg == bg)
+	  aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1;
+	oldfg_h=fg;
+	oldbg_h=bg;
+	T1_AAHSetGrayValues( aapixels); 
+      }
+      break;
+    }
+    lastlevel=j;
+    oldfg=fg;
+    oldbg=bg;
+  }
+
+  
+  if ((pglyph=T1_AASetString( FontID, string, len, 
+			      spaceoff, modflag, size,
+			      transform))==NULL){
+    T1_PrintLog( "T1_AASetStringX()",
+		 "T1_AASetString() returned NULL-pointer!",
+		 T1LOG_WARNING);
+    return(NULL);
+  }
+
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    xglyph=*pglyph;
+    return( &xglyph);
+  }
+
+  width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
+  height=pglyph->metrics.ascent-pglyph->metrics.descent;
+  
+  
+  /* Correct position */
+  if (T1_lposition){
+    x_dest += pglyph->metrics.leftSideBearing;
+    y_dest -= pglyph->metrics.ascent;
+  }
+
+  if (opaque==0){
+    clipmask_v=height;
+    clipmask_h=width;
+    width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp;
+    clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char));
+    if (clipmask_ptr==NULL){
+      T1_errno=T1ERR_ALLOC_MEM;
+      return(NULL);
+    }
+    /* Note: We pad the clipmask always to byte boundary */
+    if (pglyph->bpp==8)
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((char *)(pglyph->bits))[k*width_pad+j]!=bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    else if (pglyph->bpp==16)
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    else 
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    
+    clipmask=XCreateBitmapFromData( T1_display,
+				    d,
+				    (char *)clipmask_ptr,
+				    width,
+				    height
+				    );
+    free( clipmask_ptr);
+    XSetClipMask(T1_display, gc, clipmask);
+    XSetClipOrigin(T1_display, gc, x_dest, y_dest);
+
+  }
+  ximage=XCreateImage( T1_display,
+		       T1_visual,
+		       T1_depth, 
+		       ZPixmap, /* XYBitmap or XYPixmap */
+		       0, /* No offset */
+		       (char *)pglyph->bits,
+		       width,
+		       height,
+		       pFontBase->bitmap_pad,  /* lines padded to bytes */
+		       0 /*PAD(width,8)/8*/  /* number of bytes per line */
+		       );
+  ximage->byte_order=T1_byte_order;
+  XPutImage(T1_display,
+	    d,
+	    gc,
+	    ximage,
+	    0,  
+	    0,  
+	    x_dest,  
+	    y_dest,  
+	    width,
+	    height
+	    );
+  XDestroyImage(ximage);
+  if (clipmask){
+    XFreePixmap( T1_display, clipmask);
+    clipmask=0;
+    XSetClipMask(T1_display, gc, None);
+    XSetClipOrigin(T1_display, gc, 0, 0);
+  }
+  
+  pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
+  xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
+  xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
+  xglyph.metrics.advanceX=pglyph->metrics.advanceX;
+  xglyph.metrics.advanceY=pglyph->metrics.advanceY;
+  xglyph.metrics.ascent=pglyph->metrics.ascent;
+  xglyph.metrics.descent=pglyph->metrics.descent;
+  xglyph.bpp=pglyph->bpp;
+  
+  return( &xglyph);
+  
+  
+}
+
+
+
+/* T1_AASetCharX(): Draw a rectangle into an x11 drawable */
+GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		      int FontID, float size,
+		      float rwidth, float rheight,
+		      T1_TMATRIX *transform)
+{
+  int j, k;
+
+  GLYPH  *pglyph;
+  XImage *ximage;
+
+  static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0};
+ 
+  int height, width, width_pad;
+  
+  XGCValues xgcvalues;
+  static unsigned long fg, bg;
+
+  Pixmap clipmask=0;
+  int clipmask_h, clipmask_v, line_off;
+  char *clipmask_ptr;
+  
+  int opaque;
+  
+
+	       
+  xglyph.metrics.leftSideBearing=0;
+  xglyph.metrics.rightSideBearing=0;
+  xglyph.metrics.advanceX=0;
+  xglyph.metrics.advanceY=0;
+  xglyph.metrics.ascent=0;
+  xglyph.metrics.descent=0;
+  xglyph.pFontCacheInfo=NULL;
+  
+
+  opaque=mode;
+  
+  xglyph.bpp=T1_depth;
+  
+  /* In order to be able to contruct the pixmap we need to know
+     foreground and background color as well the copy function */
+  XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues);
+  fg=xgcvalues.foreground;
+  bg=xgcvalues.background;
+  
+
+  /* At this point we must compute the colors that are needed to do
+     antialiasing between fore- and background. The following function
+     fills the static aacolors */
+  if (T1aa_SmartOn==0)
+    j=T1_AAGetLevel();
+  else if (size>=T1aa_smartlimit2)
+    j=1;
+  else if (size>=T1aa_smartlimit1)
+    j=2;
+  else
+    j=4;
+  if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){
+    switch ( j){
+    case 1:
+      if ( fg!=oldfg_n || bg!=oldbg_n){
+	oldfg_n=fg;
+	oldbg_n=bg;
+	/* computing colors is not necessary here */
+	T1_AANSetGrayValues( bg, fg);
+      }
+      break;
+    case 2:
+      if ( fg!=oldfg_l || bg!=oldbg_l){
+	T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
+	/*~derekn*/
+	/* If fg=bg, the clipmask will be messed up; in this case  */
+	/* we can arbitrarily change bg to get a correct clipmask. */
+	if (opaque == 0 && fg == bg)
+	  aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1;
+	oldfg_l=fg;
+	oldbg_l=bg;
+	T1_AASetGrayValues(aapixels[0],   /* white */
+			   aapixels[4],
+			   aapixels[8],
+			   aapixels[12],
+			   aapixels[16] ); /* black */
+      }
+      break;
+    case 4:
+      if ( fg!=oldfg_h || bg!=oldbg_h){
+	T1_ComputeAAColorsX( fg, bg, AAMAXPLANES);
+	/*~derekn*/
+	/* If fg=bg, the clipmask will be messed up; in this case  */
+	/* we can arbitrarily change bg to get a correct clipmask. */
+	if (opaque == 0 && fg == bg)
+	  aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1;
+	oldfg_h=fg;
+	oldbg_h=bg;
+	T1_AAHSetGrayValues( aapixels); 
+      }
+      break;
+    }
+    lastlevel=j;
+    oldfg=fg;
+    oldbg=bg;
+  }
+
+  if ((pglyph=T1_AASetRect( FontID, size, rwidth, rheight, transform))==NULL){
+    T1_PrintLog( "T1_AASetRectX()",
+		 "T1_AASetRect() returned NULL-pointer!",
+		 T1LOG_WARNING);
+    return(NULL);
+  }
+
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    xglyph=*pglyph;
+    return( &xglyph);
+  }
+
+  width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing;
+  height=pglyph->metrics.ascent-pglyph->metrics.descent;
+  
+	       
+  /* Correct position */
+  if (T1_lposition){
+    x_dest += pglyph->metrics.leftSideBearing;
+    y_dest -= pglyph->metrics.ascent;
+  }
+
+  if (opaque==0){
+    clipmask_v=height;
+    clipmask_h=width;
+    width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp;
+    clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); 
+    if (clipmask_ptr==NULL){
+      T1_errno=T1ERR_ALLOC_MEM;
+      return(NULL);
+    }
+    /* Note: We pad the clipmask always to byte boundary */
+    if (pglyph->bpp==8)
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((char *)(pglyph->bits))[k*width_pad+j]!=bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    else if (pglyph->bpp==16)
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    else 
+      for ( k=0; k<clipmask_v; k++){
+	line_off=k*(PAD(clipmask_h, 8)>>3);
+	for (j=0; j<clipmask_h; j++){
+	  if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg)
+	    clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8));
+	}
+      }
+    
+    clipmask=XCreateBitmapFromData( T1_display,
+				    d,
+				    (char *)clipmask_ptr,
+				    width,
+				    height
+				    );
+    free( clipmask_ptr);
+    XSetClipMask(T1_display, gc, clipmask);
+    XSetClipOrigin(T1_display, gc, x_dest, y_dest);
+
+  }
+  ximage=XCreateImage( T1_display,
+		       T1_visual,
+		       T1_depth, 
+		       ZPixmap, /* XYBitmap or XYPixmap */
+		       0, /* No offset */
+		       (char *)pglyph->bits,
+		       width,
+		       height,
+		       pFontBase->bitmap_pad,  
+		       0 /*PAD(width,8)/8*/  /* number of bytes per line */
+		       );
+  ximage->byte_order=T1_byte_order;
+  XPutImage(T1_display,
+	    d,
+	    gc,
+	    ximage,
+	    0,  
+	    0,  
+	    x_dest,  
+	    y_dest,  
+	    width,
+	    height
+	    );
+  XDestroyImage(ximage);
+  if (clipmask){
+    XFreePixmap( T1_display, clipmask);
+    clipmask=0;
+    XSetClipMask(T1_display, gc, None);
+    XSetClipOrigin(T1_display, gc, 0, 0);
+  }
+  
+  pglyph->bits=NULL;    /* Since XDestroyImage() free's this also! */
+  xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing;
+  xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing;
+  xglyph.metrics.advanceX=pglyph->metrics.advanceX;
+  xglyph.metrics.advanceY=pglyph->metrics.advanceY;
+  xglyph.metrics.ascent=pglyph->metrics.ascent;
+  xglyph.metrics.descent=pglyph->metrics.descent;
+  xglyph.bpp=pglyph->bpp;
+  
+  return( &xglyph);
+  
+  
+}
+
+
+
+/* T1_ComputeAAColorsX(): Compute the antialiasing colors in dependency
+   of foreground and background */
+int T1_ComputeAAColorsX( unsigned long fg, unsigned long bg, int nolevels)
+{
+
+  static unsigned long last_fg;
+  static unsigned long last_bg;
+  long delta_red, delta_green, delta_blue;
+  int i;
+  int nocolors=0;
+  
+  
+  aacolors[0].pixel=bg;
+  aacolors[nolevels-1].pixel=fg;
+
+  if ((fg==last_fg)&&(bg==last_bg))
+    return(nocolors);
+  
+  /* Get RGB values for fore- and background */
+  XQueryColor( T1_display, T1_colormap, &aacolors[0]);
+  XQueryColor( T1_display, T1_colormap, &aacolors[nolevels-1]);
+  delta_red   = (aacolors[nolevels-1].red - aacolors[0].red)/(nolevels-1);
+  delta_green = (aacolors[nolevels-1].green - aacolors[0].green)/(nolevels-1);
+  delta_blue  = (aacolors[nolevels-1].blue - aacolors[0].blue)/(nolevels-1);
+  aapixels[0]=aacolors[0].pixel;
+  aapixels[nolevels-1]=aacolors[nolevels-1].pixel;
+
+  for (i=1; i<nolevels-1; i++){
+    aacolors[i].red   = aacolors[0].red + i*delta_red;
+    aacolors[i].green = aacolors[0].green + i*delta_green;
+    aacolors[i].blue  = aacolors[0].blue + i*delta_blue;
+    aacolors[i].flags = DoRed | DoGreen | DoBlue;
+    aacolors[i].pad   = aacolors[0].pad;
+    /* Allocate color in current palette */
+    if (XAllocColor( T1_display, T1_colormap, &aacolors[i])!=0){
+      aapixels[i]=aacolors[i].pixel;
+      nocolors++;
+    }
+  }
+  
+  return(nocolors);
+
+}
+
+
+
+/* Set the positioning switch */
+void T1_LogicalPositionX( int pos_switch)
+{
+  if (pos_switch)
+    T1_lposition=1;
+  else
+    T1_lposition=0;
+  return;
+}
+
+
+
+XImage *T1_XImageFromGlyph( GLYPH *pglyph)
+{
+  XImage *ximage;
+  
+  /* Check for empty bitmap */
+  if (pglyph->bits==NULL) {
+    T1_errno=T1ERR_INVALID_PARAMETER;
+    return( NULL);
+  }
+
+  if (pglyph->bpp==1) { /* we have a bitmap glyph */
+    ximage=XCreateImage( T1_display,
+			 T1_visual,
+			 1, 
+			 XYBitmap, /* XYBitmap or XYPixmap */
+			 0, /* No offset */
+			 (char *)pglyph->bits,
+			 pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing,
+			 pglyph->metrics.ascent-pglyph->metrics.descent,
+			 pFontBase->bitmap_pad,  
+			 0  /* number of bytes per line */
+			 );
+  }
+  else { /* we have an anztialiased glyph */
+    ximage=XCreateImage( T1_display,
+			 T1_visual,
+			 T1_depth, 
+			 ZPixmap, /* XYBitmap or XYPixmap */
+			 0, /* No offset */
+			 (char *)pglyph->bits,
+			 pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing,
+			 pglyph->metrics.ascent-pglyph->metrics.descent,
+			 pFontBase->bitmap_pad,  
+			 0  /* number of bytes per line */
+			 );
+  }
+  
+  if (ximage==NULL) {
+    T1_errno=T1ERR_X11;
+    return( NULL);
+  }
+  ximage->byte_order=T1_byte_order; /* Set t1lib�s byteorder */
+
+  return( ximage);
+
+}
+
Index: grace/T1lib/t1lib/t1x11.h
===================================================================
--- /dev/null
+++ grace/T1lib/t1lib/t1x11.h
@@ -0,0 +1,103 @@
+/*--------------------------------------------------------------------------
+  ----- File:        t1x11.h
+  ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
+  ----- Date:        2003-01-02
+  ----- Description: This file is part of the t1-library. It contains
+                     definitions and declarations for t1x11.c.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003. 
+                     As of version 0.5, t1lib is distributed under the
+		     GNU General Public Library Lincense. The
+		     conditions can be found in the files LICENSE and
+		     LGPL, which should reside in the toplevel
+		     directory of the distribution.  Please note that 
+		     there are parts of t1lib that are subject to
+		     other licenses:
+		     The parseAFM-package is copyrighted by Adobe Systems
+		     Inc.
+		     The type1 rasterizer is copyrighted by IBM and the
+		     X11-consortium.
+  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
+  ----- Credits:     I want to thank IBM and the X11-consortium for making
+                     their rasterizer freely available.
+		     Also thanks to Piet Tutelaers for his ps2pk, from
+		     which I took the rasterizer sources in a format
+		     independent from X11.
+                     Thanks to all people who make free software living!
+--------------------------------------------------------------------------*/
+
+#include <X11/Xlib.h>
+
+#ifdef T1X11_C
+
+int T1_SetX11Params( Display *display,
+		     Visual *visual,
+		     unsigned int depth,
+		     Colormap colormap);
+GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x, int y,
+		    int FontID, char charcode,
+		    float size, T1_TMATRIX *transform);
+GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x, int y,
+		      int FontID, char *string, int len,
+		      long spaceoff, int modflag,
+		      float size, T1_TMATRIX *transform);
+GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		    int FontID, float size,
+		    float width, float height,
+		    T1_TMATRIX *transform);
+GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x, int y,
+		      int FontID, char charcode,
+		      float size, T1_TMATRIX *transform);
+GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x, int y,
+			int FontID, char *string, int len,
+			long spaceoff, int modflag,
+			float size, T1_TMATRIX *transform);
+GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+		      int FontID, float size,
+		      float width, float height,
+		      T1_TMATRIX *transform);
+int T1_ComputeAAColorsX( unsigned long fg,
+			 unsigned long bg,
+			 int nolevels);
+int T1_GetDepthOfDrawable( Drawable drawable);
+void T1_LogicalPositionX( int pos_switch);
+
+
+#else
+
+extern Display *T1_display;
+
+extern int T1_SetX11Params( Display *display,
+			    Visual *visual,
+			    unsigned int depth,
+			    Colormap colormap);
+extern GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x, int y,
+			   int FontID, char charcode,
+			   float size, T1_TMATRIX *transform);
+extern GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x, int y,
+			     int FontID, char *string, int len,
+			     long spaceoff, int modflag,
+			     float size, T1_TMATRIX *transform);
+extern GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+			   int FontID, float size,
+			   float width, float height,
+			   T1_TMATRIX *transform);
+extern GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x, int y,
+			     int FontID, char charcode,
+			     float size, T1_TMATRIX *transform);
+extern GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x, int y,
+			       int FontID, char *string, int len,
+			       long spaceoff, int modflag,
+			       float size, T1_TMATRIX *transform);
+extern GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest,
+			     int FontID, float size,
+			     float width, float height,
+			     T1_TMATRIX *transform);
+extern int T1_ComputeAAColorsX( unsigned long fg,
+				unsigned long bg,
+				int nolevels);
+extern int T1_GetDepthOfDrawable( Drawable drawable);
+extern void T1_LogicalPositionX( int pos_switch);
+
+
+#endif
+
Index: grace/T1lib/type1/.dependencies
===================================================================
--- grace.orig/T1lib/type1/.dependencies
+++ grace/T1lib/type1/.dependencies
@@ -4,18 +4,18 @@ curves.lo: curves.c types.h objects.h sp
  curves.h lines.h arith.h
 fontfcn.lo: fontfcn.c t1imager.h types.h fontmisc.h util.h fontfcn.h \
  paths_rmz.h spaces_rmz.h ../t1lib/parseAFM.h ../t1lib/t1types.h \
- ../t1lib/t1extern.h ../t1lib/t1misc.h ../t1lib/t1base.h \
- ../t1lib/t1finfo.h
+ ../t1lib/sysconf.h ../t1lib/t1extern.h ../t1lib/t1misc.h \
+ ../t1lib/t1base.h ../t1lib/t1finfo.h
 hints.lo: hints.c types.h objects.h spaces.h paths.h regions.h hints.h
-lines.lo: lines.c types.h objects.h spaces.h regions.h lines.h
+lines.lo: lines.c types.h objects.h spaces.h paths.h regions.h lines.h
 objects.lo: objects.c types.h objects.h spaces.h paths.h regions.h \
  fonts.h pictures.h strokes.h cluts.h
 paths.lo: paths.c types.h objects.h spaces.h paths.h regions.h fonts.h \
  pictures.h strokes.h trig.h
-regions.lo: regions.c types.h objects.h spaces.h regions.h paths.h \
+regions.lo: regions.c types.h objects.h spaces.h paths.h regions.h \
  curves.h lines.h pictures.h fonts.h hints.h strokes.h
 scanfont.lo: scanfont.c t1stdio.h types.h util.h token.h fontfcn.h \
- blues.h
+ blues.h ../t1lib/t1misc.h
 spaces.lo: spaces.c types.h objects.h spaces.h paths.h pictures.h \
  fonts.h arith.h trig.h
 t1io.lo: t1io.c t1stdio.h types.h t1hdigit.h
Index: grace/T1lib/type1/fontfcn.c
===================================================================
--- grace.orig/T1lib/type1/fontfcn.c
+++ grace/T1lib/type1/fontfcn.c
@@ -46,16 +46,24 @@
 #include "../t1lib/t1base.h"
 #include "../t1lib/t1finfo.h"
 
+/* Note: The argument decodeonly is used to make Type1Char() decode only
+         such that later certain characterictics of the pass can be queried
+	 (here, information about the parts of a seac).
+*/
 extern xobject Type1Char(psfont *env, struct XYspace *S,
 			 psobj *charstrP, psobj *subrsP,
 			 psobj *osubrsP,
 			 struct blues_struct *bluesP,
-			 int *modeP, char *name);
+			 int *modeP, char *name,
+			 float strokewidth,
+			 int decodeonly);
 extern xobject Type1Line(psfont *env, struct XYspace *S,
-				 float line_position,
-				 float line_thickness,
-				 float line_length);
-extern  boolean Init_BuiltInEncoding( void);
+			 float line_position,
+			 float line_thickness,
+			 float line_length,
+			 float strokewidth);
+extern int T1int_Type1QuerySEAC( unsigned char* base,
+				 unsigned char* accent);
 void objFormatName(psobj *objP, int length, char *valueP);
   
 extern void T1io_reset( void);
@@ -64,13 +72,49 @@ extern void T1io_reset( void);
 #define LINETYPE   0x10+0x00
 #define MOVETYPE   0x10+0x05
 
+#if 1
+struct region {
+  XOBJ_COMMON           /* xobject common data define 3-26-91 PNM    */
+  /* type = REGIONTYPE                         */
+  struct fractpoint origin;    /* beginning handle:  X,Y origin of region      */
+  struct fractpoint ending;    /* ending handle:  X,Y change after painting region */
+  pel xmin,ymin;        /* minimum X,Y of region                        */
+  pel xmax,ymax;        /* mat1_mum X,Y of region                        */
+  struct edgelist *anchor;  /* list of edges that bound the region      */
+  struct picture *thresholded;  /* region defined by thresholded picture*/
+  /*
+    Note that the ending handle and the bounding box values are stored
+    relative to 'origin'.
+    
+    The above elements describe a region.  The following elements are
+    scratchpad areas used while the region is being built:
+  */
+  fractpel lastdy;      /* direction of last segment                    */
+  fractpel firstx,firsty;    /* starting point of current edge          */
+  fractpel edgexmin,edgexmax;  /* x extent of current edge              */
+  struct edgelist *lastedge,*firstedge;  /* last and first edges in subpath */
+  pel *edge;            /* pointer to array of X values for edge        */
+  fractpel edgeYstop;   /* Y value where 'edges' array ends             */
+  int (*newedgefcn)();  /* function to use when building a new edge     */
+  struct strokeinfo *strokeinfo;  /* scratchpad info during stroking only */
+} ;
+struct edgelist {
+  XOBJ_COMMON          /* xobject common data define 3-26-91 PNM        */
+  /* type = EDGETYPE                               */
+  struct edgelist *link;  /* pointer to next in linked list             */
+  struct edgelist *subpath;  /* informational link for "same subpath"   */
+  pel xmin,xmax;        /* range of edge in X                           */
+  pel ymin,ymax;        /* range of edge in Y                           */
+  pel *xvalues;         /* pointer to ymax-ymin X values                */
+};
+#endif
 
 /***================================================================***/
 /*   GLOBALS                                                          */
 /***================================================================***/
 static char CurCharName[257]="";
 static char BaseCharName[257]="";
-char CurFontName[120];
+char CurFontName[MAXPATHLEN+1];
 char *CurFontEnv;
 char *vm_base = NULL;
 
@@ -119,7 +163,6 @@ boolean initFont()
 {
   if (!(vm_init())) return(FALSE);
   vm_base = vm_next_byte();
-  if (!(Init_BuiltInEncoding())) return(FALSE);
   strcpy(CurFontName, "");    /* iniitialize to none */
   FontP->vm_start = vm_next_byte();
   FontP->FontFileName.len = 0;
@@ -140,7 +183,8 @@ char *env;
   FontP->fontInfoP = NULL;
   FontP->BluesP = NULL;
   /* This will load the font into the FontP */
-  strcpy(CurFontName,env);
+  strncpy(CurFontName,env, MAXPATHLEN);
+  CurFontName[MAXPATHLEN] = '\0';
   FontP->FontFileName.len = strlen(CurFontName);
   FontP->FontFileName.data.nameP = CurFontName;
   T1io_reset();
@@ -241,7 +285,8 @@ xobject fontfcnB(int FontID, int modflag
 		 struct XYspace *S, char **ev,
 		 unsigned char index, int *mode,
 		 psfont *Font_Ptr,
-		 int do_raster)
+		 int do_raster,
+		 float strokewidth)
 {
  
   psobj *charnameP; /* points to psobj that is name of character*/
@@ -337,7 +382,7 @@ xobject fontfcnB(int FontID, int modflag
   /* get CharString and character path */
   theStringP = &(CharStringsDictP[basechar].value);
   tmppath2 = (struct segment *) Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
-					  FontP->BluesP,mode,CurCharName);
+					  FontP->BluesP,mode,CurCharName,strokewidth,0);
   /* if Type1Char reported an error, then return */
   if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR)
     return(NULL);
@@ -378,7 +423,7 @@ xobject fontfcnB(int FontID, int modflag
     strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len);
     CurCharName[charnameP->len]='\0';
     charpath=(struct segment *)Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
-					 FontP->BluesP,mode,CurCharName);
+					 FontP->BluesP,mode,CurCharName,strokewidth,0);
     /* return if Type1Char reports an error */
     if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR)
       return(NULL);
@@ -593,7 +638,8 @@ xobject fontfcnB_string( int FontID, int
 			 unsigned char *string, int no_chars,
 			 int *mode, psfont *Font_Ptr,
 			 int *kern_pairs, long spacewidth,
-			 int do_raster)
+			 int do_raster,
+			 float strokewidth)
 {
  
   psobj *charnameP; /* points to psobj that is name of character*/
@@ -714,7 +760,7 @@ xobject fontfcnB_string( int FontID, int
       /* get CharString and character path */
       theStringP = &(CharStringsDictP[basechar].value);
       tmppath2 = (struct segment *) Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
-					      FontP->BluesP,mode,CurCharName);
+					      FontP->BluesP,mode,CurCharName,strokewidth,0);
       strcpy( BaseCharName, CurCharName);
       /* if Type1Char reports an error, clean up and return */
       if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR) {
@@ -790,7 +836,7 @@ xobject fontfcnB_string( int FontID, int
 	strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len);
 	CurCharName[charnameP->len]='\0';
 	tmppath5=(struct segment *)Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
-					     FontP->BluesP,mode,CurCharName);
+					     FontP->BluesP,mode,CurCharName,strokewidth,0);
 	/* return if Type1Char reports an error */
 	if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR)
 	  return(NULL);
@@ -873,21 +919,21 @@ xobject fontfcnB_string( int FontID, int
     tmppath2=(struct segment *)Type1Line(FontP,S,
 					 pFontBase->pFontArray[FontID].UndrLnPos,
 					 pFontBase->pFontArray[FontID].UndrLnThick,
-					 (float) acc_width);
+					 (float) acc_width,strokewidth);
     charpath=(struct segment *)Join(charpath,tmppath2);
   }
   if (modflag & T1_OVERLINE){
     tmppath2=(struct segment *)Type1Line(FontP,S,
 					 pFontBase->pFontArray[FontID].OvrLnPos,
 					 pFontBase->pFontArray[FontID].OvrLnThick,
-					 (float) acc_width);
+					 (float) acc_width,strokewidth);
     charpath=(struct segment *)Join(charpath,tmppath2);
   }
   if (modflag & T1_OVERSTRIKE){
     tmppath2=(struct segment *)Type1Line(FontP,S,
 					 pFontBase->pFontArray[FontID].OvrStrkPos,
 					 pFontBase->pFontArray[FontID].OvrStrkThick,
-					 (float) acc_width);
+					 (float) acc_width,strokewidth);
     charpath=(struct segment *)Join(charpath,tmppath2);
   }
   
@@ -1012,7 +1058,7 @@ xobject fontfcnB_ByName( int FontID, int
   /* get CharString and character path */
   theStringP = &(CharStringsDictP[basechar].value);
   tmppath2 = (struct segment *) Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
-					  FontP->BluesP,mode,CurCharName);
+					  FontP->BluesP,mode,CurCharName, 0.0f, 0);
   /* if Type1Char reported an error, then return */
   if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR)
     return(NULL);
@@ -1053,7 +1099,7 @@ xobject fontfcnB_ByName( int FontID, int
     strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len);
     CurCharName[charnameP->len]='\0';
     charpath=(struct segment *)Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
-					 FontP->BluesP,mode,CurCharName);
+					 FontP->BluesP,mode,CurCharName,0.0f,0);
     /* return if Type1Char reports an error */
     if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR)
       return(NULL);
@@ -1103,3 +1149,118 @@ xobject fontfcnB_ByName( int FontID, int
 
 }
 
+
+xobject fontfcnRect( float width,
+		     float height,
+		     struct XYspace* S,
+		     int *mode,
+		     int do_raster,
+		     float strokewidth)
+{
+  struct segment *charpath = NULL;   /* the path for this character (rectangle)  */           
+  
+  charpath = (struct segment *) Type1Line( NULL, S,
+					   0.5f * height,    /* position */
+					   height,           /* thickness */
+					   -width,            /* width */
+					   strokewidth       /* strokewidth */
+					   );
+  
+  if (do_raster) { 
+    /* fill with winding rule unless path was requested */
+    if (*mode != FF_PATH) {
+      charpath =  (struct segment *)Interior(charpath,WINDINGRULE+CONTINUITY);
+    }
+  }
+
+  return((xobject) charpath);
+  
+}
+
+
+
+/* T1int_QuerySEAC(): Query for Type of character definition of index "index".
+
+   Returns: 0     if charstring for currenc[index] not defined
+            1     if charstring defines a self-containing character
+	    2     if charstring references other definition by means of
+	          the SEAC directive.
+*/
+int T1int_QuerySEAC( int FontID, 
+		     unsigned char index,
+		     unsigned char* basepiece,
+		     unsigned char* accpiece
+		     )
+{
+  
+  psobj *charnameP; /* points to psobj that is name of character*/
+  int thischar;
+  int mode = 0;
+  
+  psdict *CharStringsDictP; /* dictionary with char strings     */
+  psobj   CodeName;   /* used to store the translation of the name*/
+  psobj  *SubrsArrayP;
+  psobj  *theStringP;
+  char **ev;
+  struct XYspace *S;
+  struct segment *path=NULL;   /* the path for this character   */           
+  
+   
+  /* set the global font pointer to the address of already allocated
+     structure and setup pointers*/
+  FontP=pFontBase->pFontArray[FontID].pType1Data;
+  CharStringsDictP =  FontP->CharStringsP;
+  SubrsArrayP = &(FontP->Subrs);
+  charnameP = &CodeName;
+
+  /* get encoding */
+  ev=pFontBase->pFontArray[FontID].pFontEnc;
+
+  if (ev==NULL){  /* font-internal encoding should be used */
+    charnameP->len = FontP->fontInfoP[ENCODING].value.data.arrayP[index].len;
+    charnameP->data.stringP = (unsigned char *) FontP->fontInfoP[ENCODING].value.data.arrayP[index].data.arrayP;
+  }
+  else{           /* some user-supplied encoding is to be used */
+    charnameP->len = strlen(ev[index]);
+    charnameP->data.stringP = (unsigned char *) ev[index];
+  }
+  strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len);
+  CurCharName[charnameP->len]='\0';
+  
+ 
+  /* search the chars string for this charname as key */
+  thischar = SearchDictName(CharStringsDictP,charnameP);
+  /* thischar is now the index of the base character in the CharStrings
+     dictionary */
+
+  if ( thischar <= 0 ) {
+    /* CharString not defined, return */
+    return 0;
+  }
+
+  /* Setup NULL-space, not needed when paths aren't created */
+  S = NULL; 
+      
+  
+  /* we provide the Type1Char() procedure with the name of the character
+     to rasterize for debugging purposes */
+  strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len);
+  CurCharName[charnameP->len]='\0';
+  /* get CharString and character path */
+  theStringP = &(CharStringsDictP[thischar].value);
+  
+  path = (struct segment *) Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
+				      FontP->BluesP,&mode,CurCharName,0, 1);
+
+  /* if Type1Char reported an error, then return */
+  if ( mode == FF_PARSE_ERROR || mode==FF_PATH_ERROR) {
+    return -1;
+  }
+
+  if ( T1int_Type1QuerySEAC( basepiece, accpiece) > 0 ) {
+    return 2;
+  }
+
+  return 1;
+
+}
Index: grace/T1lib/type1/fontstruct.h
===================================================================
--- grace.orig/T1lib/type1/fontstruct.h
+++ grace/T1lib/type1/fontstruct.h
@@ -1,4 +1,4 @@
-/* $Header: /home/fnevgeny/cvsroot/grace/T1lib/type1/fontstruct.h,v 1.3 1999/09/07 20:51:21 fnevgeny Exp $ */
+/* $Header: fontstruct.h,v 1.10 91/07/22 15:37:41 keith Exp $ */
 /***********************************************************
 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
Index: grace/T1lib/type1/hints.c
===================================================================
--- grace.orig/T1lib/type1/hints.c
+++ grace/T1lib/type1/hints.c
@@ -369,30 +369,37 @@ static pel SearchXofY(edge, y)
        register struct edgelist *edge;  /* represents edge                   */
        register pel y;       /* 'y' value to find edge for                   */
 {
-       register struct edgelist *e;  /* loop variable                        */
- 
-       if (y < edge->ymin) {
-               if (ISTOP(edge->flag))
-                       return(MINPEL);
-               for (e = edge->subpath; e->subpath != edge; e = e->subpath) { ; }
-               if (e->ymax == edge->ymin)
-                        return(XofY(e, y));
-       }
-       else if (y >= edge->ymax) {
-               if (ISBOTTOM(edge->flag))
-                       return(MINPEL);
-               e = edge->subpath;
-               if (e->ymin == edge->ymax)
-                         return(XofY(e, y));
-       }
-       else
-               return(XofY(edge, y));
- 
-       abort("bad subpath chain", 11);
-       /*NOTREACHED*/
-       /* To make ANSI-C-compiler happy: */
-       return(y);
-       
+  register struct edgelist *e;  /* loop variable                        */
+  
+  if (y < edge->ymin) {
+    if (ISTOP(edge->flag)) {
+      return(MINPEL);
+    }
+    
+    for (e = edge->subpath; e->subpath != edge; e = e->subpath) { ; }
+    if (e->ymax == edge->ymin) {
+      return(XofY(e, y));
+    }
+  }
+  else if (y >= edge->ymax) {
+    if (ISBOTTOM(edge->flag)) {
+      return(MINPEL);
+    }
+    e = edge->subpath;
+    if (e->ymin == edge->ymax) {
+      return(XofY(e, y));
+    }
+  }
+  else {
+    return(XofY(edge, y));
+  }
+  
+  
+  abort("bad subpath chain", 11);
+  /*NOTREACHED*/
+  /* To make ANSI-C-compiler happy: */
+  return(y);
+  
 }
 /*
 :h3.ISBREAK() Macro - Tests if an Edge List is at a "Break"
@@ -495,139 +502,166 @@ Also, this routine sets the ISTOP and IS
 static void FixSubPaths(R)
        register struct region *R;       /* anchor of region                */
 {
-       register struct edgelist *e;     /* fast loop variable                */
-       register struct edgelist *edge;  /* current edge in region            */
-       register struct edgelist *next;  /* next in subpath after 'edge'      */
-       register struct edgelist *break1;  /* first break after 'next'        */
-       register struct edgelist *break2=NULL; /* last break before 'edge'        */
-       register struct edgelist *prev;    /* previous edge for fixing links  */
-       int left = TRUE;
- 
-       for (edge = R->anchor; edge != NULL; edge = edge->link) {
- 
-               if (left)
-                       edge->flag |= ISLEFT(ON);
-               left = !left;
- 
-               next = edge->subpath;
- 
-               if (!ISBREAK(edge, next))
-                       continue;
-               if (edge->ymax < next->ymin)
-                       abort("disjoint subpath?", 13);
-/*
-'edge' now contains an edgelist at the bottom of an edge, and 'next'
-contains the next subsequent edgelist in the subpath, which must be at
-the top.  We refer to this a "break" in the subpath.
-*/
-               next->flag |= ISTOP(ON);
-               edge->flag |= ISBOTTOM(ON);
- 
-               if (ISDOWN(edge->flag) != ISDOWN(next->flag))
-                       continue;
-/*
-We are now in the unusual case; both edges are going in the same
-direction so this must be a "false break" due to the way that the user
-created the path.  We'll have to fix it.
-*/
-               for (break1 = next; !ISBREAK(break1, break1->subpath); break1 = break1->subpath) { ; }
- 
-               for (e = break1->subpath; e != edge; e = e->subpath)
-                       if (ISBREAK(e, e->subpath))
-                               break2 = e;
-/*
-Now we've set up 'break1' and 'break2'.  I've found the following
-diagram invaluable.  'break1' is the first break after 'next'.  'break2'
-is the LAST break before 'edge'.
-&drawing.
-         next
-        +------+     +---->+------+
-   +--->|    >-----+ |     |    >-----+
-   |    |      |   | |     |      |   |
-   | +-------------+ |  +-------------+
-   | |  |break1|     |  |  |      |
-   | +->|    >-------+  +->|    >-----+
-   |    |      |           |      |   |
-   |    |      |        +-------------+
-   |    +------+        |  |      |
-   | +----------------+ |  |      |
-   | |  +------+      | +->|    >-----+
-   | +->|    >-----+  |    |      |   |
-   |    |      |   |  | +-------------+
-   | +-------------+  | |  |      |
-   | |  |edge  |      | |  |break2|
-   | +->|    >-----+  | +->|    >-----+
-   |    |      |   |  |    |      |   |
-   |    |      |   |  |    |      |   |
-   |    |      |   |  |    |      |   |
-   |    +------+   |  |    +------+   |
-   |               |  |               |
-   +---------------+  +---------------+
- 
-&edrawing.
-We want to fix this situation by having 'edge' point to where 'break1'
-now points, and having 'break1' point to where 'break2' now points.
-Finally, 'break2' should point to 'next'.  Also, we observe that
-'break1' can't be a bottom, and is also not a top unless it is the same
-as 'next':
-*/
-               edge->subpath = break1->subpath;
- 
-               break1->subpath = break2->subpath;
-               if (ISBREAK(break1, break1->subpath))
-                       abort("unable to fix subpath break?", 14);
- 
-               break2->subpath = next;
- 
-               break1->flag &= ~ISBOTTOM(ON);
-               if (break1 != next)
-                       break1->flag &= ~ISTOP(ON);
-       }
-/*
-This region might contain "ambiguous" edges; edges exactly equal to
-edge->link.  Due to the random dynamics of where they get sorted into
-the list, they can yield false crossings, where the edges appear
-to cross.  This confuses our continuity logic no end.  Since we can
-swap them without changing the region, we do.
-*/
-       for (edge = R->anchor, prev = NULL; VALIDEDGE(edge); prev = edge, edge = prev->link) {
- 
-               if (! ISAMBIGUOUS(edge->flag))
-                       continue;
- 
-               next = edge->subpath;
- 
-               while (ISAMBIGUOUS(next->flag) && next != edge)
-                       next = next->subpath;
-/*
-We've finally found a non-ambiguous edge; we make sure it is left/right
-compatible with 'edge':
-*/
-               if ( (ISLEFT(edge->flag) == ISLEFT(next->flag) && ISDOWN(edge->flag) == ISDOWN(next->flag) )
-                    || (ISLEFT(edge->flag) != ISLEFT(next->flag) && ISDOWN(edge->flag) != ISDOWN(next->flag) ) )
-                       continue;
- 
-/*
-Incompatible, we will swap 'edge' and the following edge in the list.
-You may think that there must be a next edge in this swath.  So did I.
-No!  If there is a totally ambiguous inner loop, for example, we could
-get all the way to the outside without resolving ambiguity.
-*/
-               next = edge->link;  /* note new meaning of 'next' */
-               if (next == NULL || edge->ymin != next->ymin)
-                       continue;
-               if (prev == NULL)
-                       R->anchor = next;
-               else
-                       prev->link = next;
-               edge->link = next->link;
-               next->link = edge;
-               edge->flag ^= ISLEFT(ON);
-               edge->flag &= ~ISAMBIGUOUS(ON);
-               next->flag ^= ISLEFT(ON);
-               next->flag &= ~ISAMBIGUOUS(ON);
-               edge = next;
-       }
+  register struct edgelist *e;     /* fast loop variable                */
+  register struct edgelist *edge;  /* current edge in region            */
+  register struct edgelist *next;  /* next in subpath after 'edge'      */
+  register struct edgelist *break1;  /* first break after 'next'        */
+  register struct edgelist *break2=NULL; /* last break before 'edge'        */
+  register struct edgelist *prev;    /* previous edge for fixing links  */
+  int left = TRUE;
+  
+  for (edge = R->anchor; edge != NULL; edge = edge->link) {
+	 
+    if (left)
+      edge->flag |= ISLEFT(ON);
+    left = !left;
+    
+    next = edge->subpath;
+    
+    if (!ISBREAK(edge, next))
+      continue;
+    if (edge->ymax < next->ymin)
+      abort("disjoint subpath?", 13);
+    /*
+      'edge' now contains an edgelist at the bottom of an edge, and 'next'
+      contains the next subsequent edgelist in the subpath, which must be at
+      the top.  We refer to this a "break" in the subpath.
+    */
+    next->flag |= ISTOP(ON);
+    edge->flag |= ISBOTTOM(ON);
+    
+    if (ISDOWN(edge->flag) != ISDOWN(next->flag))
+      continue;
+    /*
+      We are now in the unusual case; both edges are going in the same
+      direction so this must be a "false break" due to the way that the user
+      created the path.  We'll have to fix it.
+    */
+    for (break1 = next; !ISBREAK(break1, break1->subpath); break1 = break1->subpath) { ; }
+    
+    for (e = break1->subpath; e != edge; e = e->subpath)
+      if (ISBREAK(e, e->subpath))
+	break2 = e;
+    /*
+      Now we've set up 'break1' and 'break2'.  I've found the following
+      diagram invaluable.  'break1' is the first break after 'next'.  'break2'
+      is the LAST break before 'edge'.
+      &drawing.
+      next
+      +------+     +---->+------+
+      +--->|    >-----+ |     |    >-----+
+      |    |      |   | |     |      |   |
+      | +-------------+ |  +-------------+
+      | |  |break1|     |  |  |      |
+      | +->|    >-------+  +->|    >-----+
+      |    |      |           |      |   |
+      |    |      |        +-------------+
+      |    +------+        |  |      |
+      | +----------------+ |  |      |
+      | |  +------+      | +->|    >-----+
+      | +->|    >-----+  |    |      |   |
+      |    |      |   |  | +-------------+
+      | +-------------+  | |  |      |
+      | |  |edge  |      | |  |break2|
+      | +->|    >-----+  | +->|    >-----+
+      |    |      |   |  |    |      |   |
+      |    |      |   |  |    |      |   |
+      |    |      |   |  |    |      |   |
+      |    +------+   |  |    +------+   |
+      |               |  |               |
+      +---------------+  +---------------+
+      
+      &edrawing.
+      We want to fix this situation by having 'edge' point to where 'break1'
+      now points, and having 'break1' point to where 'break2' now points.
+      Finally, 'break2' should point to 'next'.  Also, we observe that
+      'break1' can't be a bottom, and is also not a top unless it is the same
+      as 'next':
+    */
+    edge->subpath = break1->subpath;
+    
+    break1->subpath = break2->subpath;
+    if (ISBREAK(break1, break1->subpath))
+      abort("unable to fix subpath break?", 14);
+    
+    break2->subpath = next;
+    
+    break1->flag &= ~ISBOTTOM(ON);
+    if (break1 != next)
+      break1->flag &= ~ISTOP(ON);
+  }
+  
+  /*
+    This region might contain "ambiguous" edges; edges exactly equal to
+    edge->link.  Due to the random dynamics of where they get sorted into
+    the list, they can yield false crossings, where the edges appear
+    to cross.  This confuses our continuity logic no end.  Since we can
+    swap them without changing the region, we do.
+  */
+  for (edge = R->anchor, prev = NULL; VALIDEDGE(edge); prev = edge, edge = prev->link) {
+    
+    if (! ISAMBIGUOUS(edge->flag)) {
+      continue;
+    }
+    
+    next = edge->subpath;
+    
+    while (ISAMBIGUOUS(next->flag) && next != edge) {
+      next = next->subpath;
+    }
+    
+    /*
+      We've finally found a non-ambiguous edge; we make sure it is left/right
+      compatible with 'edge':
+    */
+    if ( (ISLEFT(edge->flag) == ISLEFT(next->flag) && ISDOWN(edge->flag) == ISDOWN(next->flag) )
+	 || (ISLEFT(edge->flag) != ISLEFT(next->flag) && ISDOWN(edge->flag) != ISDOWN(next->flag) ) ) {
+      continue;
+    }
+    
+    /*
+      Incompatible, we will swap 'edge' and the following edge in the list.
+      You may think that there must be a next edge in this swath.  So did I.
+      No!  If there is a totally ambiguous inner loop, for example, we could
+      get all the way to the outside without resolving ambiguity.
+    */
+    next = edge->link;  /* note new meaning of 'next' */
+    if (next == NULL || edge->ymin != next->ymin) {
+      continue;
+    }
+    
+    /* 
+       printf("      Swap:                \n");
+       printf("            Edge=0x%x, ymin=%d, ymax=%d, xmin=%d, xmax=%d, fpx1=%ld, fpx2=%ld\n",
+       edge, edge->ymin, edge->ymax, edge->xmin, edge->xmax, edge->fpx1, edge->fpx2);
+       printf("            Link=0x%x, ymin=%d, ymax=%d, xmin=%d, xmax=%d, fpx1=%ld, fpx2=%ld\n",
+       next, next->ymin, next->ymax, next->xmin, next->xmax, next->fpx1, next->fpx2);
+       printf("            Edge=0x%x (amb=%d), x[ymin]=%d, x[ymax]=%d, px1=%ld, px2=%ld\n",
+       edge, ISAMBIGUOUS(edge->flag), edge->xvalues[0], edge->xvalues[edge->ymax - edge->ymin],
+       edge->fpx1>>FRACTBITS, edge->fpx2>>FRACTBITS);
+       printf("            Link=0x%x (amb=%d), x[ymin]=%d, x[ymax]=%d, px1=%ld, px2=%ld\n",
+       next, ISAMBIGUOUS(next->flag), next->xvalues[0], next->xvalues[next->ymax - next->ymin],
+       next->fpx1>>FRACTBITS, next->fpx2>>FRACTBITS);
+    */
+
+    /* Check ambiguity also for link edge (RMz) */
+    if ( !ISAMBIGUOUS(next->flag) ) {
+      continue;
+    }
+    
+    
+    if (prev == NULL)
+      R->anchor = next;
+    else
+      prev->link = next;
+    edge->link = next->link;
+    next->link = edge;
+    edge->flag ^= ISLEFT(ON);
+    edge->flag &= ~ISAMBIGUOUS(ON);
+    next->flag ^= ISLEFT(ON);
+    next->flag &= ~ISAMBIGUOUS(ON);
+    edge = next;
+  }
 }
 /*
 :h3.DumpSubPaths()
@@ -719,11 +753,12 @@ static void writeXofY(e, y, x)
        int y;                /* y value                                      */
        int x;                /* new x value                                  */
 {
-       if (e->xmin > x)  e->xmin = x;
-       if (e->xmax < x)  e->xmax = x;
-       e->xvalues[y - e->ymin] = x;
+  if (e->xmin > x)  e->xmin = x;
+  if (e->xmax < x)  e->xmax = x;
+  e->xvalues[y - e->ymin] = x;
 }
  
+
 /*-------------------------------------------------------------------------*/
 /* the following three macros tell us whether we are at a birth point, a    */
 /* death point, or simply in the middle of the character                */
@@ -822,107 +857,128 @@ when the +CONTINUITY flag is on the Inte
 void ApplyContinuity(R)
 struct region *R;
 {
- struct edgelist *left;
- struct edgelist *right;
- struct edgelist *edge,*e2;
- pel rightXabove,rightXbelow,leftXabove,leftXbelow;
- pel leftX,rightX;
- int i;
- LONG newcenter,abovecenter,belowcenter;
- 
- FixSubPaths(R);
- if (RegionDebug >= 3)
-        DumpSubPaths(R->anchor);
- left = R->anchor;
-/* loop through and do all of the easy checking. ( no tops or bottoms) */
- while(VALIDEDGE(left))
- {
-  right = left->link;
-  for(i=left->ymin;i<left->ymax;++i)
-  {
-   leftX       = findXofY(left,i);
-   rightX      = findXofY(right,i);
-   leftXbelow  = findXofY(left,i+1);
-   rightXbelow = findXofY(right,i+1);
-   if(rightX <= leftX)
-   {
-/* then, we have a break in a near vertical line */
-     leftXabove  = findXofY(left,i-1);
-     rightXabove = findXofY(right,i-1);
-     if( IsValidPel(leftXabove) && IsValidPel(rightXabove) )
-     {
-      abovecenter = leftXabove + rightXabove;
-     }
-     else
-     {
-      abovecenter = leftX + rightX;
-     }
-     if( IsValidPel(leftXbelow) && IsValidPel(rightXbelow) )
-     {
-      belowcenter = leftXbelow + rightXbelow;
-     }
-     else
-     {
-      belowcenter = leftX + rightX;
-     }
-     newcenter = abovecenter + belowcenter;
-     if( newcenter > 4*leftX )
-     {
-      rightX = rightX + 1;
-     }
-     else if( newcenter < 4*leftX)
-     {
-      leftX = leftX - 1;
-     }
-     else
-     {
-      rightX = rightX + 1;
-     }
-     writeXofY(right,i,rightX);
-     writeXofY(left,i,leftX);
-     if(rightX > R->xmax) {R->xmax = rightX;}
-     if(leftX < R->xmin) {R->xmin = leftX;}
-   }
-   if( !WeAreAtBottom(left,i) && (leftXbelow>=rightX))
-   {
-/* then we have a break in a near horizontal line in the middle */
-    writeXofY(right,i,leftXbelow);
-   }
-   if( !WeAreAtBottom(right,i) && (leftX >=rightXbelow))
-   {
-/* then we have a break in a near horizontal line in the middle */
-    writeXofY(left,i,rightXbelow);
-   }
+  struct edgelist *left;
+  struct edgelist *right;
+  struct edgelist *edge,*e2;
+  pel rightXabove,rightXbelow,leftXabove,leftXbelow;
+  pel leftX,rightX;
+  int i;
+  long edgecnt = 0;
+  
+  fractpel xavrg = 0;
+  LONG newcenter,abovecenter,belowcenter;
+
+  
+  FixSubPaths(R);
+  if ( RegionDebug >= 3)
+    DumpSubPaths(R->anchor);
+  left = R->anchor;
+
+  /* loop through and do all of the easy checking. ( no tops or bottoms) */
+  while(VALIDEDGE(left)) {
+    right = left->link;
+    for(i=left->ymin;i<left->ymax;++i) {
+      leftX       = findXofY(left,i);
+      rightX      = findXofY(right,i);
+      leftXbelow  = findXofY(left,i+1);
+      rightXbelow = findXofY(right,i+1);
+      if(rightX <= leftX) {
+
+	/* then, we have a break in a near vertical line */
+	leftXabove  = findXofY(left,i-1);
+	rightXabove = findXofY(right,i-1);
+	/* Check above current scanline */
+	if ( IsValidPel(leftXabove) && IsValidPel(rightXabove) ) {
+	  abovecenter = leftXabove + rightXabove;
+	}
+	else { 
+	  /* We are at the top. We can assume that the current edge list is just started
+	     --> Inspect the stored start fractpel values in order to decide about
+	     to which side to extend. -->
+	     Compute arithmetic average between left and right edge at high resolution */
+	  xavrg        = ((left->fpx1 + right->fpx1) >> 1);
+	  /* round down to get left (not nearest!) and get right edge by adding one pel. */
+	  leftXabove   = (xavrg >> FRACTBITS);
+	  rightXabove  = leftXabove + 1;
+	  abovecenter  = leftXabove + rightXabove;
+	  belowcenter  = leftXabove + rightXabove;
+	}
+
+	/* Check below current scanline */
+	if ( IsValidPel(leftXbelow) && IsValidPel(rightXbelow) ) {
+	  belowcenter  = leftXbelow + rightXbelow;
+	}
+	else { 
+	  /* We are at the bottom. We can assume that the current edge list terminates here
+	     --> Inspect the stored end fractpel values in order to decide about
+	     to which side to extend. -->
+	     Compute arithmetic average between left and right edge at high resolution */
+	  xavrg        = ((left->fpx2 + right->fpx2) >> 1);
+	  /* round down to get left (not nearest!) and get right edge by adding one pel. */
+	  leftXbelow   = (xavrg >> FRACTBITS);
+	  rightXbelow  = leftXbelow + 1;
+	  abovecenter  = leftXbelow + rightXbelow;
+	  belowcenter  = leftXbelow + rightXbelow;
+	}
+
+	newcenter = abovecenter + belowcenter;
+
+	if( newcenter > 4*leftX ) {
+	  rightX = rightX + 1;
+	  writeXofY(right,i,rightX);
+	}
+	else if( newcenter < 4*leftX) {
+	  leftX = leftX - 1;
+	  writeXofY(left,i,leftX);
+	}
+	else {
+	  rightX = rightX + 1;
+	  writeXofY(right,i,rightX);
+	}
+	
+	if ( rightX > R->xmax ) {
+	  R->xmax = rightX;
+	}
+	if ( leftX < R->xmin ) {
+	  R->xmin = leftX;
+	}
+      }
+      if( !WeAreAtBottom(left,i) && (leftXbelow>=rightX)) {
+	/* then we have a break in a near horizontal line in the middle */
+	writeXofY(right,i,leftXbelow);
+      }
+      if( !WeAreAtBottom(right,i) && (leftX >=rightXbelow)) {
+	/* then we have a break in a near horizontal line in the middle */
+	writeXofY(left,i,rightXbelow);
+      }
+    }
+    left = right->link;
+    ++edgecnt;
   }
-  left = right->link;
- }
-/*
-There may be "implied horizontal lines" between edges that have
-implications for continuity.  This loop looks for white runs that
-have implied horizontal lines on the top or bottom, and calls
-CollapseWhiteRuns to check and fix any continuity problems from
-them.
-*/
-      for (edge = R->anchor; VALIDEDGE(edge); edge = edge->link) {
-              if ((!ISTOP(edge->flag) && !ISBOTTOM(edge->flag)) || ISLEFT(edge->flag))
-                      continue;  /* at some future date we may want left edge logic here too */
-              for (e2 = edge->link; VALIDEDGE(e2) && SAMESWATH(edge,e2); e2 = e2->link) {
-                      if (ISTOP(e2->flag) && ISTOP(edge->flag)
-                          && NONE != ImpliedHorizontalLine(edge,e2,edge->ymin)) {
-                              if (ISLEFT(e2->flag))
-                                      CollapseWhiteRun(R->anchor, edge->ymin-1,
-                                                       edge, e2, edge->ymin);
-                      }
-                      if (ISBOTTOM(e2->flag) && ISBOTTOM(edge->flag)
-                          && NONE != ImpliedHorizontalLine(edge,e2, edge->ymax)) {
-                              if (ISLEFT(e2->flag))
-                                      CollapseWhiteRun(R->anchor, edge->ymax,
-                                                       edge, e2, edge->ymax-1);
-                      }
-              }
+  
+  /*
+    There may be "implied horizontal lines" between edges that have
+    implications for continuity.  This loop looks for white runs that
+    have implied horizontal lines on the top or bottom, and calls
+    CollapseWhiteRuns to check and fix any continuity problems from
+    them.
+  */
+  for (edge = R->anchor; VALIDEDGE(edge); edge = edge->link) {
+    if ((!ISTOP(edge->flag) && !ISBOTTOM(edge->flag)) || ISLEFT(edge->flag))
+      continue;  /* at some future date we may want left edge logic here too */
+    for (e2 = edge->link; VALIDEDGE(e2) && SAMESWATH(edge,e2); e2 = e2->link) {
+      if (ISTOP(e2->flag) && ISTOP(edge->flag)
+	  && NONE != ImpliedHorizontalLine(edge,e2,edge->ymin)) {
+	if (ISLEFT(e2->flag))
+	  CollapseWhiteRun(R->anchor, edge->ymin-1,
+			   edge, e2, edge->ymin);
+      }
+      if (ISBOTTOM(e2->flag) && ISBOTTOM(edge->flag)
+	  && NONE != ImpliedHorizontalLine(edge,e2, edge->ymax)) {
+	if (ISLEFT(e2->flag))
+	  CollapseWhiteRun(R->anchor, edge->ymax,
+			   edge, e2, edge->ymax-1);
       }
+    }
+  }
 }
- 
- 
- 
- 
Index: grace/T1lib/type1/lines.c
===================================================================
--- grace.orig/T1lib/type1/lines.c
+++ grace/T1lib/type1/lines.c
@@ -43,6 +43,7 @@ The included files are:
 #include "types.h"
 #include "objects.h"
 #include "spaces.h"
+#include "paths.h"
 #include "regions.h"
 #include "lines.h"
  
@@ -66,6 +67,10 @@ This module provides the following entry
 None.
 */
  
+#define  BITS         (sizeof(LONG)*8)
+#define  HIGHTEST(p)  (((p)>>(BITS-2)) != 0)  /* includes sign bit */
+#define  TOOBIG(xy)   ((xy < 0) ? HIGHTEST(-xy) : HIGHTEST(xy))
+
 /*
 :h2.StepLine() - Produces Run Ends for a Line After Checks
  
@@ -83,6 +88,9 @@ void StepLine(R, x1, y1, x2, y2)
        IfTrace4((LineDebug > 0), ".....StepLine: (%d,%d) to (%d,%d)\n",
                                             x1, y1, x2, y2);
  
+      if ( TOOBIG(x1) || TOOBIG(x2) || TOOBIG(y1) || TOOBIG(y2))
+              abort("Lines this big not supported", 49);
+
        dy = y2 - y1;
  
 /*
@@ -147,6 +155,7 @@ Find the starting x and y integer pel co
  
  x = RoundFP(x1,PREC);
  y = RoundFP(y1,PREC);
+
  edgeP += y;
  count = RoundFP(y2,PREC) - y;
 /*------------------------------------------------------------------*/
@@ -172,6 +181,15 @@ Find the starting x and y integer pel co
  }
  else  /* positive dx */
  {
+   
+   if ( dx == 0 ) {
+     while(--count >= 0 ) {
+       *(edgeP++) = x;
+     }
+     return;
+     
+   }
+   
 #define P PREC
   d = (dy*((x<<P)-x1+(1<<(P-1)))-dx*((y<<P)-y1+(1<<(P-1))))>>P;
 #undef P
Index: grace/T1lib/type1/objects.c
===================================================================
--- grace.orig/T1lib/type1/objects.c
+++ grace/T1lib/type1/objects.c
@@ -542,7 +542,7 @@ struct xobject *t1_Copy(obj)
                return(NULL);
  
        if (ISPATHTYPE(obj->type))
-               obj = (struct xobject *) CopyPath(obj);
+               obj = (struct xobject *) CopyPath((struct segment *)obj);
        else
                switch (obj->type) {
                    case SPACETYPE:
@@ -584,7 +584,7 @@ struct xobject *Destroy(obj) /* non-ANSI
                return(NULL);
        }
        if (ISPATHTYPE(obj->type))
-               KillPath(obj);
+               KillPath((struct segment *)obj);
        else {
                switch (obj->type) {
                    case REGIONTYPE:
@@ -957,7 +957,7 @@ struct xobject *TypeErr(name, obj, expec
  
        sprintf(typemsg, "Wrong object type in %s; expected %s, found %s.\n",
                   name, TypeFmt(expect), TypeFmt(obj->type));
-       IfTrace0(TRUE,typemsg);
+       IfTrace1(TRUE, "%s", typemsg);
  
        ObjectPostMortem(obj);
  
@@ -1137,12 +1137,13 @@ char *t1_get_abort_message( int number)
     "Context:  out of them", /* 46 */
     "MatrixInvert:  can't", /* 47 */
     "xiStub called", /* 48 */
-    "Illegal access type1 abort() message" /* 49 */
+    "Lines this big not supported", /* 49 */
+    "Illegal access type1 abort() message" /* 50 */
   };
 
-  /* no is valid from 1 to 48 */
-  if ( (number<1)||(number>48))
-    number=49;
+  /* no is valid from 1 to 49 */
+  if ( (number<1)||(number>49))
+    number=50;
   return( err_msgs[number-1]);
     
 }
Index: grace/T1lib/type1/objects.h
===================================================================
--- grace.orig/T1lib/type1/objects.h
+++ grace/T1lib/type1/objects.h
@@ -214,7 +214,7 @@ struct xobject {
 /*SHARED*/
 /* NDW: personally, I want to see status and error messages! */
 #define IfTrace0(condition,model)                                 \
-        {if (condition) printf(model);}
+        {if (condition) fputs(model,stdout);}
 #define IfTrace1(condition,model,arg0)                            \
         {if (condition) printf(model,arg0);}
 #define IfTrace2(condition,model,arg0,arg1)                       \
@@ -288,7 +288,7 @@ We define other routines formatting para
  
 void t1_DumpArea();           /* dump a region structure                      */
 void t1_DumpText();           /* dump a textpath structure                    */
-void t1_DumpPath();           /* dump a path list                             */
+void T1_DumpPath();           /* dump a path list                             */
 void t1_DumpSpace();          /* dump a coordinate space structure            */
 void t1_DumpEdges();          /* dump a region's edge list                    */
 void t1_FormatFP();           /* dump a format a "fractpel" coordinate        */
Index: grace/T1lib/type1/paths.c
===================================================================
--- grace.orig/T1lib/type1/paths.c
+++ grace/T1lib/type1/paths.c
@@ -1049,21 +1049,23 @@ void PathDelta(p, pt)
        register struct segment *p; /* input path                             */
        register struct fractpoint *pt; /* pointer to x,y to set              */
 {
-       struct fractpoint mypoint;  /* I pass this to TextDelta               */
-       register fractpel x,y;  /* working variables for path current point   */
- 
-       for (x=y=0; p != NULL; p=p->link) {
-               x += p->dest.x;
-               y += p->dest.y;
-               if (p->type == TEXTTYPE) {
-                       TextDelta(p, &mypoint);
-                       x += mypoint.x;
-                       y += mypoint.y;
-               }
-       }
- 
-       pt->x = x;
-       pt->y = y;
+  register fractpel x,y;  /* working variables for path current point   */
+  
+  for (x=y=0; p != NULL; p=p->link) {
+    x += p->dest.x;
+    y += p->dest.y;
+    if (p->type == TEXTTYPE) {
+      struct fractpoint mypoint;
+      
+      mypoint.x = mypoint.y = 0;
+      TextDelta(p, &mypoint);
+      x += mypoint.x;
+      y += mypoint.y;
+    }
+  }
+  
+  pt->x = x;
+  pt->y = y;
 }
  
 /*
Index: grace/T1lib/type1/paths.h
===================================================================
--- grace.orig/T1lib/type1/paths.h
+++ grace/T1lib/type1/paths.h
@@ -52,11 +52,46 @@
 #define   QueryPath(p,t,B,C,D,r)       t1_QueryPath(p,t,B,C,D,r)
 #define   QueryBounds(p,S,x1,y1,x2,y2)  t1_QueryBounds(p,S,x1,y1,x2,y2)
  
+/*SHARED*/
+ 
+struct segment {
+  XOBJ_COMMON     /* xobject common data define 3-26-91 PNM             */
+  unsigned char size;   /* size of the structure                        */
+  unsigned char context;  /* index to device context                    */
+  struct segment *link; /* pointer to next structure in linked list     */
+  struct segment *last; /* pointer to last structure in list            */
+  struct fractpoint dest; /* relative ending location of path segment   */
+};
  
+#define   ISCLOSED(flag)   ((flag)&0x80)  /* subpath is closed               */
+#define   LASTCLOSED(flag) ((flag)&0x40)  /* last segment in closed subpath  */
+
+/*
+  NOTE: The ISCLOSED flag is set on the MOVETYPE segment before the
+  subpath proper; the LASTCLOSED flag is set on the last segment (LINETYPE)
+  in the subpath
+  
+  We define the ISPATHANCHOR predicate to test that a path handle
+  passed by the user is valid:
+*/
+
+#define   ISPATHANCHOR(p)  (ISPATHTYPE(p->type)&&p->last!=NULL)
+
+/*
+  For performance reasons, a user's "location" object is identical to
+  a path whose only segment is a move segment.  We define a predicate
+  to test for this case.  See also :hdref refid=location..
+*/
+
+#define   ISLOCATION(p)    ((p)->type == MOVETYPE && (p)->link == NULL)
+
+/*END SHARED*/
+
+
 struct segment *t1_Loc();     /* create a location object (or "move" segment) */
 struct segment *t1_ILoc();    /* integer argument version of same             */
 struct segment *t1_Line();    /* straight line path segment                   */
-struct segment *t1_Join();    /* join two paths or regions together           */
+struct segment *t1_Join(struct segment *,struct segment *);    /* join two paths or regions together           */
 struct segment *t1_ClosePath();  /* close a path or path set                  */
 struct conicsegment *t1_Conic();  /* conic curve path segment                 */
 struct conicsegment *t1_RoundConic();  /* ditto, specified another way        */
@@ -86,8 +121,8 @@ void t1_QueryBounds();        /* Query t
 #define   Hypoteneuse(dx,dy)      t1_Hypoteneuse(dx,dy)
 #define   BoxPath(S,h,w)          t1_BoxPath(S,h,w)
  
-struct segment *t1_CopyPath(); /* duplicate a path                            */
-void t1_KillPath();           /* destroy a path                               */
+struct segment *t1_CopyPath(struct segment *); /* duplicate a path                            */
+void t1_KillPath(struct segment *);           /* destroy a path                               */
 struct segment *t1_PathXform();  /* transform a path arbitrarily              */
 void t1_PathDelta();          /* calculate the ending point of a path         */
 struct segment *t1_PathSegment(); /* produce a MOVE or LINE segment           */
@@ -101,39 +136,6 @@ struct segment *t1_BoxPath();   /* retur
 #define    ConsumePath(p)    MAKECONSUME(p,KillPath(p))
 #define    UniquePath(p)     MAKEUNIQUE(p,CopyPath(p))
  
-/*END SHARED*/
-/*SHARED*/
- 
-struct segment {
-       XOBJ_COMMON     /* xobject common data define 3-26-91 PNM             */
-       unsigned char size;   /* size of the structure                        */
-       unsigned char context;  /* index to device context                    */
-       struct segment *link; /* pointer to next structure in linked list     */
-       struct segment *last; /* pointer to last structure in list            */
-       struct fractpoint dest; /* relative ending location of path segment   */
-} ;
- 
-#define   ISCLOSED(flag)   ((flag)&0x80)  /* subpath is closed               */
-#define   LASTCLOSED(flag) ((flag)&0x40)  /* last segment in closed subpath  */
- 
-/*
-NOTE: The ISCLOSED flag is set on the MOVETYPE segment before the
-subpath proper; the LASTCLOSED flag is set on the last segment (LINETYPE)
-in the subpath
- 
-We define the ISPATHANCHOR predicate to test that a path handle
-passed by the user is valid:
-*/
- 
-#define   ISPATHANCHOR(p)  (ISPATHTYPE(p->type)&&p->last!=NULL)
- 
-/*
-For performance reasons, a user's "location" object is identical to
-a path whose only segment is a move segment.  We define a predicate
-to test for this case.  See also :hdref refid=location..
-*/
- 
-#define   ISLOCATION(p)    ((p)->type == MOVETYPE && (p)->link == NULL)
  
 /*END SHARED*/
 /*SHARED*/
Index: grace/T1lib/type1/regions.c
===================================================================
--- grace.orig/T1lib/type1/regions.c
+++ grace/T1lib/type1/regions.c
@@ -46,8 +46,8 @@ The included files are:
 #include  "types.h"
 #include  "objects.h"
 #include  "spaces.h"
-#include  "regions.h"
 #include  "paths.h"
+#include  "regions.h"
 #include  "curves.h"
 #include  "lines.h"
 #include  "pictures.h"
@@ -268,6 +268,11 @@ struct region *CopyRegion(area)
         for (p=area->anchor; VALIDEDGE(p); p=p->link) {
  
                newp = NewEdge(p->xmin, p->xmax, p->ymin, p->ymax, p->xvalues, ISDOWN(p->flag));
+	       newp->fpx1 = p->fpx1;
+	       newp->fpx2 = p->fpx2;
+	       newp->fpy1 = p->fpy1;
+	       newp->fpy2 = p->fpy2;
+	       
                if (r->anchor == NULL)
                        r->anchor = last = newp;
                else
@@ -373,225 +378,155 @@ struct region *Interior(p, fillrule)
        register struct segment *p;    /* take interior of this path          */
        register int fillrule;         /* rule to follow if path crosses itself */
 {
-       register fractpel x,y;  /* keeps ending point of path segment         */
-       fractpel lastx,lasty; /* previous x,y from path segment before        */
-       register struct region *R;  /* region I will build                    */
-       register struct segment *nextP; /* next segment of path */
-       struct fractpoint hint; /* accumulated hint value */
-       char tempflag;        /* flag; is path temporary?                     */
-       char Cflag;           /* flag; should we apply continuity?            */
- 
-       IfTrace2((MustTraceCalls),".  INTERIOR(%p, %d)\n", p, (LONG) fillrule);
- 
-       if (p == NULL)
-               return(NULL);
-/*
-Establish the 'Cflag' continuity flag based on user's fill rule and
-our own 'Continuity' pragmatic (0: never do continuity, 1: do what
-user asked, >1: do it regardless).
-*/
-       if (fillrule > 0) {
-               Cflag = Continuity > 0;
-               fillrule -= CONTINUITY;
-       }
-       else
-               Cflag = Continuity > 1;
- 
-       ARGCHECK((fillrule != WINDINGRULE && fillrule != EVENODDRULE),
-                       "Interior: bad fill rule", NULL, NULL, (1,p), struct region *);
- 
-       if (p->type == TEXTTYPE)
-/*             if (fillrule != EVENODDRULE)
-               else */
-                       return((struct region *)UniquePath(p));
-       if (p->type == STROKEPATHTYPE){
-	 if (fillrule == WINDINGRULE)
-	   return((struct region *)DoStroke(p));
-	 else
-	   p = CoercePath(p);
-       }
-       
- 
-       R = (struct region *)Allocate(sizeof(struct region), &EmptyRegion, 0);
- 
-       ARGCHECK(!ISPATHANCHOR(p), "Interior:  bad path", p, R, (0), struct region *);
-       ARGCHECK((p->type != MOVETYPE), "Interior:  path not closed", p, R, (0), struct region *);
- 
- 
-/* changed definition from !ISPERMANENT to references <= 1 3-26-91 PNM */
-       tempflag =  (p->references <= 1); /* only first segment in path is so marked */
-       if (!ISPERMANENT(p->flag)) p->references -= 1;
- 
-       R->newedgefcn = newfilledge;
-/*
-Believe it or not, "R" is now completely initialized.  We are counting
-on the copy of template to get other fields the way we want them,
-namely
-:ol.
-:li.anchor = NULL
-:li.xmin, ymin, xmax, ymax, to minimum and maximum values respectively.
-:eol.
-Anchor = NULL is very
-important to ChangeDirection.
-See :hdref refid=CD..
- 
-To minimize problems of "wrapping" in our pel arithmetic, we keep an
-origin of the region which is the first move.  Hopefully, that keeps
-numbers within plus or minus 32K pels.
-*/
-       R->origin.x = 0/*TOFRACTPEL(NEARESTPEL(p->dest.x))*/;
-       R->origin.y = 0/*TOFRACTPEL(NEARESTPEL(p->dest.y))*/;
-       lastx = - R->origin.x;
-       lasty = - R->origin.y;
-/*
-ChangeDirection initializes other important fields in R, such as
-lastdy, edge, edgeYstop, edgexmin, and edgexmax.  The first segment
-is a MOVETYPE, so it will be called first.
-*/
-/*
-The hints data structure must be initialized once for each path.
-*/
- 
-       if (ProcessHints)
-               InitHints(); /* initialize hint data structure */
- 
-       while (p != NULL)  {
- 
-               x = lastx + p->dest.x;
-               y = lasty + p->dest.y;
- 
-               IfTrace2((HintDebug > 0),"Ending point = (%d,%d)\n",
-			x,
-			y);
- 
-               nextP = p->link;
- 
-/*
-Here we start the hints processing by initializing the hint value to
-zero.  If ProcessHints is FALSE, the value will remain zero.
-Otherwise, hint accumulates the computed hint values.
-*/
- 
-               hint.x = hint.y = 0;
- 
-/*
-If we are processing hints, and this is a MOVE segment (other than
-the first on the path), we need to close (reverse) any open hints.
-*/
- 
-               if (ProcessHints)
-                       if ((p->type == MOVETYPE) && (p->last == NULL)) {
-                               CloseHints(&hint);
-                               IfTrace2((HintDebug>0),"Closed point= (%d,%d)\n",
-					x+hint.x,
-					y+hint.y);
-                       }
- 
-/*
-Next we run through all the hint segments (if any) attached to this
-segment.  If ProcessHints is TRUE, we will accumulate computed hint
-values.  In either case, nextP will be advanced to the first non-HINT
-segment (or NULL), and each hint segment will be freed if necessary.
-*/
- 
-               while ((nextP != NULL) && (nextP->type == HINTTYPE))  {
-                       if (ProcessHints)
-                               ProcessHint(nextP, x + hint.x, y + hint.y, &hint);
-		       
-                       {
-                               register struct segment *saveP = nextP;
- 
-                               nextP = nextP->link;
-                               if (tempflag)
-                                       Free(saveP);
-                       }
-               }
- 
-/*
-We now apply the full hint value to the ending point of the path segment.
-*/
-	       /*  printf("Applying hints (x=%d,y=%d)\n", hint.x, hint.y);*/
- 
-               x += hint.x;
-               y += hint.y;
- 
-               IfTrace2((HintDebug>0),"Hinted ending point = (%d,%d)\n", 
-			x, y);
- 
-               switch(p->type) {
- 
-                   case LINETYPE:
-                       StepLine(R, lastx, lasty, x, y);
-                       break;
- 
-                   case CONICTYPE:
-                   {
- 
-/*
-For a conic curve, we apply half the hint value to the conic midpoint.
-*/
- 
-                   }
-                       break;
- 
-                   case BEZIERTYPE:
-                   {
-                       register struct beziersegment *bp = (struct beziersegment *) p;
- 
-/*
-For a Bezier curve, we apply the full hint value to the Bezier C point.
-*/
- 
-                       StepBezier(R, lastx, lasty,
-                                 lastx + bp->B.x, lasty + bp->B.y,
-                                 lastx + bp->C.x + hint.x,
-                                 lasty + bp->C.y + hint.y,
-                                 x, y);
-                   }
-                       break;
- 
-                   case MOVETYPE:
-/*
-At this point we have encountered a MOVE segment.  This breaks the
-path, making it disjoint.
-*/
-                       if (p->last == NULL) /* i.e., not first in path */
-                               ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0);
- 
-                       ChangeDirection(CD_FIRST, R, x, y, (fractpel) 0);
-/*
-We'll just double check for closure here.  We forgive an appended
-MOVETYPE at the end of the path, if it isn't closed:
-*/
-                       if (!ISCLOSED(p->flag) && p->link != NULL)
-                               return((struct region *)ArgErr("Fill: sub-path not closed", p, NULL));
-                       break;
- 
-                   default:
-                       abort("Interior: path type error", 30);
-               }
-/*
-We're done with this segment.  Advance to the next path segment in
-the list, freeing this one if necessary:
-*/
-               lastx = x;  lasty = y;
- 
-               if (tempflag)
-                       Free(p);
-               p = nextP;
-       }
-       ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0);
-       R->ending.x = lastx;
-       R->ending.y = lasty;
-/*
-Finally, clean up the region's based on the user's 'fillrule' request:
-*/
-       if (Cflag)
-             ApplyContinuity(R);
-       if (fillrule == WINDINGRULE)
-             Unwind(R->anchor);
-       return(R);
+  register fractpel x,y;  /* keeps ending point of path segment         */
+  fractpel lastx,lasty; /* previous x,y from path segment before        */
+  register struct region *R;  /* region I will build                    */
+  register struct segment *nextP; /* next segment of path */
+  char tempflag;        /* flag; is path temporary?                     */
+  char Cflag;           /* flag; should we apply continuity?            */
+  
+  IfTrace2((MustTraceCalls),".  INTERIOR(%p, %d)\n", p, (LONG) fillrule);
+  
+  if (p == NULL)
+    return(NULL);
+  /*
+    Establish the 'Cflag' continuity flag based on user's fill rule and
+    our own 'Continuity' pragmatic (0: never do continuity, 1: do what
+    user asked, >1: do it regardless).
+  */
+  if (fillrule > 0) {
+    Cflag = Continuity > 0;
+    fillrule -= CONTINUITY;
+  }
+  else
+    Cflag = Continuity > 1;
+ 
+  ARGCHECK((fillrule != WINDINGRULE && fillrule != EVENODDRULE),
+	   "Interior: bad fill rule", NULL, NULL, (1,p), struct region *);
+  
+  if (p->type == TEXTTYPE)
+    /*             if (fillrule != EVENODDRULE)
+		   else */
+    return((struct region *)UniquePath(p));
+  if (p->type == STROKEPATHTYPE){
+    if (fillrule == WINDINGRULE)
+      return((struct region *)DoStroke(p));
+    else
+      p = CoercePath(p);
+  }
+  
+ 
+  R = (struct region *)Allocate(sizeof(struct region), &EmptyRegion, 0);
+  
+  ARGCHECK(!ISPATHANCHOR(p), "Interior:  bad path", p, R, (0), struct region *);
+  ARGCHECK((p->type != MOVETYPE), "Interior:  path not closed", p, R, (0), struct region *);
+  
+  
+  /* changed definition from !ISPERMANENT to references <= 1 3-26-91 PNM */
+  tempflag =  (p->references <= 1); /* only first segment in path is so marked */
+  if (!ISPERMANENT(p->flag)) p->references -= 1;
+  
+  R->newedgefcn = newfilledge;
+  /*
+    Believe it or not, "R" is now completely initialized.  We are counting
+    on the copy of template to get other fields the way we want them,
+    namely
+    :ol.
+    :li.anchor = NULL
+    :li.xmin, ymin, xmax, ymax, to minimum and maximum values respectively.
+    :eol.
+    Anchor = NULL is very
+    important to ChangeDirection.
+    See :hdref refid=CD..
+    
+    To minimize problems of "wrapping" in our pel arithmetic, we keep an
+    origin of the region which is the first move.  Hopefully, that keeps
+    numbers within plus or minus 32K pels.
+  */
+  R->origin.x = 0/*TOFRACTPEL(NEARESTPEL(p->dest.x))*/;
+  R->origin.y = 0/*TOFRACTPEL(NEARESTPEL(p->dest.y))*/;
+  lastx = - R->origin.x;
+  lasty = - R->origin.y;
+  /*
+    ChangeDirection initializes other important fields in R, such as
+    lastdy, edge, edgeYstop, edgexmin, and edgexmax.  The first segment
+    is a MOVETYPE, so it will be called first.
+  */
+  /*
+    Note: Hinting is completely performed in charspace coordinates
+          in the Type 1 module. Therefore, I have removed the code
+	  to handle hint segments. (2002-08-11)
+  */
+  
+  while (p != NULL)  {
+ 
+    x = lastx + p->dest.x;
+    y = lasty + p->dest.y;
+    
+    nextP = p->link;
+ 
+    switch(p->type) {
+      
+    case LINETYPE:
+      StepLine(R, lastx, lasty, x, y);
+      break;
+      
+    case CONICTYPE:
+	/* 2nd order Beziers not implemented! */
+      break;
+      
+    case BEZIERTYPE:
+      {
+	register struct beziersegment *bp = (struct beziersegment *) p;
+	
+	StepBezier(R, lastx, lasty,
+		   lastx + bp->B.x, lasty + bp->B.y,
+		   lastx + bp->C.x,
+		   lasty + bp->C.y,
+		   x, y);
+      }
+      break;
+ 
+    case MOVETYPE:
+      /* At this point we have encountered a MOVE segment.  This breaks the
+	 path, making it disjoint. */
+      if (p->last == NULL) /* i.e., not first in path */
+	ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0, (fractpel) 0, (fractpel) 0);
+      
+      ChangeDirection(CD_FIRST, R, x, y, (fractpel) 0, (fractpel) 0, (fractpel) 0);
+      /* We'll just double check for closure here.  We forgive an appended
+	 MOVETYPE at the end of the path, if it isn't closed: */
+      if (!ISCLOSED(p->flag) && p->link != NULL)
+	return((struct region *)ArgErr("Fill: sub-path not closed", p, NULL));
+      break;
+      
+    default:
+      abort("Interior: path type error", 30);
+    }
+    /*  We're done with this segment.  Advance to the next path segment in
+	the list, freeing this one if necessary: */
+    lastx = x;  lasty = y;
+    
+    if (tempflag)
+      Free(p);
+    p = nextP;
+  }
+  ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0, (fractpel) 0, (fractpel) 0);
+  R->ending.x = lastx;
+  R->ending.y = lasty;
+
+
+  /*  Finally, clean up the region's based on the user's 'fillrule' request: */
+  if (Cflag)
+    ApplyContinuity(R);
+
+  if (fillrule == WINDINGRULE)
+    Unwind(R->anchor);
+
+  return R;
 }
+
+
 /*
 :h4.Unwind() - Discards Edges That Fail the Winding Rule Test
  
@@ -664,11 +599,12 @@ emerging edgelist at 'anchor' by calling
 is appropriate.
 */
  
-void ChangeDirection(type, R, x, y, dy)
+void ChangeDirection(type, R, x, y, dy, x2, y2)
        int type;             /* CD_FIRST, CD_CONTINUE, or CD_LAST            */
        register struct region *R;  /* region in which we are changing direction */
        fractpel x,y;         /* current beginning x,y                        */
        fractpel dy;          /* direction and magnitude of change in y       */
+       int x2, y2;
 {
        register fractpel ymin,ymax;  /* minimum and maximum Y since last call */
        register fractpel x_at_ymin,x_at_ymax;  /* their respective X's       */
@@ -699,7 +635,8 @@ void ChangeDirection(type, R, x, y, dy)
  
  
                (*R->newedgefcn)(R, R->edgexmin, R->edgexmax, ymin, ymax,
-                                   R->lastdy > 0, x_at_ymin, x_at_ymax);
+				R->lastdy > 0, x_at_ymin, x_at_ymax,
+				x, y, x2, y2);
  
        }
  
@@ -750,37 +687,89 @@ This function also has to keep the bound
 up to date.
 */
  
-static int newfilledge(R, xmin, xmax, ymin, ymax, isdown)
-       register struct region *R;  /* region being built                     */
-       fractpel xmin,xmax;   /* X range of this edge                         */
-       fractpel ymin,ymax;   /* Y range of this edge                         */
-       int isdown;           /* flag:  TRUE means edge goes down, else up    */
-{
- 
-       register pel pelxmin,pelymin,pelxmax,pelymax;  /* pel versions of bounds */
-       register struct edgelist *edge;  /* newly created edge                */
- 
-       pelymin = NEARESTPEL(ymin);
-       pelymax = NEARESTPEL(ymax);
-       if (pelymin == pelymax)
-               return(0);
- 
-       pelxmin = NEARESTPEL(xmin);
-       pelxmax = NEARESTPEL(xmax);
- 
-       if (pelxmin < R->xmin)  R->xmin = pelxmin;
-       if (pelxmax > R->xmax)  R->xmax = pelxmax;
-       if (pelymin < R->ymin)  R->ymin = pelymin;
-       if (pelymax > R->ymax)  R->ymax = pelymax;
- 
-       edge = NewEdge(pelxmin, pelxmax, pelymin, pelymax, &R->edge[pelymin], isdown);
-       edge->subpath = R->lastedge;
-       R->lastedge = edge;
-       if (R->firstedge == NULL)
-               R->firstedge = edge;
- 
-       R->anchor = SortSwath(R->anchor, edge, swathxsort);
-       return(0);
+static int newfilledge(R, xmin, xmax, ymin, ymax, isdown, x1, y1, x2, y2)
+     register struct region *R;  /* region being built                     */
+     fractpel xmin,xmax;   /* X range of this edge                         */
+     fractpel ymin,ymax;   /* Y range of this edge                         */
+     int isdown;           /* flag:  TRUE means edge goes down, else up    */
+     fractpel x1;
+     fractpel y1;
+     fractpel x2;
+     fractpel y2;
+{
+  
+  register pel pelxmin,pelymin,pelxmax,pelymax;  /* pel versions of bounds */
+  register struct edgelist *edge;  /* newly created edge                */
+  
+  pelymin = NEARESTPEL(ymin);
+  pelymax = NEARESTPEL(ymax);
+  if (pelymin == pelymax)
+    return(0);
+  
+  pelxmin = NEARESTPEL(xmin);
+  pelxmax = NEARESTPEL(xmax);
+  
+  if (pelxmin < R->xmin)  R->xmin = pelxmin;
+  if (pelxmax > R->xmax)  R->xmax = pelxmax;
+  if (pelymin < R->ymin)  R->ymin = pelymin;
+  if (pelymax > R->ymax)  R->ymax = pelymax;
+  
+  edge = NewEdge(pelxmin, pelxmax, pelymin, pelymax, &R->edge[pelymin], isdown);
+
+  /* Save maximum and minimum values of edge in order to be able to
+     use them in ApplyContinity. */
+  edge->fpx1 = x1;
+  edge->fpy1 = y1;
+  edge->fpx2 = x2;
+  edge->fpy2 = y2;
+  
+  edge->subpath = R->lastedge;
+  R->lastedge = edge;
+  if (R->firstedge == NULL)
+    R->firstedge = edge;
+   
+  R->anchor = SortSwath(R->anchor, edge, swathxsort);
+
+  /*
+  { 
+    struct region*   r  = (struct region*) R;
+    struct edgelist* el = (struct edgelist*) (r->anchor);
+    
+    while ( el != 0 )
+      {
+	long i = 0;
+	short int* spl;
+	short int* spr;
+	int xl;
+	int xr;
+	
+	printf( "Region after Sort (NE=%ld) : ymin=%d, ymax=%d, xmin=%d, xmax=%d\n",
+		callcount, el->ymin, el->ymax, el->xmin, el->xmax);
+	for ( i=0; i<((el->ymax)-(el->ymin)); i++ ) {
+	  spl = el->xvalues;
+	  if ( el->link != NULL ) {
+	    spr = el->link->xvalues;
+	    xl = spl[i];
+	    xr = spr[i];
+	    printf( "Region after Sort (NE=%ld): y=%ld              xleft=%d, xright=%d\n",
+		    callcount, el->ymin + i, xl, xr);
+	  }
+	  else {
+	    printf( "Region after Sort (NE=%ld): y=%ld              xval=%d\n",
+		    callcount, el->ymin + i, spl[i]);
+	  }
+	}
+	if ( el->link != 0 )
+	  el = el->link->link;
+	else
+	  break;
+      }
+  }
+
+  ++callcount;
+  */
+  
+  return 0;
 }
  
 /*
@@ -812,106 +801,108 @@ struct edgelist *SortSwath(anchor, edge,
        register struct edgelist *edge;  /* incoming edge or pair of edges    */
        struct edgelist *(*swathfcn)();  /* horizontal sorter                 */
 {
-       register struct edgelist *before,*after;
-       struct edgelist base;
- 
-       if (RegionDebug > 0) {
-               if (RegionDebug > 2)  {
-                       IfTrace3(TRUE,"SortSwath(anchor=%p, edge=%p, fcn=%p)\n",
-                            anchor, edge, swathfcn);
-               }
-               else  {
-                       IfTrace3(TRUE,"SortSwath(anchor=%p, edge=%p, fcn=%p)\n",
-                            anchor, edge, swathfcn);
-               }
-       }
-       if (anchor == NULL)
-               return(edge);
- 
-       before = &base;
-       before->ymin = before->ymax = MINPEL;
-       before->link = after = anchor;
- 
-/*
-If the incoming edge is above the current list, we connect the current
-list to the bottom of the incoming edge.  One slight complication is
-if the incoming edge overlaps into the current list.  Then, we
-first split the incoming edge in two at the point of overlap and recursively
-call ourselves to sort the bottom of the split into the current list:
-*/
-       if (TOP(edge) < TOP(after)) {
-               if (BOTTOM(edge) > TOP(after)) {
- 
-                       after = SortSwath(after, splitedge(edge, TOP(after)), swathfcn);
-               }
-               vertjoin(edge, after);
-               return(edge);
-       }
-/*
-At this point the top of edge is not higher than the top of the list,
-which we keep in 'after'.  We move the 'after' point down the list,
-until the top of the edge occurs in the swath beginning with 'after'.
- 
-If the bottom of 'after' is below the bottom of the edge, we have to
-split the 'after' swath into two parts, at the bottom of the edge.
-If the bottom of 'after' is above the bottom of the swath,
-*/
- 
-       while (VALIDEDGE(after)) {
- 
-               if (TOP(after) == TOP(edge)) {
-                       if (BOTTOM(after) > BOTTOM(edge))
-                               vertjoin(after, splitedge(after, BOTTOM(edge)));
-                       else if (BOTTOM(after) < BOTTOM(edge)) {
-                               after = SortSwath(after,
-                                     splitedge(edge, BOTTOM(after)), swathfcn);
-                       }
-                       break;
-               }
-               else if (TOP(after) > TOP(edge)) {
-                       IfTrace0((BOTTOM(edge) < TOP(after) && RegionDebug > 0),
-                                                "SortSwath:  disjoint edges\n");
-                       if (BOTTOM(edge) > TOP(after)) {
-                               after = SortSwath(after,
-                                         splitedge(edge, TOP(after)), swathfcn);
-                       }
-                       break;
-               }
-               else if (BOTTOM(after) > TOP(edge))
-                       vertjoin(after, splitedge(after, TOP(edge)));
- 
-               before = after;
-               after = after->link;
-       }
- 
-/*
-At this point 'edge' exactly corresponds in height to the current
-swath pointed to by 'after'.
-*/
-       if (after != NULL && TOP(after) == TOP(edge)) {
-               before = (*swathfcn)(before, edge);
-               after = before->link;
-       }
-/*
-At this point 'after' contains all the edges after 'edge', and 'before'
-contains all the edges before.  Whew!  A simple matter now of adding
-'edge' to the linked list in its rightful place:
-*/
-       before->link = edge;
-       if (RegionDebug > 1) {
-               IfTrace3(TRUE,"SortSwath:  in between %p and %p are %p",
-                                                before, after, edge);
-               while (edge->link != NULL) {
-                       edge = edge->link;
-                       IfTrace1(TRUE," and %p", edge);
-               }
-               IfTrace0(TRUE,"\n");
-       }
-       else
-               for (; edge->link != NULL; edge = edge->link) { ; }
- 
-       edge->link = after;
-       return(base.link);
+  register struct edgelist *before,*after;
+  struct edgelist base;
+  
+  if (RegionDebug > 0) {
+    if (RegionDebug > 2)  {
+      IfTrace3(TRUE,"SortSwath(anchor=%p, edge=%p, fcn=%p)\n",
+	       anchor, edge, swathfcn);
+    }
+    else  {
+      IfTrace3(TRUE,"SortSwath(anchor=%p, edge=%p, fcn=%p)\n",
+	       anchor, edge, swathfcn);
+    }
+  }
+  if (anchor == NULL)
+    return(edge);
+  
+  before = &base;
+  before->ymin = before->ymax = MINPEL;
+  before->link = after = anchor;
+  
+  /*
+    If the incoming edge is above the current list, we connect the current
+    list to the bottom of the incoming edge.  One slight complication is
+    if the incoming edge overlaps into the current list.  Then, we
+    first split the incoming edge in two at the point of overlap and recursively
+    call ourselves to sort the bottom of the split into the current list:
+  */
+  if (TOP(edge) < TOP(after)) {
+    if (BOTTOM(edge) > TOP(after)) {
+      after = SortSwath(after, splitedge(edge, TOP(after)), swathfcn);
+    }
+    vertjoin(edge, after);
+    return(edge);
+  }
+  
+  /*
+    At this point the top of edge is not higher than the top of the list,
+    which we keep in 'after'.  We move the 'after' point down the list,
+    until the top of the edge occurs in the swath beginning with 'after'.
+    
+    If the bottom of 'after' is below the bottom of the edge, we have to
+    split the 'after' swath into two parts, at the bottom of the edge.
+    If the bottom of 'after' is above the bottom of the swath,
+  */
+ 
+  while (VALIDEDGE(after)) {
+    
+    if (TOP(after) == TOP(edge)) {
+      if (BOTTOM(after) > BOTTOM(edge))
+	vertjoin(after, splitedge(after, BOTTOM(edge)));
+      else if (BOTTOM(after) < BOTTOM(edge)) {
+	after = SortSwath(after,
+			  splitedge(edge, BOTTOM(after)), swathfcn);
+      }
+      break;
+    }
+    else if (TOP(after) > TOP(edge)) {
+      IfTrace0((BOTTOM(edge) < TOP(after) && RegionDebug > 0),
+	       "SortSwath:  disjoint edges\n");
+      if (BOTTOM(edge) > TOP(after)) {
+	after = SortSwath(after,
+			  splitedge(edge, TOP(after)), swathfcn);
+      }
+      break;
+    }
+    else if (BOTTOM(after) > TOP(edge))
+      vertjoin(after, splitedge(after, TOP(edge)));
+    
+    before = after;
+    after = after->link;
+  }
+  
+  /*
+    At this point 'edge' exactly corresponds in height to the current
+    swath pointed to by 'after'.
+  */
+  if (after != NULL && TOP(after) == TOP(edge)) {
+    before = (*swathfcn)(before, edge);
+    after = before->link;
+  }
+  /*
+    At this point 'after' contains all the edges after 'edge', and 'before'
+    contains all the edges before.  Whew!  A simple matter now of adding
+    'edge' to the linked list in its rightful place:
+  */
+  before->link = edge;
+  if (RegionDebug > 1) {
+    IfTrace3(TRUE,"SortSwath:  in between %p and %p are %p",
+	     before, after, edge);
+    while (edge->link != NULL) {
+      edge = edge->link;
+      IfTrace1(TRUE," and %p", edge);
+    }
+    IfTrace0(TRUE,"\n");
+  }
+  else
+    for (; edge->link != NULL; edge = edge->link) { ; }
+  
+  edge->link = after;
+
+  return base.link;
+  
 }
  
 /*
@@ -926,66 +917,78 @@ static struct edgelist *splitedge(list,
        struct edgelist *list;  /* area to split                              */
        register pel y;       /* Y value to split list at                     */
 {
-       register struct edgelist *new;  /* anchor for newly built list        */
-       register struct edgelist *last=NULL;  /* end of newly built list           */
-       register struct edgelist *r;  /* temp pointer to new structure        */
-       register struct edgelist *lastlist;  /* temp pointer to last 'list' value */
- 
-       IfTrace2((RegionDebug > 1),"splitedge of %p at %d ", list, (LONG) y);
- 
-       lastlist = new = NULL;
- 
-       while (list != NULL) {
-               if (y < list->ymin)
-                       break;
-               if (y >= list->ymax)
-                       abort("splitedge: above top of list", 33);
-               if (y == list->ymin)
-                       abort("splitedge: would be null", 34);
- 
-               r = (struct edgelist *)Allocate(sizeof(struct edgelist), list, 0);
-/*
-At this point 'r' points to a copy of the single structure at 'list'.
-We will make 'r' be the new split 'edgelist'--the lower half.
-We don't bother to correct 'xmin' and 'xmax', we'll take the
-the pessimistic answer that results from using the old values.
-*/
-               r->ymin = y;
-               r->xvalues = list->xvalues + (y - list->ymin);
-/*
-Note that we do not need to allocate new memory for the X values,
-they can remain with the old "edgelist" structure.  We do have to
-update that old structure so it is not as high:
-*/
-               list->ymax = y;
-/*
-Insert 'r' in the subpath chain:
-*/
-               r->subpath = list->subpath;
-               list->subpath = r;
-/*
-Now attach 'r' to the list we are building at 'new', and advance
-'list' to point to the next element in the old list:
-*/
-               if (new == NULL)
-                       new = r;
-               else
-                       last->link = r;
-               last = r;
-               lastlist = list;
-               list = list->link;
-       }
-/*
-At this point we have a new list built at 'new'.  We break the old
-list at 'lastlist', and add the broken off part to the end of 'new'.
-Then, we return the caller a pointer to 'new':
-*/
-       if (new == NULL)
-               abort("null splitedge", 35);
-       lastlist->link = NULL;
-       last->link = list;
-       IfTrace1((RegionDebug > 1),"yields %p\n", new);
-       return(new);
+  register struct edgelist *new;  /* anchor for newly built list        */
+  register struct edgelist *last=NULL;  /* end of newly built list           */
+  register struct edgelist *r;  /* temp pointer to new structure        */
+  register struct edgelist *lastlist;  /* temp pointer to last 'list' value */
+  
+  IfTrace2((RegionDebug > 1),"splitedge of %p at %d ", list, (LONG) y);
+  
+  lastlist = new = NULL;
+  
+  while (list != NULL) {
+    if (y < list->ymin)
+      break;
+    
+    if (y >= list->ymax)
+      abort("splitedge: above top of list", 33);
+    if (y == list->ymin)
+      abort("splitedge: would be null", 34);
+    
+    r = (struct edgelist *)Allocate(sizeof(struct edgelist), list, 0);
+    /*
+      At this point 'r' points to a copy of the single structure at 'list'.
+      We will make 'r' be the new split 'edgelist'--the lower half.
+      We don't bother to correct 'xmin' and 'xmax', we'll take the
+      the pessimistic answer that results from using the old values.
+    */
+    r->ymin = y;
+    r->xvalues = list->xvalues + (y - list->ymin);
+    
+    /*
+      Update the fpx values so that ApplyContinuity() will continue
+      to work. Note that high precision is a fake, here!
+    */
+    r->fpx1 = (r->xvalues[0]) << FRACTBITS;
+    r->fpx2 = (list->xvalues[list->ymax - list->ymin - 1]) << FRACTBITS;
+    list->fpx2 = (list->xvalues[y - list->ymin -1]) << FRACTBITS;
+    
+    /*
+      Note that we do not need to allocate new memory for the X values,
+      they can remain with the old "edgelist" structure.  We do have to
+      update that old structure so it is not as high:
+    */
+    list->ymax = y;
+    
+    /*
+      Insert 'r' in the subpath chain:
+    */
+    r->subpath = list->subpath;
+    list->subpath = r;
+    /*
+      Now attach 'r' to the list we are building at 'new', and advance
+      'list' to point to the next element in the old list:
+    */
+    if (new == NULL) {
+      new = r;
+    }
+    else
+      last->link = r;
+    last = r;
+    lastlist = list;
+    list = list->link;
+  }
+  /*
+    At this point we have a new list built at 'new'.  We break the old
+    list at 'lastlist', and add the broken off part to the end of 'new'.
+    Then, we return the caller a pointer to 'new':
+  */
+  if (new == NULL)
+    abort("null splitedge", 35);
+  lastlist->link = NULL;
+  last->link = list;
+  IfTrace1((RegionDebug > 1),"yields %p\n", new);
+  return(new);
 }
  
 /*
@@ -1559,7 +1562,7 @@ void MoreWorkArea(R, x1, y1, x2, y2)
                currentworkarea = (pel *)Allocate(0, NULL, idy * sizeof(pel));
                currentsize = idy;
        }
-       ChangeDirection(CD_CONTINUE, R, x1, y1, y2 - y1);
+       ChangeDirection(CD_CONTINUE, R, x1, y1, y2 - y1, x2, y2);
 }
  
 /*
Index: grace/T1lib/type1/regions.h
===================================================================
--- grace.orig/T1lib/type1/regions.h
+++ grace/T1lib/type1/regions.h
@@ -35,7 +35,7 @@
 #define   Complement(area)        t1_Complement(area)
 #define   Overlap(a1,a2)          t1_OverLap(a1,a2)
  
-struct region *t1_Interior(); /* returns the interior of a closed path        */
+struct region *t1_Interior(struct segment *,int); /* returns the interior of a closed path        */
 struct region *t1_Union();   /* set union of paths or regions                */
 struct region *t1_Intersect();  /* set intersection of regions                */
 struct region *t1_Complement();  /* complement of a region                    */
@@ -45,7 +45,7 @@ int t1_Overlap();             /* returns
 /*END SHARED*/
 /*SHARED*/
  
-#define   ChangeDirection(type,R,x,y,dy)  t1_ChangeDirection(type,R,x,y,dy)
+#define   ChangeDirection(type,R,x,y,dy,x2,y2)  t1_ChangeDirection(type,R,x,y,dy,x2,y2)
  
 void t1_ChangeDirection();    /* called when we change direction in Y         */
 #define   CD_FIRST         -1  /* enumeration of ChangeDirection type       */
@@ -80,17 +80,17 @@ void t1_UnJumble();           /* sort th
 #define GOING_TO(R, x1, y1, x2, y2, dy) { \
    if (dy < 0) { \
       if (R->lastdy >= 0) \
-          ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \
+          ChangeDirection(CD_CONTINUE, R, x1, y1, dy, x2, y2); \
       if (y2 < R->edgeYstop) \
           MoreWorkArea(R, x1, y1, x2, y2); \
    } \
    else if (dy > 0) { \
       if (R->lastdy <= 0) \
-          ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \
+          ChangeDirection(CD_CONTINUE, R, x1, y1, dy, x2, y2); \
       if (y2 > R->edgeYstop) \
           MoreWorkArea(R, x1, y1, x2, y2); \
    } \
-   else /* dy == 0 */ ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \
+   else /* dy == 0 */ ChangeDirection(CD_CONTINUE, R, x1, y1, dy, x2, y2); \
    if (x2 < R->edgexmin) R->edgexmin = x2; \
    else if (x2 > R->edgexmax) R->edgexmax = x2; \
 }
@@ -166,13 +166,18 @@ is frequently intersected.
 /*SHARED*/
  
 struct edgelist {
-       XOBJ_COMMON          /* xobject common data define 3-26-91 PNM        */
-                            /* type = EDGETYPE                               */
-       struct edgelist *link;  /* pointer to next in linked list             */
-       struct edgelist *subpath;  /* informational link for "same subpath"   */
-       pel xmin,xmax;        /* range of edge in X                           */
-       pel ymin,ymax;        /* range of edge in Y                           */
-       pel *xvalues;         /* pointer to ymax-ymin X values                */
+  XOBJ_COMMON          /* xobject common data define 3-26-91 PNM        */
+  /* type = EDGETYPE                               */
+  struct edgelist *link;  /* pointer to next in linked list             */
+  struct edgelist *subpath;  /* informational link for "same subpath"   */
+  pel xmin,xmax;        /* range of edge in X                           */
+  pel ymin,ymax;        /* range of edge in Y                           */
+  pel *xvalues;         /* pointer to ymax-ymin X values                */
+  
+  fractpel fpx1;        /* Added by RMz, author of t1lib, 2002-08-15.   */
+  fractpel fpy1;        /* This produces a little memory overhead, but  */
+  fractpel fpx2;        /* gives the opportunity to take more           */ 
+  fractpel fpy2;        /* intelligent decisions in ApplyContinuity().  */
 } ;
 /*
 The end of the list is marked by either "link" being NULL, or by
Index: grace/T1lib/type1/scanfont.c
===================================================================
--- grace.orig/T1lib/type1/scanfont.c
+++ grace/T1lib/type1/scanfont.c
@@ -30,12 +30,14 @@
 /* Author: Katherine A. Hitchcock    IBM Almaden Research Laboratory */
  
 #include <string.h>
+#include <stdlib.h>
 #include "t1stdio.h"
 #include "util.h"
 #include "token.h"
 #include "fontfcn.h"
 #include "blues.h"
 
+#include "../t1lib/t1misc.h"
 
 /* #define DEBUG_SCANFONT */
  
@@ -247,7 +249,7 @@ static psobj *MakeEncodingArrayP(encodin
   int i;
   psobj *encodingArrayP;
  
-  encodingArrayP = (psobj *)vm_alloc(256*(sizeof(psobj)));
+  encodingArrayP = (psobj *)malloc(256*(sizeof(psobj)));
   if (!encodingArrayP)
       return NULL;
 
@@ -267,6 +269,12 @@ static psobj *MakeEncodingArrayP(encodin
  
 boolean Init_BuiltInEncoding()
 {
+  if ( StdEncArrayP != NULL) {
+    /* Note: We should not run into this case because multiple
+             initialization should be caught by T1_InitLib(). */
+    return FALSE;
+  }
+  
   StdEncArrayP = MakeEncodingArrayP(StdEnc);
   if (StdEncArrayP==NULL)
     return( FALSE);
@@ -1217,7 +1225,7 @@ int scan_font(FontP)
 {
  
  
-  char   filename[128];
+  char   filename[MAXPATHLEN+1];
   FILE   *fileP;
   char   *nameP;
   int    namelen;
@@ -1234,6 +1242,10 @@ int scan_font(FontP)
     while ((namelen>0) && ( nameP[namelen-1] == ' ')) {
       namelen--;
     }
+    if ( namelen >= MAXPATHLEN ) {
+      /* Hopefully, this will lead to a file open error */
+      namelen = MAXPATHLEN;
+    }
     strncpy(filename,nameP,namelen);
     filename[namelen] = '\0';
     /* file name is now constructed */
@@ -1281,10 +1293,14 @@ int scan_font(FontP)
             tokenStartP[tokenLength] = '\0';
 	    /* At this point we check for the font not being a
 	       Multiple Master Font. If it is, we return an error.
-	       (RMz, 01/29/1999) */
-	    if (strncmp(tokenStartP, "BlendAxisTypes", 14)==0){
-	      rc=SCAN_MMFONT;
-	      break;
+	       However, we restrict searching for forbidden keywords
+	       to FontInfo, in order not to make assumptions about
+	       internal PostScript routine names. (RMz, 2004-11-27) */
+	    if ( !InPrivateDict ) {
+	      if (strncmp(tokenStartP, "BlendAxisTypes", 14)==0){
+		rc=SCAN_MMFONT;
+		break;
+	      }
 	    }
             if (InPrivateDict ) {
               if (0== strncmp(tokenStartP,"Subrs",5) ) {
@@ -1343,7 +1359,11 @@ int scan_font(FontP)
 	      filterFile.data.fileP = T1eexec(inputP->data.fileP);
 	      if (filterFile.data.fileP == NULL) {
 		fclose(inputFile.data.fileP);
-		return(SCAN_FILE_OPEN_ERROR);
+		/* SCAN_FILE_OPEN_ERROR replaced because at this point
+		   a portion of the file has already been read successfully.
+		   We hence have encountered a premature end of file
+		   (2002-08-17, RMz). */
+		return SCAN_FILE_EOF;
 	      }
 	      inputP = &filterFile;
 	      
Index: grace/T1lib/type1/t1chardump
===================================================================
--- /dev/null
+++ grace/T1lib/type1/t1chardump
@@ -0,0 +1,697 @@
+/*--------------------------------------------------------------------------
+  ----- File:        t1chardump 
+  ----- Author:      Rainer Menzner (Rainer.Menzner@web.de)
+  ----- Date:        2003-03-02
+  ----- Description: This file is part of the t1-library. It contains
+                     code responsible for dumping outline data to a
+		     PostScript file (used only for debugging.
+  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2003.
+                     As of version 0.5, t1lib is distributed under the
+		     GNU General Public Library Lincense. The
+		     conditions can be found in the files LICENSE and
+		     LGPL, which should reside in the toplevel
+		     directory of the distribution.  Please note that 
+		     there are parts of t1lib that are subject to
+		     other licenses:
+		     The parseAFM-package is copyrighted by Adobe Systems
+		     Inc.
+		     The type1 rasterizer is copyrighted by IBM and the
+		     X11-consortium.
+  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)
+  ----- Credits:     I want to thank IBM and the X11-consortium for making
+                     their rasterizer freely available.
+		     Also thanks to Piet Tutelaers for his ps2pk, from
+		     which I took the rasterizer sources in a format
+		     independent from X11.
+                     Thanks to all people who make free software living!
+--------------------------------------------------------------------------*/
+
+fputs( "\
+%!PS-Adobe-2.0 EPSF-1.2\n\
+%%Creator: t1lib\n\
+%%Title: Type1Char Character Dump\n\
+%%Pages: 1\n\
+%%PageOrder: Ascend\n\
+%%BoundingBox: 0 0 596 842\n\
+%%DocumentPaperSizes: a4\n\
+%%EndComments\n\
+%!\n\
+/T1LibDict 100 dict def \n\
+T1LibDict begin\n\
+% Setup the size from the type1 module\n\
+/t1SetupSize {\n\
+  /size exch def\n\
+} def\n\
+\n\
+% Prepare the page. Compute scales and fill the charspace unit square\n\
+% background\n\
+/t1PreparePage {\n\
+\n\
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\
+  %\n\
+  % Start of Customizable Section\n\
+  %\n\
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\
+\n\
+  % Setup a standard linewidth\n\
+  /t1dumpstdlinewidth 1.0 def\n\
+  % Setup a scale for drawing direction arrows\n\
+  /arrowscale 3.0 def\n\
+\n\
+  % Should we draw the device pixel grid? (1=yes, otherwise no)\n\
+  /t1drawgrid 1 def\n\
+  % Should we draw stems? (1=yes, otherwise no)\n\
+  /t1drawstems 1 def\n\
+  % Should we draw alignment zones? (1=yes, otherwise no)\n\
+  /t1drawzones 1 def\n\
+  % Should we fill the charspace unit square? (1=yes, otherwise no)\n\
+  /t1fillunitsquare 1 def\n\
+  % Should we fill the device page? (1=yes, otherwise no)\n\
+  /t1fillpage 1 def\n\
+  % Should we show path segment On-Curve points? (1=yes, otherwise no)\n\
+  /t1showoncurvepoints 1 def\n\
+  % Should we show path segment Off Curve points? (1=yes, otherwise no)\n\
+  /t1showoffcurvepoints 1 def\n\
+  % Should we show Bezier tangets and their defining points? (1=yes, otherwise no)\n\
+  /t1showbeziertangents 1 def\n\
+\n\
+  % Define a few colors\n\
+  /t1linecolor         { 0.0 0.0 0.0 } def\n\
+  /t1hlinecolor        { 1.0 0.0 0.0 } def\n\
+  /t1slinecolor        { 1.0 1.0 1.0 } def\n\
+  /t1movecolor         { 0.0 0.0 0.0 } def\n\
+  /t1hmovecolor        { 1.0 0.0 0.0 } def\n\
+  /t1smovecolor        { 1.0 1.0 1.0 } def\n\
+  /t1curvecolor        { 0.0 0.0 0.0 } def\n\
+  /t1hcurvecolor       { 1.0 0.0 0.0 } def\n\
+  /t1scurvecolor       { 0.0 0.0 1.0 } def\n\
+  /t1sprolongatecolor  { 1.0 0.0 1.0 } def\n\
+  /t1stemcolor         { 0.0 0.0 1.0 } def\n\
+  /t1alignedstemcolor  { 1.0 0.0 1.0 } def\n\
+  /t1bottomzonecolor   { 1.0 1.0 0.0 } def\n\
+  /t1topzonecolor      { 1.0 1.0 0.0 } def\n\
+  /t1arrowcolor        { 0.0 0.0 0.0 } def\n\
+  /t1harrowcolor       { 1.0 0.0 0.0 } def\n\
+  /t1sarrowcolor       { 0.0 0.0 1.0 } def\n\
+  /t1sbwcolor          { 0.0 0.0 0.0 } def\n\
+  /t1closepathcolor    { 0.0 0.0 0.0 } def\n\
+  /t1hclosepathcolor   { 1.0 0.0 0.0 } def\n\
+  /t1sclosepathcolor   { 0.0 0.0 1.0 } def\n\
+  /t1pagecolor         { 0.7 0.7 0.7 } def\n\
+  /t1unitsquarecolor   { 0.4 0.4 0.4 } def\n\
+  /t1gridcolor         { 0.0 0.0 0.0 } def\n\
+\n\
+  % Line scale relative to the standard linewidth
+  /t1linescale 0.4 def\n\
+  /t1hlinescale 0.4 def\n\
+  /t1slinescale 0.4 def\n\
+  /t1movescale 0.4 def\n\
+  /t1hmovescale 0.4 def\n\
+  /t1smovescale 0.4 def\n\
+  /t1curvescale 0.4 def\n\
+  /t1hcurvescale 0.4 def\n\
+  /t1scurvescale 0.4 def\n\
+  /t1curvetangentscale 0.5 def\n\
+  /t1sprolongatescale 0.4 def\n\
+  /t1stemscale 0.5 def\n\
+  /t1alignedstemscale 0.5 def\n\
+  /t1bottomzonescale 0.5 def\n\
+  /t1topzonescale 0.5 def\n\
+  /t1closepathscale 0.4 def\n\
+  /t1hclosepathscale 0.4 def\n\
+  /t1sclosepathscale 0.4 def\n\
+  /t1gridscale 0.5 def\n\
+\n\
+  % Line dash specifications (stems and zones are not configurable!) 
+  /t1linedash { [] 0 } def\n\
+  /t1hlinedash { [] 0 } def\n\
+  /t1slinedash { [] 0 } def\n\
+  /t1movedash { [2 2] 0 } def\n\
+  /t1hmovedash { [2 2] 0 } def\n\
+  /t1smovedash { [2 2] 0 } def\n\
+  /t1curvedash { [] 0 } def\n\
+  /t1hcurvedash { [] 0 } def\n\
+  /t1scurvedash { [] 0 } def\n\
+  /t1sprolongatedash { [1 1] 0 }def\n\
+  /t1closepathdash { [] 0 } def\n\
+  /t1hclosepathdash { [] 0 } def\n\
+  /t1sclosepathdash { [] 0 } def\n\
+  /t1griddash { [3 3] 0 } def\n\
+\n\
+  % Define a clipping rectangle ROI (in charspace coordinates)\n\
+  /t1ROIxmin -200 def\n\
+  /t1ROIxmax 1200 def\n\
+  /t1ROIymin -500 def\n\
+  /t1ROIymax 1200 def\n\
+\n\
+  % Device values (in bp). These must match the Bounding Box Statement!\n\
+  /xmindev 0 neg def\n\
+  /xmaxdev 596 def\n\
+  /ymindev 0 neg def\n\
+  /ymaxdev 842 def\n\
+  /dxdev 1 def\n\
+  /dydev 1 def\n\
+\n\
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\
+  %\n\
+  % End of Customizable Section\n\
+  %\n\
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\
+\n\
+  % logical pixel values\n\
+  /xminpixel t1ROIxmin 1000.0 div size mul def\n\
+  /xmaxpixel t1ROIxmax 1000.0 div size mul def\n\
+  /yminpixel t1ROIymin 1000.0 div size mul def\n\
+  /ymaxpixel t1ROIymax 1000.0 div size mul def\n\
+  /dxpixel 1 def\n\
+  /dypixel 1 def\n\
+\n\
+  % compute scales and set minimum scale\n\
+  /scalex xmaxdev xmindev sub xmaxpixel xminpixel sub div def\n\
+  /scaley ymaxdev ymindev sub ymaxpixel yminpixel sub div def\n\
+  scalex scaley gt { /scale scaley def } { /scale scalex def } ifelse\n\
+\n\
+  % Fill device page\n\
+  xmindev ymindev moveto\n\
+  xmaxdev 0 rlineto\n\
+  0 ymaxdev rlineto\n\
+  xmaxdev neg 0 rlineto\n\
+  0 ymaxdev neg rlineto\n\
+  closepath\n\
+  clip\n\
+  t1fillpage 1 eq\n\
+  {\n\
+    t1pagecolor setrgbcolor\n\
+    fill\n\
+  } if\n\
+\n\
+  % reassign device values\n\
+  /xmindev xminpixel scale mul def\n\
+  /xmaxdev xmaxpixel scale mul def\n\
+  /ymindev yminpixel scale mul def\n\
+  /ymaxdev ymaxpixel scale mul def\n\
+  /dxdev   dxpixel   scale mul def\n\
+  /dydev   dypixel   scale mul def\n\
+\n\
+  % translate coordinate system \n\
+  xminpixel scale mul neg yminpixel scale mul neg translate\n\
+  \n\
+  % Fill unit square of charspace coordinate system \n\
+  t1fillunitsquare 1 eq\n\
+  {\n\
+    t1unitsquarecolor setrgbcolor\n\
+    0 0 moveto\n\
+    size scale mul 0 rlineto\n\
+    0 size scale mul rlineto\n\
+    size scale mul neg 0 rlineto\n\
+    0 size scale mul neg rlineto\n\
+    closepath fill\n\
+  } if\n\
+} def\n\
+\n\
+/t1FinishPage {\n\
+  t1drawgrid 1 eq\n\
+  {\n\
+    t1gridcolor setrgbcolor\n\
+    t1gridscale setlinewidth\n\
+    t1griddash setdash\n\
+    % draw grid and align to the point (0,0)\n\
+    0 dxdev xmaxdev {\n\
+      /xval exch def\n\
+      xval ymindev moveto\n\
+      xval ymaxdev lineto\n\
+      stroke\n\
+    } for\n\
+    0 dxdev neg xmindev {\n\
+      /xval exch def\n\
+      xval ymindev moveto\n\
+      xval ymaxdev lineto\n\
+      stroke\n\
+    } for\n\
+    0 dydev ymaxdev {\n\
+      /yval exch def\n\
+      xmindev yval moveto\n\
+      xmaxdev yval lineto\n\
+      stroke\n\
+    } for\n\
+    0 dydev neg ymindev {\n\
+      /yval exch def\n\
+      xmindev yval moveto\n\
+      xmaxdev yval lineto\n\
+      stroke\n\
+    } for\n\
+  } if\n\
+} def\n\
+\n\
+% Define three arrow routines available for later providing the output with directions\n\
+/t1arrowhead {\n\
+  /tmpy exch def\n\
+  /tmpx exch def\n\
+  gsave\n\
+  t1arrowcolor setrgbcolor\n\
+  currx curry translate\n\
+  tmpy tmpx atan rotate\n\
+  newpath\n\
+  0 0 moveto\n\
+  0 2 arrowscale currentlinewidth neg mul mul rlineto\n\
+  6 arrowscale currentlinewidth mul mul 2 arrowscale currentlinewidth mul mul rlineto\n\
+  6 arrowscale currentlinewidth mul mul neg 2 arrowscale currentlinewidth mul mul rlineto\n\
+  closepath\n\
+  fill\n\
+  grestore\n\
+  tmpx\n\
+  tmpy\n\
+} def\n\
+/t1harrowhead {\n\
+  /tmpy exch def\n\
+  /tmpx exch def\n\
+  gsave\n\
+  t1harrowcolor setrgbcolor\n\
+  currhx currhy translate\n\
+  tmpy tmpx atan rotate\n\
+  newpath\n\
+  0 0 moveto\n\
+  0 2 arrowscale currentlinewidth neg mul mul rlineto\n\
+  6 arrowscale currentlinewidth mul mul 2 arrowscale currentlinewidth mul mul rlineto\n\
+  6 arrowscale currentlinewidth mul mul neg 2 arrowscale currentlinewidth mul mul rlineto\n\
+  closepath\n\
+  fill\n\
+  grestore\n\
+  tmpx\n\
+  tmpy\n\
+} def\n\
+/t1sarrowhead {\n\
+  /tmpy exch def\n\
+  /tmpx exch def\n\
+  gsave\n\
+  t1sarrowcolor setrgbcolor\n\
+  currsx currsy translate\n\
+  tmpy tmpx atan rotate\n\
+  newpath\n\
+  0 0 moveto\n\
+  0 2 arrowscale currentlinewidth neg mul mul rlineto\n\
+  6 arrowscale currentlinewidth mul mul 2 arrowscale currentlinewidth mul mul rlineto\n\
+  6 arrowscale currentlinewidth mul mul neg 2 arrowscale currentlinewidth mul mul rlineto\n\
+  closepath\n\
+  fill\n\
+  grestore\n\
+  tmpx\n\
+  tmpy\n\
+} def\n\
+\n\
+/t1rlineto {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1linecolor setrgbcolor\n\
+  t1linedash setdash\n\
+  t1linescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currx x2 add curry y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currx curry moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currx currx x2 add def\n\
+  /curry curry y2 add def\n\
+} def\n\
+\n\
+/t1srlineto {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1slinecolor setrgbcolor\n\
+  t1slinedash setdash\n\
+  t1slinescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currsx x2 add currsy y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currsx currsy moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currsx currsx x2 add def\n\
+  /currsy currsy y2 add def\n\
+} def\n\
+\n\
+/t1sprolongate {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1sprolongatecolor setrgbcolor\n\
+  t1sprolongatedash setdash\n\
+  t1sprolongatescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currsx x2 add currsy y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currsx currsy moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currsx currsx x2 add def\n\
+  /currsy currsy y2 add def\n\
+} def\n\
+\n\
+/t1hintedrlineto {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1hlinecolor setrgbcolor\n\
+  t1hlinedash setdash\n\
+  t1hlinescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currhx x2 add currhy y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currhx currhy moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currhx currhx x2 add def\n\
+  /currhy currhy y2 add def\n\
+} def\n\
+\n\
+/t1rmoveto {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1movecolor setrgbcolor\n\
+  t1movedash setdash\n\
+  t1movescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currx x2 add curry y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currx curry moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currx currx x2 add def\n\
+  /curry curry y2 add def\n\
+  /startx currx def\n\
+  /starty curry def\n\
+} def\n\
+\n\
+/t1srmoveto {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1smovecolor setrgbcolor\n\
+  t1smovedash setdash\n\
+  t1smovescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currsx x2 add currsy y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currsx currsy moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currsx currsx x2 add def\n\
+  /currsy currsy y2 add def\n\
+  /startsx currsx def\n\
+  /startsy currsy def\n\
+} def\n\
+\n\
+/t1hintedrmoveto {\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1hmovecolor setrgbcolor\n\
+  t1hmovedash setdash\n\
+  t1hmovescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currhx x2 add currhy y2 add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  currhx currhy moveto\n\
+  x2 y2 rlineto\n\
+  stroke\n\
+  /currhx currhx x2 add def\n\
+  /currhy currhy y2 add def\n\
+  /starthx currhx def\n\
+  /starthy currhy def\n\
+} def\n\
+\n\
+/t1rrcurveto {\n\
+  /y4 exch scale mul def\n\
+  /x4 exch scale mul def\n\
+  /y3 exch scale mul def\n\
+  /x3 exch scale mul def\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1curvecolor setrgbcolor\n\
+  t1curvedash setdash\n\
+  t1curvescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoffcurvepoints 1 eq\n\
+  {\n
+    newpath currx x2  add curry y2 add 1.0 currentlinewidth mul 0 360 arc closepath fill\n\
+    newpath currx x2 x3 add add curry y2 y3 add add 1.0 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currx x2 x3 x4 add add add curry y2 y3 y4 add add add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  t1showbeziertangents 1 eq\n\
+  {\n\
+    [2 2] 0 setdash\n\
+    t1curvetangentscale currentlinewidth mul setlinewidth\n\
+    currx curry moveto\n\
+    currx x2 add curry y2 add lineto\n\
+    stroke\n\
+    currx x2 x3 add add curry y2 y3 add add moveto\n\
+    currx x2 x3 x4 add add add curry y2 y3 y4 add add add lineto\n\
+    stroke\n\
+  } if\n\
+  t1curvedash setdash\n\
+  t1curvescale t1dumpstdlinewidth mul setlinewidth\n\
+  currx curry moveto\n\
+  x2 y2  x2 x3 add y2 y3 add  x2 x3 x4 add add y2 y3 y4 add add  rcurveto\n\
+  stroke\n\
+  /currx currx x2 x3 x4 add add add def\n\
+  /curry curry y2 y3 y4 add add add def\n\
+} def\n\
+\n\
+/t1srrcurveto {\n\
+  /y4 exch scale mul def\n\
+  /x4 exch scale mul def\n\
+  /y3 exch scale mul def\n\
+  /x3 exch scale mul def\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1scurvecolor setrgbcolor\n\
+  t1scurvedash setdash\n\
+  t1scurvescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoffcurvepoints 1 eq\n\
+  {\n\
+    newpath currsx x2  add currsy y2 add 1.0 currentlinewidth mul 0 360 arc closepath fill\n\
+    newpath currsx x2 x3 add add currsy y2 y3 add add 1.0 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currsx x2 x3 x4 add add add currsy y2 y3 y4 add add add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  t1showbeziertangents 1 eq\n\
+  {\n\
+    [2 2] 0 setdash\n\
+    t1curvetangentscale currentlinewidth mul setlinewidth\n\
+    currsx currsy moveto\n\
+    currsx x2 add currsy y2 add lineto\n\
+    stroke\n\
+    currsx x2 x3 add add currsy y2 y3 add add moveto\n\
+    currsx x2 x3 x4 add add add currsy y2 y3 y4 add add add lineto\n\
+    stroke\n\
+  } if\n\
+  t1scurvedash setdash\n\
+  t1scurvescale t1dumpstdlinewidth mul setlinewidth\n\
+  currsx currsy moveto\n\
+  x2 y2  x2 x3 add y2 y3 add  x2 x3 x4 add add y2 y3 y4 add add  rcurveto\n\
+  stroke\n\
+  /currsx currsx x2 x3 x4 add add add def\n\
+  /currsy currsy y2 y3 y4 add add add def\n\
+} def\n\
+\n\
+/t1hintedrrcurveto {\n\
+  /y4 exch scale mul def\n\
+  /x4 exch scale mul def\n\
+  /y3 exch scale mul def\n\
+  /x3 exch scale mul def\n\
+  /y2 exch scale mul def\n\
+  /x2 exch scale mul def\n\
+  t1hcurvecolor setrgbcolor\n\
+  t1hcurvedash setdash\n\
+  t1hcurvescale t1dumpstdlinewidth mul setlinewidth\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currhx x2  add currhy y2 add 1.0 currentlinewidth mul 0 360 arc closepath fill\n\
+    newpath currhx x2 x3 add add currhy y2 y3 add add 1.0 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  t1showoncurvepoints 1 eq\n\
+  {\n\
+    newpath currhx x2 x3 x4 add add add currhy y2 y3 y4 add add add 1.5 currentlinewidth mul 0 360 arc closepath fill\n\
+  } if\n\
+  t1showbeziertangents 1 eq\n\
+  {\n\
+    [2 2] 0 setdash\n\
+    t1curvetangentscale currentlinewidth mul setlinewidth\n\
+    currhx currhy moveto\n\
+    currhx x2 add currhy y2 add lineto\n\
+    stroke\n\
+    currhx x2 x3 add add currhy y2 y3 add add moveto\n\
+    currhx x2 x3 x4 add add add currhy y2 y3 y4 add add add lineto\n\
+    stroke\n\
+  } if\n\
+  t1hcurvedash setdash\n\
+  t1hcurvescale t1dumpstdlinewidth mul setlinewidth\n\
+  currhx currhy moveto\n\
+  x2 y2  x2 x3 add y2 y3 add  x2 x3 x4 add add y2 y3 y4 add add  rcurveto\n\
+  stroke\n\
+  /currhx currhx x2 x3 x4 add add add def\n\
+  /currhy currhy y2 y3 y4 add add add def\n\
+} def\n\
+\n\
+/t1sbw {\n\
+  /wy exch scale mul def\n\
+  /wx exch scale mul def\n\
+  /sby exch scale mul def\n\
+  /sbx exch scale mul def\n\
+  t1sbwcolor setrgbcolor\n\
+  newpath sbx sby 3 0 360 arc closepath fill\n\
+  newpath wx  wy  3 0 360 arc closepath fill\n\
+  /currx  sbx def\n\
+  /curry  sby def\n\
+  /currhx sbx def\n\
+  /currhy sby def\n\
+  /currsx sbx def\n\
+  /currsy sby def\n\
+} def\n\
+\n\
+/t1closepath {\n\
+  t1closepathdash setdash\n\
+  t1closepathscale t1dumpstdlinewidth mul setlinewidth\n\
+  t1closepathcolor setrgbcolor\n\
+  currx curry moveto\n\
+  startx starty lineto\n\
+  stroke\n\
+} def\n\
+\n\
+/t1sclosepath {\n\
+  t1sclosepathdash setdash\n\
+  t1sclosepathscale t1dumpstdlinewidth mul setlinewidth\n\
+  t1sclosepathcolor setrgbcolor\n\
+  currsx currsy moveto\n\
+  startsx startsy lineto\n\
+  stroke\n\
+} def\n\
+\n\
+/t1hintedclosepath {\n\
+  t1hclosepathdash setdash\n\
+  t1hclosepathscale t1dumpstdlinewidth mul setlinewidth\n\
+  t1hclosepathcolor setrgbcolor\n\
+  currhx currhy moveto\n\
+  starthx starthy lineto\n\
+  stroke\n\
+} def\n\
+\n\
+/t1vstem {\n\
+  t1drawstems 1 eq\n\
+  {\n\
+    /stemwidth exch scale mul def\n\
+    /stemstart exch scale mul def\n\
+    t1stemscale t1dumpstdlinewidth mul setlinewidth\n\
+    t1stemcolor setrgbcolor\n\
+    [] 0 setdash\n\
+    stemstart ymindev moveto\n\
+    stemstart ymaxdev lineto\n\
+    stroke\n\
+    [2 2] 0 setdash\n\
+    stemwidth stemstart add ymindev moveto\n\
+    stemwidth stemstart add ymaxdev lineto\n\
+    stroke\n\
+  } if\n\
+} def\n\
+\n\
+/t1alignedvstem {\n\
+  t1drawstems 1 eq\n\
+  {\n\
+    /stemwidth exch scale mul def\n\
+    /stemstart exch scale mul def\n\
+    t1alignedstemscale t1dumpstdlinewidth mul setlinewidth\n\
+    t1alignedstemcolor setrgbcolor\n\
+    [] 0 setdash\n\
+    stemstart ymindev moveto\n\
+    stemstart ymaxdev lineto\n\
+    stroke\n\
+    [2 2] 0 setdash\n\
+    stemwidth stemstart add ymindev moveto\n\
+    stemwidth stemstart add ymaxdev lineto\n\
+    stroke\n\
+  } if\n\
+} def\n\
+\n\
+/t1hstem {\n\
+  t1drawstems 1 eq\n\
+  {\n\
+    /stemwidth exch scale mul def\n\
+    /stemstart exch scale mul def\n\
+    t1stemscale t1dumpstdlinewidth mul setlinewidth\n\
+    t1stemcolor setrgbcolor\n\
+    [] 0 setdash\n\
+    xmindev stemstart moveto\n\
+    xmaxdev stemstart lineto\n\
+    stroke\n\
+    [2 2] 0 setdash\n\
+    xmindev stemwidth stemstart add moveto\n\
+    xmaxdev stemwidth stemstart add lineto\n\
+    stroke\n\
+  } if\n\
+} def\n\
+\n\
+/t1alignedhstem {\n\
+  t1drawstems 1 eq\n\
+  {\n\
+    /stemwidth exch scale mul def\n\
+    /stemstart exch scale mul def\n\
+    t1alignedstemscale t1dumpstdlinewidth mul setlinewidth\n\
+    t1alignedstemcolor setrgbcolor\n\
+    [] 0 setdash\n\
+    xmindev stemstart moveto\n\
+    xmaxdev stemstart lineto\n\
+    stroke\n\
+    [2 2] 0 setdash\n\
+    xmindev stemwidth stemstart add moveto\n\
+    xmaxdev stemwidth stemstart add lineto\n\
+    stroke\n\
+  } if\n\
+} def\n\
+\n\
+/t1bottomzone {\n\
+  t1drawzones 1 eq\n\
+  {\n\
+    /bottom exch scale mul def\n\
+    /top    exch scale mul def\n\
+    t1bottomzonescale t1dumpstdlinewidth mul setlinewidth\n\
+    t1bottomzonecolor setrgbcolor\n\
+    [] 0 setdash\n\
+    xmindev bottom moveto\n\
+    xmaxdev bottom lineto\n\
+    stroke\n\
+    [2 2] 0 setdash\n\
+    xmindev top moveto\n\
+    xmaxdev top lineto\n\
+    stroke\n\
+  } if\n\
+} def\n\
+\n\
+/t1topzone {\n\
+  t1drawzones 1 eq\n\
+  {\n\
+    /bottom exch scale mul def\n\
+    /top    exch scale mul def\n\
+    t1topzonescale t1dumpstdlinewidth mul setlinewidth\n\
+    t1topzonecolor setrgbcolor\n\
+    [2 2] 0 setdash\n\
+    xmindev bottom moveto\n\
+    xmaxdev bottom lineto\n\
+    stroke\n\
+    [] 0 setdash\n\
+    xmindev top moveto\n\
+    xmaxdev top lineto\n\
+    stroke\n\
+  } if\n\
+} def\n\
+\n\
+end\n\
+\n\
+% Next follows drawing code from charstring commands:\n", fp);
Index: grace/T1lib/type1/t1io.c
===================================================================
--- grace.orig/T1lib/type1/t1io.c
+++ grace/T1lib/type1/t1io.c
@@ -56,7 +56,7 @@
 /* we define this to switch to decrypt-debugging mode. The stream of
    decrypted bytes will be written to stdout! This contains binary
    charstring data */
-/* #define DEBUG_DECRYPTION  */
+/* #define DEBUG_DECRYPTION */
 /* #define DEBUG_PFB_BLOCKS  */
 
 /* Constants and variables used in the decryption */
@@ -82,8 +82,8 @@ STATIC unsigned char TheBuffer[F_BUFSIZ]
  
 /* Our routines */
 F_FILE *T1Open(), *T1eexec();
-int T1Close();
-int T1Read(), T1Getc(), T1Ungetc();
+int T1Close(F_FILE *);
+int T1Read(), T1Getc(F_FILE *), T1Ungetc(int,F_FILE *);
 void T1io_reset(void);
 STATIC int T1Decrypt(), T1Fill();
  
@@ -104,7 +104,7 @@ F_FILE *T1Open(fn, mode)
 #ifndef O_BINARY
 #  define O_BINARY 0x0
 #endif
-
+ 
   /* We know we are only reading */
   if ((of->fd=open(fn, O_RDONLY | O_BINARY)) < 0) return NULL;
 
@@ -154,7 +154,7 @@ int T1Getc(f)        /* Read one charact
     T1Gets(): Read a line of the file and save it to string. At most,
     (size-1) bytes are read. The user *must* ensure (by making size large
     enough) that "eexec" does not get split between two calls because
-    in this case, eexec-encryption does not set in.
+    in this case, eexec-decryption does not set in.
     ------------------------------------------------------------ */
 int T1Gets(char *string,
 	   int size,
@@ -198,7 +198,7 @@ int T1Gets(char *string,
     }
 
     /* do not skip white space as required by Adobe spec, because
-       if have found fonts where the first encrypted byte was of
+       I have found fonts where the first encrypted byte was of
        white space type. */
     if ( (eexec_startOK==1) && (eexec_endOK==1)) {
       T1eexec( f);
@@ -228,7 +228,15 @@ int T1Gets(char *string,
        seen a pfb-file which uses the sequence '\r''\n' as a newline
        indicator, as known from DOS. So we don't take care for this case
        and simply map both single characters \r and \n into \n. Of course,
-       this can only be done in the ASCII section of the font. */
+       this can only be done in the ASCII section of the font.
+
+       2002-10-26: Well, life life is teaching me better: There *are* fonts
+       out there, ASCII encoded pfa's, that use the crappy DOSian 0x0d 0x0a
+       sequence as line separation. In order to make it still work, we absorb
+       the byte 0x0a. Failure to do so result in decryption failure. The
+       workaround is implemented T1eexec():
+       
+    */
     if ( *(f->b_ptr)=='\n' || *(f->b_ptr)=='\r') {
       if (in_eexec==0)
 	string[i-1]='\n';  
@@ -269,6 +277,7 @@ int T1GetTrailer(char *string,
   char *ctmP;
   int i=0, j;
   int datasize;
+  int len;
   
   datasize=size;
   
@@ -289,11 +298,18 @@ int T1GetTrailer(char *string,
       datasize=i; /* we skip the segment marker of pfb-files */
     }
     if ((ctmP=strstr( &(buf[j]), "cleartomark"))!=NULL) {
-      memcpy( string, &(buf[i]), datasize-i);
-      string[datasize-i]='\0';
+      /* buf[i-1] now is the first character after cleartomark. Advance now
+	 to the next non white character of EOF. */
+      len = datasize - i;
+      while ( (isspace( (int)(buf[i-1])) != 0) &&
+	      (i < datasize) ) {
+	++i;
+      }
+      memcpy( string, &(buf[i-1]), len);
+      string[len]='\0';
       lseek( f->fd, off_save, SEEK_SET);
       free( buf);
-      return( datasize-i);
+      return len;
     }
     i--;
   }
@@ -386,6 +402,7 @@ F_FILE *T1eexec(f)   /* Initialization *
   int H;
   
   unsigned char *p;
+  int testchar;
   unsigned char randomP[8];
  
   r = 55665;  /* initial key */
@@ -394,7 +411,15 @@ F_FILE *T1eexec(f)   /* Initialization *
 #ifdef DEBUG_DECRYPTION
   printf("T1eexec(1): first 20 bytes=%.20s, b_cnt=%d\n", f->b_ptr, f->b_cnt);
 #endif
-  
+
+  /* As the very first action we check the first byte against 0x0a.
+     This mmight happen in context with the T1gets() function for
+     pfa files that use DOSian linefeed style. If that character appears
+     here, we absorb it (see also T1Gets()!). 
+  */
+  if ( ( testchar = T1Getc( f)) != 0x0a )
+    T1Ungetc( testchar, f);
+    
   /* Consume the 4 random bytes, determining if we are also to
      ASCIIDecodeHex as we process our input.  (See pages 63-64
      of the Adobe Type 1 Font Format book.)  */
Index: grace/T1lib/type1/t1stdio.h
===================================================================
--- grace.orig/T1lib/type1/t1stdio.h
+++ grace/T1lib/type1/t1stdio.h
@@ -63,7 +63,9 @@ typedef struct F_FILE {
 #ifndef NULL
 #define NULL 0       /* null pointer */
 #endif
+#ifndef EOF
 #define EOF (-1)     /* end of file */
+#endif
 #define F_BUFSIZ (512)
  
 #define getc(f) \
@@ -74,7 +76,7 @@ typedef struct F_FILE {
   )
  
 extern FILE *T1Open(), *T1eexec();
-extern int T1Close(), T1Ungetc(), T1Read();
+extern int T1Close(F_FILE *), T1Ungetc(int,F_FILE *), T1Read();
 
 #define  fclose(f)          T1Close(f)
 #define  fopen(name,mode)   T1Open(name,mode)
Index: grace/T1lib/type1/type1.c
===================================================================
--- grace.orig/T1lib/type1/type1.c
+++ grace/T1lib/type1/type1.c
@@ -42,13 +42,29 @@
 /*                 (Font level hints & stem hints)                   */
 /*                                                                   */
 /*********************************************************************/
- 
+
+
+/* Write debug info into a PostScript file? */
+/* #define DUMPDEBUGPATH */
+/* If Dumping a debug path, should we dump both character and
+   outline path? Warning: Do never enable this, unless, your name
+   is Rainer Menzner and you know what you are doing! */
+/* #define DUMPDEBUGPATHBOTH */
+
+/* Generate a bunch of stderr output to understand and debug
+   the generation of outline surrounding curves */
+/* #define DEBUG_OUTLINE_SURROUNDING */
+
+#define SUBPATH_CLOSED     1
+#define SUBPATH_OPEN       0
+
 /******************/
 /* Include Files: */
 /******************/
 #include  "types.h"
 #include  <stdio.h>          /* a system-dependent include, usually */
 #include  <math.h>
+#include  <stdlib.h>
 
 #include  "objects.h"
 #include  "spaces.h"
@@ -60,7 +76,218 @@ typedef struct xobject xobject;
 #include  "util.h"       /* PostScript objects */
 #include  "fontfcn.h"
 #include  "blues.h"          /* Blues structure for font-level hints */
- 
+
+
+/* Considerations about hinting (2002-07-11, RMz (Author of t1lib))
+
+   It turns out that the hinting code as used until now produces some
+   artifacts in which may show up in suboptimal bitmaps. I have therefore
+   redesigned the algorithm. It is generally a bad idea to hint every
+   point that falls into a stem hint.
+
+   The idea is to hint only points for
+   which at least one of the two neighboring curve/line segments is aligned
+   with the stem in question. For curves, we are speaking about the
+   tangent line, that is, the line defined by (p1-p2) or (p3-p4).
+
+   For vertical stems this means, that only points which are connected
+   exactly into vertical direction are hinted. That is, the dx of the
+   respective curve vanishes. For horizontal stems, accordingly, dy must
+   vanish at least on one hand side of the point in order to be considered
+   as a stem.
+
+   Unfortunately this principle requires information about both sides of the
+   neighborhood of the point in question. In other words, it is not possible
+   to define a segment completely until the next segment has been inspected.
+   The idea thus is not compatible with the code in this file.
+
+   Furthermore, if certain points of a character outline are hinted according
+   to the stem hint info from the charstring, the non-hinted points may not be
+   left untouched. This would lead to very strong artifacts at small sizes,
+   especially if characters are defined in terms of curves. This is predominantly
+   the case for ComputerModern, for example.
+
+   To conclude, it is best to build a point list from the character description
+   adjust the non-hinted points after hinting has been completely finished. 
+
+   
+   Another rule we should state is
+   
+   We can work around this by not directly connecting the path segments at
+   the end of the lineto/curveto's, but rather deferring this to the beginning
+   of the next path constructing function. It's not great but it should work.
+
+   The functions that produce segments are
+
+   1) RMoveTo()
+   2) RLineto()
+   3) RRCurveTo()
+   4) DoClosePath()
+
+   Their code is moved into the switch statement of the new function
+   handleCurrentSegment(). This function is called when a new segment generating
+   operation has been decoded from the charstring. At this point a serious
+   decision about how to hint the points is possible.
+
+   ...
+*/
+
+
+/* The following struct is used to record points that define a path
+   in absolute charspace coordinates. x and y describe the location and
+   hinted, if greater 0, indicates that this point has been hinted. Bit 0
+   (0x1) indicates vertically adjusted and Bit 1 (0x2) indicates
+   horizontally adjusted. If hinted == -1, this point is not to be hinted
+   at all. This, for example, is the case for a a (H)SBW command.
+
+   The member type can be one of
+
+   PPOINT_SBW                --> initial path point as setup by (H)SBW
+   PPOINT_MOVE               --> point that finishes a MOVE segment
+   PPOINT_LINE               --> point that finishes a LINE segment
+   PPOINT_BEZIER_B           --> second point of a BEZIER segment
+   PPOINT_BEZIER_C           --> third point of a BEZIER segment
+   PPOINT_BEZIER_D           --> fourth point of a BEZIER segment
+   PPOINT_CLOSEPATH          --> a ClosePath command
+   PPOINT_ENDCHAR            --> an EndChar command
+   PPOINT_SEAC               --> a Standard Encoding Accented Char command
+   PPOINT_NONE               --> an invalid entry
+   
+
+   Note: BEZIER_B and BEZIER_C points generally cannot be flagged as
+   being hinted because are off-curve points.
+*/
+typedef struct 
+{
+  double x;              /* x-coordinate */
+  double y;              /* y-coordinate */
+  double ax;             /* adjusted x-coordinate */
+  double ay;             /* adjusted y-coordinate */
+  double dxpr;           /* x-shift in right path due to incoming segment (previous) */
+  double dypr;           /* y-shift in right path due to incoming segment (previous) */
+  double dxnr;           /* x-shift in right path due to outgoing segment (next) */
+  double dynr;           /* y-shift in right path due to incoming segment (next) */
+  double dxir;           /* x-shift in right path resulting from prologation of the linkend tangents (intersect) */
+  double dyir;           /* y-shift in right path resulting from prologation of the linkend tangents (intersect) */
+  double dist2prev;      /* distance to the previous point in path (used only for stroking) */
+  double dist2next;      /* distance to the next point in path (used only for stroking) */
+  enum 
+  {
+    PPOINT_SBW,
+    PPOINT_MOVE,
+    PPOINT_LINE,
+    PPOINT_BEZIER_B,
+    PPOINT_BEZIER_C,
+    PPOINT_BEZIER_D,
+    PPOINT_CLOSEPATH,
+    PPOINT_ENDCHAR,
+    PPOINT_SEAC,
+    PPOINT_NONE
+  } type;                /* type of path point */
+  signed char   hinted;  /* is this point hinted? */
+  unsigned char shape;   /* is the outline concave or convex or straight at this point? This flag
+			    is only relevant for onCurve points in the context of stroking! */
+} PPOINT;
+
+#define CURVE_NONE            0x00
+#define CURVE_STRAIGHT        0x01
+#define CURVE_CONVEX          0x02
+#define CURVE_CONCAVE         0x03
+
+#ifdef DEBUG_OUTLINE_SURROUNDING
+static char* pptypes[] = {
+  "PPOINT_SBW",
+  "PPOINT_MOVE",
+  "PPOINT_LINE",
+  "PPOINT_BEZIER_B",
+  "PPOINT_BEZIER_C",
+  "PPOINT_BEZIER_D",
+  "PPOINT_CLOSEPATH",
+  "PPOINT_ENDCHAR",
+  "PPOINT_SEAC"
+};
+static char* ppshapes[] = {
+  "SHAPE_OFFCURVE",
+  "SHAPE_STRAIGHT",
+  "SHAPE_CONVEX",
+  "SHAPE_CONCAVE"
+};
+#endif
+
+
+/* The PPOINT structs are organized in an array which is allocated
+   in chunks of 256 entries. A new point is allocated by a call to
+   nextPPoint and returns the index in the array of the newly
+   allocated point. */
+static PPOINT* ppoints       = NULL;
+static long numppoints       = 0;
+static long numppointchunks  = 0;
+static int  closepathatfirst = 0;
+
+static long nextPPoint( void) 
+{
+  ++numppoints;
+  /* Check whether to reallocate */
+  if ( numppoints > (numppointchunks * 256) ) {
+    ++numppointchunks;
+    ppoints = (PPOINT*) realloc( ppoints, (numppointchunks * 256) * sizeof( PPOINT));
+  }
+  /* return the current index */
+  return numppoints-1;
+}
+
+static void createFillPath( void);
+static void createStrokePath( double strokewidth, int subpathclosed);
+static void createClosedStrokeSubPath( long startind, long stopind,
+				       double strokewidth, int subpathclosed);
+static long computeDistances( long startind, long stopind, int subpathclosed);
+static void transformOnCurvePathPoint( double strokewidth,
+				       long prevind, long currind, long lastind);
+static void transformOffCurvePathPoint( double strokewidth, long currind);
+/* values for flag:
+   INTERSECT_PREVIOUS:     only take previous path segment into account.
+   INTERSECT_NEXT:         only take next path segment into account. 
+   INTERSECT_BOTH:         do a real intersection
+*/
+#define INTERSECT_PREVIOUS    -1
+#define INTERSECT_NEXT         1
+#define INTERSECT_BOTH         0
+static void intersectRight( long index, double halfwidth, long flag);
+/* values for orientation:
+   PATH_LEFT:              we are constructing the left path.
+   PATH_RIGHT:             we are constructing the right path.
+*/
+#define PATH_LEFT              1
+#define PATH_RIGHT             0
+/* values for position:
+   PATH_START:             current point starts the current path (use next-values).
+   PATH_END:               current point ends the current path (use prev-values).
+*/
+#define PATH_START             0
+#define PATH_END               1
+static void linkNode( long index, int position, int orientation);
+
+
+static long handleNonSubPathSegments( long pindex);
+static void handleCurrentSegment( long pindex);
+static void adjustBezier( long pindex);
+
+static double  size;
+static double scxx, scyx, scxy, scyy;
+static double  up;
+
+#ifdef DUMPDEBUGPATH
+static FILE*   psfile = NULL;
+static void PSDumpProlog( FILE* fp);
+static void PSDumpEpilog( FILE* fp);
+#endif
+
+/* variables for querying SEAC from external */
+static int isseac                = 0;
+static unsigned char seacbase    = 0;
+static unsigned char seacaccent  = 0;
+
+
 /**********************************/
 /* Type1 Constants and Structures */
 /**********************************/
@@ -71,7 +298,7 @@ typedef struct xobject xobject;
 #define MAXLABEL 256       /* Maximum number of new hints */
 #define MAXSTEMS 512       /* Maximum number of VSTEM and HSTEM hints */
 #define EPS 0.001          /* Small number for comparisons */
- 
+
 /************************************/
 /* Adobe Type 1 CharString commands */
 /************************************/
@@ -143,7 +370,7 @@ static LONG tmpi;    /* Store converted
 
 #define CC IfTrace1(TRUE, "Char \"%s\": ", currentchar)
 
-/* To make some compiler happy we have to care about return  types! */
+/* To make some compiler happy we have to care about return types! */
 #define Errori {errflag = TRUE; return 0;}    /* integer */
 #define Errord {errflag = TRUE; return 0.0;}  /* double */
 #define Errorv {errflag = TRUE; return;}      /* void */
@@ -159,21 +386,47 @@ static LONG tmpi;    /* Store converted
 /********************/
 /* global variables */
 /********************/
-struct stem {                     /* representation of a STEM hint */
-    int vertical;                 /* TRUE if vertical, FALSE otherwise */
-    DOUBLE x, dx;                 /* interval of vertical stem */
-    DOUBLE y, dy;                 /* interval of horizontal stem */
-    struct segment *lbhint, *lbrevhint;   /* left  or bottom hint adjustment */
-    struct segment *rthint, *rtrevhint;   /* right or top    hint adjustment */
+struct stem {              /* representation of a STEM hint */
+  int vertical;                 /* TRUE if vertical, FALSE otherwise */
+  DOUBLE x, dx;                 /* interval of vertical stem */
+  DOUBLE y, dy;                 /* interval of horizontal stem */
+  DOUBLE alx, aldx;             /* interval of grid-aligned vertical stem */
+  DOUBLE aly, aldy;             /* interval of grid-aligned horizontal stem */
+  double lbhintval;             /* adjustment value for left or bottom hint */
+  double rthintval;             /* adjustment value for right ir top hint */
 };
  
+/******************************************************/
+/* Subroutines and statics for the Type1Char routines */
+/******************************************************/
+ 
+static int strindex; /* index into PostScript string being interpreted */
+static double currx, curry;           /* accumulated x and y values */
+static double hcurrx, hcurry;         /* accumulated values with hinting */
+
+
+struct callstackentry {
+  psobj *currstrP;        /* current CharStringP */
+  int currindex;          /* current strindex */
+  unsigned short currkey; /* current decryption key */
+  };
+ 
+static DOUBLE Stack[MAXSTACK];
+static int Top;
+static struct callstackentry CallStack[MAXCALLSTACK];
+static int CallTop;
+static DOUBLE PSFakeStack[MAXPSFAKESTACK];
+static int PSFakeTop;
+ 
+
 extern struct XYspace *IDENTITY;
  
 static DOUBLE escapementX, escapementY;
 static DOUBLE sidebearingX, sidebearingY;
 static DOUBLE accentoffsetX, accentoffsetY;
  
-static struct segment *path;
+static struct segment *path;    /* path of basechar */
+static struct segment *apath;   /* pass of accent char */
 static int errflag;
  
 /*************************************************/
@@ -207,11 +460,6 @@ static int Sbw();
 static int CallOtherSubr();
 static int SetCurrentPoint();
 
-/*****************************************/
-/* statics for Flex procedures (FlxProc) */
-/*****************************************/
-static struct segment *FlxOldPath; /* save path before Flex feature */
- 
 /******************************************************/
 /* statics for Font level hints (Blues) (see blues.h) */
 /******************************************************/
@@ -332,6 +580,16 @@ static int ComputeAlignmentZones()
 	    blues->FamilyBlues[i];
 	  alignmentzones[numalignmentzones].topy =
 	    blues->FamilyBlues[i+1];
+#ifdef DUMPDEBUGPATH
+	  if ( psfile != NULL ) {
+	    if ( alignmentzones[numalignmentzones].topzone == TRUE )
+	      fprintf( psfile, "%f %f t1topzone\n", (blues->FamilyBlues[i])*up,
+		       (blues->BlueValues[i+1])*up);
+	    else
+	      fprintf( psfile, "%f %f t1bottomzone\n", (blues->FamilyBlues[i])*up,
+		       (blues->BlueValues[i+1])*up);
+	  }
+#endif
 	  continue;
 	}
       }
@@ -339,6 +597,16 @@ static int ComputeAlignmentZones()
     /* use this font's Blue zones */
     alignmentzones[numalignmentzones].bottomy = blues->BlueValues[i];
     alignmentzones[numalignmentzones].topy = blues->BlueValues[i+1];
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL ) {
+      if ( alignmentzones[numalignmentzones].topzone == TRUE )
+	fprintf( psfile, "%f %f t1topzone\n", (blues->BlueValues[i])*up,
+		 (blues->BlueValues[i+1])*up);
+      else
+	fprintf( psfile, "%f %f t1bottomzone\n", (blues->BlueValues[i])*up,
+		 (blues->BlueValues[i+1])*up);
+    }
+#endif
   }
  
   /* do the OtherBlues zones */
@@ -362,6 +630,12 @@ static int ComputeAlignmentZones()
 	    blues->FamilyOtherBlues[i];
 	  alignmentzones[numalignmentzones].topy =
 	    blues->FamilyOtherBlues[i+1];
+#ifdef DUMPDEBUGPATH
+	  if ( psfile != NULL ) {
+	    fprintf( psfile, "%f %f t1bottomzone\n", (blues->FamilyOtherBlues[i])*up,
+		     (blues->FamilyOtherBlues[i+1])*up);
+	  }
+#endif
 	  continue;
 	}
       }
@@ -369,6 +643,12 @@ static int ComputeAlignmentZones()
     /* use this font's Blue zones (as opposed to the Family Blues */
     alignmentzones[numalignmentzones].bottomy = blues->OtherBlues[i];
     alignmentzones[numalignmentzones].topy = blues->OtherBlues[i+1];
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL ) {
+      fprintf( psfile, "%f %f t1bottomzone\n", (blues->OtherBlues[i])*up,
+	       (blues->OtherBlues[i+1])*up);
+    }
+#endif
   }
   return(0);
   
@@ -395,20 +675,7 @@ static int InitStems()  /* Initialize th
   
 }
  
-static int FinitStems()  /* Terminate the STEM hint data structures */
-{
-  int i;
- 
-  for (i = 0; i < numstems; i++) {
-    Destroy(stems[i].lbhint);
-    Destroy(stems[i].lbrevhint);
-    Destroy(stems[i].rthint);
-    Destroy(stems[i].rtrevhint);
-  }
-  return(0);
-  
-}
- 
+
 /*******************************************************************/
 /* Compute the dislocation that a stemhint should cause for points */
 /* inside the stem.                                                */
@@ -441,10 +708,9 @@ int stemno;
   else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001)
     rotated = FALSE; /* Char is upright (0 or 180 degrees), possibly oblique. */
   else {
-    stems[stemno].lbhint = NULL; /* Char is at non-axial angle, ignore hints. */
-    stems[stemno].lbrevhint = NULL;
-    stems[stemno].rthint = NULL;
-    stems[stemno].rtrevhint = NULL;
+    stems[stemno].lbhintval = 0.0; /* Char is at non-axial angle, ignore hints. */
+    stems[stemno].rthintval = 0.0;
+    ProcessHints = 0;
     return(0);
   }
  
@@ -454,10 +720,18 @@ int stemno;
     verticalondevice = !rotated;
     stemstart = stems[stemno].x;
     stemwidth = stems[stemno].dx;
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1vstem\n", stemstart*up, stemwidth*up);
+#endif
   } else {
     verticalondevice = rotated;
     stemstart = stems[stemno].y;
     stemwidth = stems[stemno].dy;
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1hstem\n", stemstart*up, stemwidth*up);
+#endif
   }
  
   /* Determine how many pixels (non-negative) correspond to 1 character space
@@ -476,7 +750,7 @@ int stemno;
     unitpixels = FABS(Ypixels);
  
   onepixel = 1.0 / unitpixels;
- 
+
   /**********************/
   /* ADJUST STEM WIDTHS */
   /**********************/
@@ -501,7 +775,7 @@ int stemno;
         widthdiff = blues->StemSnapH[i] - stemwidth;
     }
   }
- 
+
   /* Only expand or contract stems if they differ by less than 1 pixel from
      the closest standard width, otherwise make the width difference = 0. */
   if (FABS(widthdiff) > onepixel)
@@ -528,7 +802,7 @@ int stemno;
  
   stemshift = 0.0;
  
-  if (!stems[stemno].vertical) {
+  if ( !stems[stemno].vertical ) {
  
     /* Get bottom and top boundaries of the stem. */
     stembottom = stemstart;
@@ -648,11 +922,18 @@ int stemno;
         rthintvalue = stemshift + widthdiff; /* top    */
       }
 
-      stems[stemno].lbhint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  lbhintvalue));
-      stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue));
-      stems[stemno].rthint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  rthintvalue));
-      stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue));
- 
+      stems[stemno].lbhintval = lbhintvalue;
+      stems[stemno].rthintval = rthintvalue;
+
+      /* store grid-aligned stems values */
+      stems[stemno].aly       = stemstart + lbhintvalue;
+      stems[stemno].aldy      = stemwidth + widthdiff;
+      
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL )
+	fprintf( psfile, "%f %f t1alignedhstem\n", (stems[stemno].aly)*up,
+		 (stems[stemno].aldy)*up);
+#endif
       return(0);
  
     } /* endif (i < numalignmentzones) */
@@ -671,157 +952,180 @@ int stemno;
   rthintvalue = stemshift + widthdiff / 2; /* right or top    */
  
   if (stems[stemno].vertical) {
-    stems[stemno].lbhint    = (struct segment *)Permanent(Loc(CharSpace,  lbhintvalue, 0.0));
-    stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, -lbhintvalue, 0.0));
-    stems[stemno].rthint    = (struct segment *)Permanent(Loc(CharSpace,  rthintvalue, 0.0));
-    stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, -rthintvalue, 0.0));
+    stems[stemno].lbhintval = lbhintvalue;
+    stems[stemno].rthintval = rthintvalue;
+
+    /* store grid-aligned stem values */
+    stems[stemno].alx       = stemstart + stemshift;
+    stems[stemno].aldx      = stemwidth + widthdiff;
+      
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1alignedvstem\n", (stems[stemno].alx)*up,
+	       (stems[stemno].aldx)*up);
+#endif
   } else {
-    stems[stemno].lbhint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  lbhintvalue));
-    stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue));
-    stems[stemno].rthint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  rthintvalue));
-    stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue));
+    stems[stemno].lbhintval = lbhintvalue;
+    stems[stemno].rthintval = rthintvalue;
+
+    /* store grid-aligned stem values */
+    stems[stemno].aly       = stemstart + stemshift;
+    stems[stemno].aldy      = stemwidth + widthdiff;
+      
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1alignedhstem\n", (stems[stemno].aly)*up,
+    	       (stems[stemno].aldy)*up);
+#endif
   }
   return(0);
   
 }
  
+
 #define LEFT   1
 #define RIGHT  2
 #define BOTTOM 3
 #define TOP    4
- 
-/*********************************************************************/
-/* Adjust a point using the given stem hint.  Use the left/bottom    */
-/* hint value or the right/top hint value depending on where the     */
-/* point lies in the stem.                                           */
-/*********************************************************************/
-static struct segment *Applyhint(p, stemnumber, half)
-struct segment *p;
-int stemnumber, half;
-{
-  if (half == LEFT || half == BOTTOM)
-    return Join(p, stems[stemnumber].lbhint); /* left  or bottom hint */
-  else
-    return Join(p, stems[stemnumber].rthint); /* right or top    hint */
-}
- 
-/*********************************************************************/
-/* Adjust a point using the given reverse hint.  Use the left/bottom */
-/* hint value or the right/top hint value depending on where the     */
-/* point lies in the stem.                                           */
-/*********************************************************************/
-static struct segment *Applyrevhint(p, stemnumber, half)
-struct segment *p;
-int stemnumber, half;
-{
-  if (half == LEFT || half == BOTTOM)
-    return Join(p, stems[stemnumber].lbrevhint); /* left  or bottom hint */
-  else
-    return Join(p, stems[stemnumber].rtrevhint); /* right or top    hint */
-}
- 
+
+
 /***********************************************************************/
 /* Find the vertical and horizontal stems that the current point       */
 /* (x, y) may be involved in.  At most one horizontal and one vertical */
 /* stem can apply to a single point, since there are no overlaps       */
 /* allowed.                                                            */
-/*   The actual hintvalue is returned as a location.                   */
+/*   The point list updated by this function.                          */
 /* Hints are ignored inside a DotSection.                              */
 /***********************************************************************/
-static struct segment *FindStems(x, y, dx, dy)
-DOUBLE x, y, dx, dy;
+static void FindStems( double x, double y,
+		       double dx, double dy,
+		       double nextdx, double nextdy)
 {
   int i;
   int newvert, newhor;
-  struct segment *p;
   int newhorhalf, newverthalf;
+
+  /* The following values will be used to decide whether a curve
+     crosses or touches a stem in an aligned manner or not */
+  double dtana     = 0.0;   /* tangent of pre-delta against horizontal line */ 
+  double dtanb     = 0.0;   /* tangent of pre-delta against vertical line */ 
+  double nextdtana = 0.0;   /* tangent of post-delta against horizontal line */ 
+  double nextdtanb = 0.0;   /* tangent of post-delta against vertical line */ 
+  
+  if (ppoints == NULL || numppoints < 1) Error0v("FindStems: No previous point!\n");
  
-  if (InDotSection) return(NULL);
- 
+  /* setup default hinted position */
+  ppoints[numppoints-1].ax     = ppoints[numppoints-1].x;
+  ppoints[numppoints-1].ay     = ppoints[numppoints-1].y;
+  if ( ppoints[numppoints-1].hinted == -1 )
+    /* point is not to be hinted! */
+    return;
+  else
+    ppoints[numppoints-1].hinted = 0;
+
+  if ( InDotSection )
+    return;
+
+  if ( ProcessHints == 0 ) {
+    return;
+  }
+
+  /* setup (absolute) tangent values and define limits that indicate nearly
+     horizontal or nearly vertical alignment */
+#define NEARLYVERTICAL     0.2   /* This corresponds to about 11.3 degress deviation */
+#define NEARLYHORIZONTAL   0.2   /* from the ideal direction.                        */
+  if ( dy != 0 ) {
+    dtana = dx/dy;
+    if ( dtanb < 0.0 )
+      dtana = -dtana;
+  }
+  else
+    dtana = NEARLYHORIZONTAL;
+  if ( dx != 0 ) {
+    dtanb = dy/dx;
+    if ( dtanb < 0.0 )
+      dtanb = -dtanb;
+  }
+  else
+    dtanb = NEARLYVERTICAL;
+  if ( nextdy != 0 ) {
+    nextdtana = nextdx/nextdy;
+    if ( nextdtana < 0.0 )
+      nextdtana = -nextdtana;
+  }
+  else
+    nextdtana = NEARLYHORIZONTAL;
+  if ( nextdx != 0 ) {
+    nextdtanb = nextdy/nextdx;
+    if ( nextdtanb < 0.0 )
+      nextdtanb = -nextdtanb;
+  }
+  else
+    nextdtanb = NEARLYVERTICAL;
+  
   newvert = newhor = -1;
   newhorhalf = newverthalf = -1;
- 
+
   for (i = currstartstem; i < numstems; i++) {
     if (stems[i].vertical) { /* VSTEM hint */
-      if ((x >= stems[i].x - EPS) &&
-          (x <= stems[i].x+stems[i].dx + EPS)) {
-        newvert = i;
-        if (dy != 0.0) {
-          if (dy < 0) newverthalf = LEFT;
-          else        newverthalf = RIGHT;
-        } else {
-          if (x < stems[i].x+stems[i].dx / 2) newverthalf = LEFT;
-          else                                newverthalf = RIGHT;
-        }
+      /* OK, stem is crossed in an aligned way */
+      if ( (dtana <= NEARLYVERTICAL) || (nextdtana <= NEARLYVERTICAL)) {
+	if ((x >= stems[i].x ) &&
+	    (x <= stems[i].x+stems[i].dx )) {
+	  newvert = i;
+	  if (x < stems[i].x+stems[i].dx / 2)
+	    newverthalf = LEFT;
+	  else
+	    newverthalf = RIGHT;
+	}
       }
-    } else {                 /* HSTEM hint */
-      if ((y >= stems[i].y - EPS) &&
-          (y <= stems[i].y+stems[i].dy + EPS)) {
-        newhor = i;
-        if (dx != 0.0) {
-          if (dx < 0) newhorhalf = TOP;
-          else        newhorhalf = BOTTOM;
-        } else {
-          if (y < stems[i].y+stems[i].dy / 2) newhorhalf = BOTTOM;
-          else                                newhorhalf = TOP;
-        }
+    }
+    else {                 /* HSTEM hint */
+      if ( (dtanb <= NEARLYHORIZONTAL) || (nextdtanb <= NEARLYHORIZONTAL)) {
+	/* OK, stem is crossed in an aligned way */
+	if ((y >= stems[i].y ) &&
+	    (y <= stems[i].y+stems[i].dy )) {
+	  newhor = i;
+	  if (y < stems[i].y+stems[i].dy / 2)
+	    newhorhalf = BOTTOM;
+	  else
+	    newhorhalf = TOP;
+	}
       }
     }
   }
- 
-  p = NULL;
- 
-  if (newvert == -1 && oldvert == -1) ; /* Outside of any hints */
-  else if (newvert == oldvert &&
-    newverthalf == oldverthalf); /* No hint change */
-  else if (oldvert == -1) { /* New vertical hint in effect */
-    p = Applyhint(p, newvert, newverthalf);
-  } else if (newvert == -1) { /* Old vertical hint no longer in effect */
-    p = Applyrevhint(p, oldvert, oldverthalf);
-  } else { /* New vertical hint in effect, old hint no longer in effect */
-    p = Applyrevhint(p, oldvert, oldverthalf);
-    p = Applyhint(p, newvert, newverthalf);
-  }
- 
-  if (newhor == -1 && oldhor == -1) ; /* Outside of any hints */
-  else if (newhor == oldhor &&
-    newhorhalf == oldhorhalf) ; /* No hint change */
-  else if (oldhor == -1) { /* New horizontal hint in effect */
-    p = Applyhint(p, newhor, newhorhalf);
-  } else if (newhor == -1) { /* Old horizontal hint no longer in effect */
-    p = Applyrevhint(p, oldhor, oldhorhalf);
-  }
-  else { /* New horizontal hint in effect, old hint no longer in effect */
-    p = Applyrevhint(p, oldhor, oldhorhalf);
-    p = Applyhint(p, newhor, newhorhalf);
+
+  if ( newvert != -1 ) {
+    /* mark the latest point in the point list to be v-hinted! */
+    if ( newverthalf == LEFT ) {
+      /* left hint */
+      ppoints[numppoints-1].ax  += stems[newvert].lbhintval;
+    }
+    else {
+       /* right hint */
+      ppoints[numppoints-1].ax  += stems[newvert].rthintval;
+    }
+    ppoints[numppoints-1].hinted |= 0x01;
   }
- 
-  oldvert = newvert; oldverthalf = newverthalf;
-  oldhor  = newhor;  oldhorhalf  = newhorhalf;
- 
-  return p;
+  if ( newhor != -1 ) {
+    /* mark the latest point in the point list to be h-hinted! */
+    if ( newhorhalf == BOTTOM ) {
+      /* bottom hint */
+      ppoints[numppoints-1].ay  += stems[newhor].lbhintval;
+    }
+    else {
+       /* top hint */
+      ppoints[numppoints-1].ay  += stems[newhor].rthintval;
+    }
+    ppoints[numppoints-1].hinted |= 0x02;
+  }
+  
+  return;
+  
 }
- 
-/******************************************************/
-/* Subroutines and statics for the Type1Char routines */
-/******************************************************/
- 
-static int strindex; /* index into PostScript string being interpreted */
-static DOUBLE currx, curry; /* accumulated x and y values for hints */
- 
-struct callstackentry {
-  psobj *currstrP;        /* current CharStringP */
-  int currindex;          /* current strindex */
-  unsigned short currkey; /* current decryption key */
-  };
- 
-static DOUBLE Stack[MAXSTACK];
-static int Top;
-static struct callstackentry CallStack[MAXCALLSTACK];
-static int CallTop;
-static DOUBLE PSFakeStack[MAXPSFAKESTACK];
-static int PSFakeTop;
- 
+
+
+/* Type 1 internal functions */
 static int ClearStack()
 {
   Top = -1;
@@ -986,7 +1290,7 @@ unsigned char cipher;
 static int DoRead(CodeP)
   int *CodeP;
 {
-  if (strindex >= CharStringP->len) return(FALSE); /* end of string */
+  if (!CharStringP || strindex >= CharStringP->len) return(FALSE); /* end of string */
   /* We handle the non-documented Adobe convention to use lenIV=-1 to
      suppress charstring encryption. */
   if (blues->lenIV==-1) {
@@ -1394,20 +1698,25 @@ static int VStem(x, dx)
 static int RLineTo(dx, dy)
   DOUBLE dx, dy;
 {
-  struct segment *B;
- 
-  IfTrace2((FontDebug), "RLineTo %f %f\n", dx, dy);
- 
-  B = Loc(CharSpace, dx, dy);
- 
-  if (ProcessHints) {
-    currx += dx;
-    curry += dy;
-    /* B = Join(B, FindStems(currx, curry)); */
-    B = Join(B, FindStems(currx, curry, dx, dy));
-  }
- 
-  path = Join(path, Line(B));
+  long pindex = 0;
+  
+  /* compute hinting for previous segment! */
+  if (ppoints == NULL || numppoints < 2) Error0i("RLineTo: No previous point!\n");
+  FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx, dy);
+
+  /* Allocate a new path point and pre-setup data */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx + dx;
+  ppoints[pindex].y       = curry + dy;
+  ppoints[pindex].ax      = ppoints[pindex].x;
+  ppoints[pindex].ay      = ppoints[pindex].y;
+  ppoints[pindex].type    = PPOINT_LINE;
+  ppoints[pindex].hinted  = 0;
+
+  /* update ideal position */
+  currx                  += dx;
+  curry                  += dy;
+
   return(0);
 }
  
@@ -1418,31 +1727,55 @@ static int RLineTo(dx, dy)
 static int RRCurveTo(dx1, dy1, dx2, dy2, dx3, dy3)
   DOUBLE dx1, dy1, dx2, dy2, dx3, dy3;
 {
-  struct segment *B, *C, *D;
- 
-  IfTrace4((FontDebug), "RRCurveTo %f %f %f %f ", dx1, dy1, dx2, dy2);
-  IfTrace2((FontDebug), "%f %f\n", dx3, dy3);
- 
-  B = Loc(CharSpace, dx1, dy1);
-  C = Loc(CharSpace, dx2, dy2);
-  D = Loc(CharSpace, dx3, dy3);
- 
-  if (ProcessHints) {
-    /* For a Bezier curve, we apply the full hint value to
-       the Bezier C point (and thereby D point). */
-    currx += dx1 + dx2 + dx3;
-    curry += dy1 + dy2 + dy3;
-    /* C = Join(C, FindStems(currx, curry)); */
-    C = Join(C, FindStems(currx, curry, dx3, dy3));
-  }
- 
-  /* Since XIMAGER is not completely relative, */
-  /* we need to add up the delta values */
- 
-  C = Join(C, Dup(B));
-  D = Join(D, Dup(C));
- 
-  path = Join(path, Bezier(B, C, D));
+  long pindex = 0;
+  
+  /* compute hinting for previous point! */
+  if (ppoints == NULL || numppoints < 2) Error0i("RRCurveTo: No previous point!\n");
+  FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx1, dy1);
+
+  /* Allocate three new path points and pre-setup data */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx + dx1;
+  ppoints[pindex].y       = curry + dy1;
+  ppoints[pindex].ax      = ppoints[pindex].x;
+  ppoints[pindex].ay      = ppoints[pindex].y;
+  ppoints[pindex].type    = PPOINT_BEZIER_B;
+  ppoints[pindex].hinted  = 0;
+
+  /* update ideal position */
+  currx                  += dx1;
+  curry                  += dy1;
+
+  /* compute hinting for previous point! */
+  FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx2, dy2);
+
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx + dx2;
+  ppoints[pindex].y       = curry + dy2;
+  ppoints[pindex].ax      = ppoints[pindex].x;
+  ppoints[pindex].ay      = ppoints[pindex].y;
+  ppoints[pindex].type    = PPOINT_BEZIER_C;
+  ppoints[pindex].hinted  = 0;
+
+  /* update ideal position */
+  currx                  += dx2;
+  curry                  += dy2;
+
+  /* compute hinting for previous point! */
+  FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y, dx3, dy3);
+
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx + dx3;
+  ppoints[pindex].y       = curry + dy3;
+  ppoints[pindex].ax      = ppoints[pindex].x;
+  ppoints[pindex].ay      = ppoints[pindex].y;
+  ppoints[pindex].type    = PPOINT_BEZIER_D;
+  ppoints[pindex].hinted  = 0;
+
+  /* update ideal position */
+  currx                  += dx3;
+  curry                  += dy3;
+
   return(0);
 }
  
@@ -1451,12 +1784,52 @@ static int RRCurveTo(dx1, dy1, dx2, dy2,
 /* current point */
 static int DoClosePath()
 {
-  struct segment *CurrentPoint;
- 
-  IfTrace0((FontDebug), "DoClosePath\n");
-  CurrentPoint = Phantom(path);
-  path = ClosePath(path);
-  path = Join(Snap(path), CurrentPoint);
+  long pindex = 0;
+  long i = 0;
+  long tmpind;
+  double deltax = 0.0;
+  double deltay = 0.0;
+ 
+  if (ppoints == NULL || numppoints < 1) Error0i("DoClosePath: No previous point!");
+ 
+  /* If this ClosePath command together with the starting point of this
+     path completes to a segment aligned to a stem, we would miss
+     hinting for this point. --> Check and explicitly care for this! */
+  /* 1. Step back in the point list to the last moveto-point */
+  i = numppoints - 1;
+  while ( (i > 0) && (ppoints[i].type != PPOINT_MOVE ) ) { 
+    --i; 
+  }
+  
+  /* 2. Re-hint starting point and hint current point */
+  if ( ppoints[i].type == PPOINT_MOVE) {
+    deltax = ppoints[i].x - ppoints[numppoints-1].x;
+    deltay = ppoints[i].y - ppoints[numppoints-1].y;
+
+    if (ppoints == NULL || numppoints <= i + 1) Error0i("DoClosePath: No previous point!");
+    /* save nummppoints and reset to move point */
+    tmpind = numppoints;
+    numppoints = i + 1;
+    
+    /* re-hint starting point of current subpath (uses the value of numppoints!) */
+    FindStems( ppoints[i].x, ppoints[i].y, deltax, deltay,
+	       ppoints[i+1].x-ppoints[i].x, ppoints[i+1].y-ppoints[i].y);
+
+    /* restore numppoints and setup hinting for current point */
+    numppoints = tmpind;
+    FindStems( currx, curry, currx-ppoints[numppoints-2].x, curry-ppoints[numppoints-2].y,
+	       deltax, deltay);
+  }
+  
+  /* Allocate a new path point and pre-setup data */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx;
+  ppoints[pindex].y       = curry;
+  ppoints[pindex].ax      = ppoints[pindex-1].x;
+  ppoints[pindex].ay      = ppoints[pindex-1].y;
+  ppoints[pindex].type    = PPOINT_CLOSEPATH;
+  ppoints[pindex].hinted  = 0;
+
   return(0);
 }
  
@@ -1466,7 +1839,7 @@ static int DoClosePath()
 static int CallSubr(subrno)
   int subrno;
 {
-  IfTrace1((FontDebug), "CallSubr %d\n", subrno);
+  IfTrace2((FontDebug), "CallSubr %d (CallStackSize=%d)\n", subrno, CallTop);
   if ((subrno < 0) || (subrno >= SubrsP->len))
     Error0i("CallSubr: subrno out of range\n");
   PushCall(CharStringP, strindex, r);
@@ -1495,16 +1868,26 @@ static int Return()
 /* font dictionary */
 static int EndChar()
 {
+  long pindex = 0;
+  
   IfTrace0((FontDebug), "EndChar\n");
  
   /* There is no need to compute and set bounding box for
      the cache, since XIMAGER does that on the fly. */
  
-  /* Perform a Closepath just in case the command was left out */
-  path = ClosePath(path);
- 
-  /* Set character width */
-  path = Join(Snap(path), Loc(CharSpace, escapementX, escapementY));
+  /* Allocate a new path point and pre-setup data.
+     Note: For this special case, we use the variables that usually
+     store hinted coordinates for the escapement of the character.
+     It is required in handleCurrentSegment().
+  */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx;
+  ppoints[pindex].y       = curry;
+  ppoints[pindex].ax      = escapementX;
+  ppoints[pindex].ay      = escapementY;
+  ppoints[pindex].type    = PPOINT_ENDCHAR;
+  ppoints[pindex].hinted  = -1;
+
   return(0);
  
 }
@@ -1514,21 +1897,38 @@ static int EndChar()
 static int RMoveTo(dx,dy)
   DOUBLE dx,dy;
 {
-  struct segment *B;
- 
-  IfTrace2((FontDebug), "RMoveTo %f %f\n", dx, dy);
- 
-  B = Loc(CharSpace, dx, dy);
- 
-  if (ProcessHints) {
-    currx += dx;
-    curry += dy;
-    /* B = Join(B, FindStems(currx, curry)); */
-    B = Join(B, FindStems(currx, curry, 0.0, 0.0));
+  long pindex = 0;
+
+  /* Compute hinting for this path point! */
+  if ( numppoints == 1 ) {
+    /* Since RMoveTo for this case starts a new path segment
+       (flex-constructs have already been handled), the current
+       point is hinted here only taking the next point into account,
+       but not the previous. Later on, in DoClosePath(), we'll step
+       back to this point and the position might be rehinted. */
+    FindStems( currx, curry, 0, 0, dx, dy);
   }
- 
-  path = Join(path, B);
-  return(0);
+  else {
+    if (ppoints == NULL || numppoints < 2) Error0i("RMoveTo: No previous point!\n");
+    FindStems( currx, curry, ppoints[numppoints-2].x, ppoints[numppoints-2].y, dx, dy);
+  }
+  
+
+
+  /* Allocate a new path point and pre-setup data */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx + dx;
+  ppoints[pindex].y       = curry + dy;
+  ppoints[pindex].ax      = ppoints[pindex].x;
+  ppoints[pindex].ay      = ppoints[pindex].y;
+  ppoints[pindex].type    = PPOINT_MOVE;
+  ppoints[pindex].hinted  = 0;
+
+  /* update ideal position */
+  currx                  += dx;
+  curry                  += dy;
+  
+  return 0;
 }
  
 /* - DOTSECTION |- */
@@ -1548,8 +1948,12 @@ static int Seac(asb, adx, ady, bchar, ac
   unsigned char bchar, achar;
 {
   int Code;
-  struct segment *mypath;
- 
+  long pindex = 0;
+  
+  isseac      = 1;
+  seacaccent  = achar;
+  seacbase    = bchar;
+
   IfTrace4((FontDebug), "SEAC %f %f %f %d ", asb, adx, ady, bchar);
   IfTrace1((FontDebug), "%d\n", achar);
  
@@ -1558,9 +1962,9 @@ static int Seac(asb, adx, ady, bchar, ac
   /* The variables accentoffsetX/Y modify sidebearingX/Y in Sbw(). */
   /* Note that these incorporate the base character's sidebearing shift by */
   /* using the current sidebearingX, Y values. */
-  accentoffsetX = sidebearingX + adx - asb;
-  accentoffsetY = sidebearingY + ady;
- 
+  accentoffsetX = adx - asb;
+  accentoffsetY = ady;
+
   /* Set path = NULL to avoid complaints from Sbw(). */
   path = NULL;
  
@@ -1580,10 +1984,18 @@ static int Seac(asb, adx, ady, bchar, ac
     Decode(Code);
     if (errflag) return(0);
   }
-  /* Copy snapped path to mypath and set path to NULL as above. */
-  mypath = Snap(path);
-  path = NULL;
- 
+
+  /* Allocate a new path point. Data in this case is not relevant
+     in handleSegment(), we merely insert a snap() in order to return
+     to origin of the accent char. */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = accentoffsetX;
+  ppoints[pindex].y       = accentoffsetY;
+  ppoints[pindex].ax      = accentoffsetX;
+  ppoints[pindex].ay      = accentoffsetY;
+  ppoints[pindex].type    = PPOINT_SEAC;
+  ppoints[pindex].hinted  = 0;
+
   /* We must reset these to null now. */
   accentoffsetX = accentoffsetY = 0;
  
@@ -1595,7 +2007,6 @@ static int Seac(asb, adx, ady, bchar, ac
   ClearPSFakeStack();
   ClearCallStack();
  
-  FinitStems();
   InitStems();
  
   for (;;) {
@@ -1603,7 +2014,7 @@ static int Seac(asb, adx, ady, bchar, ac
     Decode(Code);
     if (errflag) return(0);
   }
-  path = Join(mypath, path);
+
   return(0);
 }
  
@@ -1614,6 +2025,9 @@ static int Seac(asb, adx, ady, bchar, ac
 static int Sbw(sbx, sby, wx, wy)
   DOUBLE sbx, sby, wx, wy;
 {
+  long pindex = 0;
+  
+  
   IfTrace4((FontDebug), "SBW %f %f %f %f\n", sbx, sby, wx, wy);
  
   escapementX = wx; /* Character width vector */
@@ -1623,8 +2037,29 @@ static int Sbw(sbx, sby, wx, wy)
   sidebearingX = sbx + accentoffsetX;
   sidebearingY = sby + accentoffsetY;
  
+  currx = sidebearingX;
+  curry = sidebearingY;
+  /*
   path = Join(path, Loc(CharSpace, sidebearingX, sidebearingY));
-  if (ProcessHints) {currx = sidebearingX; curry = sidebearingY;}
+  if (ProcessHints) {
+    hcurrx = sidebearingX;
+    hcurry = sidebearingY;
+  }
+  */
+  
+  /* Allocate a path point and setup.
+     Note: In this special case, we store the char escapement in the members
+           ax and ay. They are required in handleCurrentSegment(). Hinting
+	   is not required for SBW, anyhow!
+  */
+  pindex = nextPPoint();
+  ppoints[pindex].x       = currx;
+  ppoints[pindex].y       = curry;
+  ppoints[pindex].ax      = wx;
+  ppoints[pindex].ay      = wy;
+  ppoints[pindex].type    = PPOINT_SBW;
+  ppoints[pindex].hinted  = -1; /* indicate that point is not to be hinted */
+ 
   return(0);
 }
  
@@ -1675,24 +2110,6 @@ static DOUBLE Div(num1, num2)
  
 #define PaintType (0)
  
-#define lineto(x,y) { \
-  struct segment *CurrentPoint; \
-  DOUBLE CurrentX, CurrentY; \
-  CurrentPoint = Phantom(path); \
-  QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \
-  Destroy(CurrentPoint); \
-  RLineTo(x - CurrentX, y - CurrentY); \
-}
- 
-#define curveto(x0,y0,x1,y1,x2,y2) { \
-  struct segment *CurrentPoint; \
-  DOUBLE CurrentX, CurrentY; \
-  CurrentPoint = Phantom(path); \
-  QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \
-  Destroy(CurrentPoint); \
-  RRCurveTo(x0 - CurrentX, y0 - CurrentY, x1 - x0, y1 - y0, x2 - x1, y2 - y1); \
-}
- 
 #define xshrink(x) ((x - c4x2) * shrink +c4x2)
 #define yshrink(y) ((y - c4y2) * shrink +c4y2)
  
@@ -1741,9 +2158,16 @@ static void FlxProc(c1x2, c1y2, c3x0, c3
   DOUBLE eShift;
   DOUBLE cx, cy;
   DOUBLE ex, ey;
- 
-  Destroy(path);
-  path = FlxOldPath; /* Restore previous path (stored in FlxProc1) */
+
+  if (ppoints == NULL || numppoints < 8) Error0v("FlxProc: No previous point!");
+
+  /* Our PPOINT list now contains 7 moveto commands which
+     are about to be consumed by the Flex mechanism. --> Remove these
+     seven elements (their values already reside on the PSFakeStack!)
+     and approriately restore the current accumulated position. */
+  numppoints -= 7;
+  currx = ppoints[numppoints-1].x;
+  curry = ppoints[numppoints-1].y;
  
   if (ProcessHints) {
     dmin = TYPE1_ABS(idmin) / 100.0; /* Minimum Flex height in pixels */
@@ -1865,15 +2289,25 @@ static void FlxProc(c1x2, c1y2, c3x0, c3
     }
  
     if (x2 == x5 || y2 == y5) {
-      lineto(x5, y5);
+      RLineTo( x5 - currx, y5 - curry); \
     } else {
-      curveto(x0, y0, x1, y1, x2, y2);
-      curveto(x3, y3, x4, y4, x5, y5);
+      RRCurveTo( x0 - currx, y0 - curry,
+		 x1 - x0, y1 - y0,
+		 x2 - x1,
+		 y2 - y1); 
+      RRCurveTo( x3 - currx, y3 - curry,
+		 x4 - x3, y4 - y3,
+		 x5 - x4, y5 - y4); 
     }
   } else { /* ProcessHints is off */
     PickCoords(FALSE); /* Pick original control points */
-    curveto(x0, y0, x1, y1, x2, y2);
-    curveto(x3, y3, x4, y4, x5, y5);
+    RRCurveTo( x0 - currx, y0 - curry,
+	       x1 - x0, y1 - y0,
+	       x2 - x1,
+	       y2 - y1); 
+    RRCurveTo( x3 - currx, y3 - curry,
+	       x4 - x3, y4 - y3,
+	       x5 - x4, y5 - y4); 
   }
  
   PSFakePush(epY);
@@ -1885,12 +2319,9 @@ static void FlxProc(c1x2, c1y2, c3x0, c3
 /*   Saves and clears path, then restores currentpoint */
 static void FlxProc1()
 {
-  struct segment *CurrentPoint;
- 
-  CurrentPoint = Phantom(path);
- 
-  FlxOldPath = path;
-  path = CurrentPoint;
+  /* Since we are now building the path point list,
+     there's nothing to do here! */
+  return;
 }
  
 /* FlxProc2() = OtherSubrs[2]; Part of Flex */
@@ -1898,16 +2329,10 @@ static void FlxProc1()
 /*   Returns currentpoint on stack          */
 static void FlxProc2()
 {
-  struct segment *CurrentPoint;
-  DOUBLE CurrentX, CurrentY;
- 
-  CurrentPoint = Phantom(path);
-  QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY);
-  Destroy(CurrentPoint);
- 
+  if (ppoints == NULL || numppoints < 1) Error0v("FlxProc2: No previous point!");
   /* Push CurrentPoint on fake PostScript stack */
-  PSFakePush(CurrentX);
-  PSFakePush(CurrentY);
+  PSFakePush( ppoints[numppoints-1].x);
+  PSFakePush( ppoints[numppoints-1].y);
 }
  
 /* HintReplace() = OtherSubrs[3]; Hint Replacement            */
@@ -1988,12 +2413,43 @@ struct xobject *Type1Char(psfont *env, s
 			  psobj *charstrP, psobj *subrsP,
 			  psobj *osubrsP,
 			  struct blues_struct *bluesP,
-			  int *modeP, char *charname)
+			  int *modeP, char *charname,
+			  float strokewidth,
+			  int decodeonly)
 {
   int Code;
- 
-  path = NULL;
+  long i = 0;
+  
+  double xp, yp;
+#ifdef DUMPDEBUGPATH
+  char fnbuf[128];
+#endif
+  struct segment* p;
+
+  /* Reset SEAC querying variables */
+  isseac     = 0;
+  seacbase   = 0;
+  seacaccent = 0;
+  
+  /* Reset point list */
+  ppoints          = NULL;
+  numppoints       = 0;
+  numppointchunks  = 0;
+
+  /* disable hinting for stroking */
+  if ( strokewidth != 0.0f )
+    ProcessHints = 0;
+  
+  if ( env->fontInfoP[PAINTTYPE].value.data.integer == 1 )
+    ProcessHints = 0;
+
+  path    = NULL;
+  apath   = NULL;
   errflag = FALSE;
+
+  if ( S == NULL ) {
+    S=(struct XYspace *) IDENTITY;
+  }
  
   /* Make parameters available to all Type1 routines */
   currentchar=charname;
@@ -2005,7 +2461,24 @@ struct xobject *Type1Char(psfont *env, s
   ModeP = modeP;
  
   blues = bluesP;
- 
+
+  if ( decodeonly == 0 ) {
+    QuerySpace( S, &scxx, &scyx, &scxy, &scyy); /* Transformation matrix */
+    p = ILoc( S, 1, 0);
+    QueryLoc(p, IDENTITY, &xp, &yp);
+    up = FABS(xp);
+    
+    size = scxx * 1000.0;
+#ifdef DUMPDEBUGPATH
+    sprintf( fnbuf, "t1dump_%s_%f.eps", charname, size); 
+    psfile = fopen( fnbuf, "wb");
+    if ( psfile != NULL ) {
+      PSDumpProlog( psfile);
+      fprintf( psfile, "T1LibDict begin\n\ngsave\n%f t1SetupSize\nt1PreparePage\n", size);
+    }
+#endif
+  }
+
   /* compute the alignment zones */
   SetRasterFlags();
   ComputeAlignmentZones();
@@ -2014,21 +2487,76 @@ struct xobject *Type1Char(psfont *env, s
   ClearPSFakeStack();
   ClearCallStack();
   InitStems();
- 
-  currx = curry = 0;
+
+  /* reset variables */
+  currx = curry = 0.0;
+  hcurrx = hcurry = 0.0;
   escapementX = escapementY = 0;
   sidebearingX = sidebearingY = 0;
   accentoffsetX = accentoffsetY = 0;
   wsoffsetX = wsoffsetY = 0;           /* No shift to preserve whitspace. */
   wsset = 0;                           /* wsoffsetX,Y haven't been set yet. */
- 
+
   for (;;) {
     if (!DoRead(&Code)) break;
     Decode(Code);
     if (errflag) break;
   }
-  FinitStems();
 
+  if ( decodeonly != 0 ) {
+    /* OK, character description is now on stack, finish ... */
+    return NULL;
+  }
+
+  /* We now have a point list in absolute charspace coordinates. Adjust
+     non-hinted points to suppress hinting artifacts and generate path. */
+  for ( i=0; i<numppoints; i++ ) {
+    if ( ppoints[i].type == PPOINT_BEZIER_D)
+      adjustBezier( i);
+  }
+  /* Create path elements */
+#if defined(DUMPDEBUGPATH) & defined(DUMPDEBUGPATHBOTH)
+  if ( env->fontInfoP[PAINTTYPE].value.data.integer == 0 ) {
+    /* For this special debug case, we generate both a filled and a stroked
+       path!. */
+      createStrokePath( strokewidth, SUBPATH_CLOSED);
+      createFillPath();
+  }
+  else if ( env->fontInfoP[PAINTTYPE].value.data.integer == 1 ) {
+    /* PaintType = 1 indicates stroked font. If strokewidth is 0.0f,
+       we stroke using the font's internal strokewidth. Otherwise, the
+       user supplied value is used. */
+    if ( strokewidth != 0.0f )
+      createStrokePath( strokewidth, SUBPATH_OPEN);
+    else
+      createStrokePath( env->fontInfoP[STROKEWIDTH].value.data.real, SUBPATH_OPEN);
+  }
+#else
+  if ( env->fontInfoP[PAINTTYPE].value.data.integer == 0 ) {
+    /* PaintType = 0 indicates filled font. Hence, a strokewidth value
+       other than 0.0 indicates the character is to be stroked instead
+       of to be filled. */
+    if ( strokewidth != 0.0f )
+      createStrokePath( strokewidth, SUBPATH_CLOSED);
+    else
+      createFillPath();
+  }
+  else if ( env->fontInfoP[PAINTTYPE].value.data.integer == 1 ) {
+    /* PaintType = 1 indicates stroked font. If strokewidth is 0.0f,
+       we stroke using the font's internal strokewidth. Otherwise, the
+       user supplied value is used. */
+    if ( strokewidth != 0.0f )
+      createStrokePath( strokewidth, SUBPATH_OPEN);
+    else
+      createStrokePath( env->fontInfoP[STROKEWIDTH].value.data.real, SUBPATH_OPEN);
+  }
+#endif
+  
+  /* check and handle accented char */
+  if ( apath != NULL ) {
+    path = Join( apath, path);
+  }
+  
   /* Report a possible error: */
   *modeP=errflag;
   
@@ -2040,6 +2568,21 @@ struct xobject *Type1Char(psfont *env, s
     }
   }
  
+#ifdef DUMPDEBUGPATH
+  if ( psfile != NULL ) {
+    PSDumpEpilog( psfile);
+    fclose( psfile);
+    psfile = 0;
+  }
+#endif
+
+  /* Cleanup ppoints */
+  if ( ppoints != NULL ) {
+    free( ppoints);
+    ppoints = NULL;
+    numppoints = 0;
+  }
+  
   return((struct xobject *) path);
 }
  
@@ -2048,11 +2591,19 @@ struct xobject *Type1Char(psfont *env, s
 struct xobject *Type1Line(psfont *env, struct XYspace *S,
 			  float line_position,
 			  float line_thickness,
-			  float line_length)
+			  float line_length,
+			  float strokewidth)
 {
+
+  /* Reset point list */
+  ppoints          = NULL;
+  numppoints       = 0;
+  numppointchunks  = 0;
   
-  path = NULL;
+  path    = NULL;
+  apath   = NULL;
   errflag = FALSE;
+
   
   /* Make parameters available to all Type1 routines */
   Environment = (char *)env;
@@ -2075,11 +2626,2060 @@ struct xobject *Type1Line(psfont *env, s
   DoClosePath();  
   EndChar();
 
-  /* De-Initialize the stems (of course there have not been
-     defined any) */
-  FinitStems();
+  /* Create path */
+  if ( strokewidth != 0.0f )
+    createStrokePath( strokewidth, SUBPATH_CLOSED);
+  else
+    createFillPath();
   
+  /* Cleanup ppoints */
+  if ( ppoints != NULL ) {
+    free( ppoints);
+    ppoints = NULL;
+  }
+
   return((struct xobject *)path);
   
 }
 
+
+/* Adjust the points of a given cubic Bezier Spline so that the
+   geometric relation of points B and C to A and D remain
+   qualitatively the same. This reduces hinting artifacts
+   at low resolutions.
+*/
+static void adjustBezier( long pindex)
+{
+  double deltax  = 0.0;      /* x distance between point A and D */
+  double deltay  = 0.0;      /* y distance between point A and D */
+  double adeltax = 0.0;      /* x distance between hinted point A and D */
+  double adeltay = 0.0;      /* y distance between hinted point A and D */
+
+  deltax  = ppoints[pindex].x - ppoints[pindex-3].x;
+  deltay  = ppoints[pindex].y - ppoints[pindex-3].y;
+  adeltax = ppoints[pindex].ax - ppoints[pindex-3].ax;
+  adeltay = ppoints[pindex].ay - ppoints[pindex-3].ay;
+
+  if ( deltax == 0 || deltay == 0 )
+    return;
+  
+  ppoints[pindex-1].ax = ppoints[pindex-3].ax +
+    (adeltax / deltax * (ppoints[pindex-1].x - ppoints[pindex-3].x));
+  ppoints[pindex-1].ay = ppoints[pindex-3].ay +
+    (adeltay / deltay * (ppoints[pindex-1].y - ppoints[pindex-3].y));
+  ppoints[pindex-2].ax = ppoints[pindex-3].ax +
+    (adeltax / deltax * (ppoints[pindex-2].x - ppoints[pindex-3].x));
+  ppoints[pindex-2].ay = ppoints[pindex-3].ay +
+    (adeltay / deltay * (ppoints[pindex-2].y - ppoints[pindex-3].y));
+
+  return;
+  
+}
+
+
+
+/* This function actually generates path segments. It is called
+   after all hinting and adjustments have been performed.
+*/
+static void handleCurrentSegment( long pindex)
+{
+  struct segment* B;
+  struct segment* C;
+  struct segment* D;
+  struct segment* tmpseg;
+  double dx1;
+  double dy1;
+  double dx2;
+  double dy2;
+  double dx3;
+  double dy3;
+  double adx1;
+  double ady1;
+  double adx2;
+  double ady2;
+  double adx3;
+  double ady3;
+  
+
+  /* handle the different segment types in a switch-statement */
+  switch ( ppoints[pindex].type ) {
+
+  case PPOINT_MOVE:
+    /* handle a move segment */
+    dx1  = ppoints[pindex].x - ppoints[pindex-1].x;
+    dy1  = ppoints[pindex].y - ppoints[pindex-1].y;
+    adx1 = ppoints[pindex].ax - ppoints[pindex-1].ax;
+    ady1 = ppoints[pindex].ay - ppoints[pindex-1].ay;
+    
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1rmoveto %% pindex = %ld\n", dx1*up, dy1*up, pindex);
+#endif
+    if ( ProcessHints ) {
+      IfTrace2((FontDebug), "RMoveTo(h) %f %f\n", adx1, ady1);
+      B = Loc(CharSpace, adx1, ady1);
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL ) {
+	fprintf( psfile, "%f %f t1hintedrmoveto %% pindex = %ld\n", adx1*up, ady1*up, pindex);
+      }
+#endif
+    }
+    else {
+      IfTrace2((FontDebug), "RMoveTo %f %f\n", dx1, dy1);
+      B = Loc(CharSpace, dx1, dy1);
+    }
+    path = Join(path, B);
+    break;
+
+
+  case PPOINT_LINE:
+    /* handle a line segment */
+    dx1  = ppoints[pindex].x - ppoints[pindex-1].x;
+    dy1  = ppoints[pindex].y - ppoints[pindex-1].y;
+    adx1 = ppoints[pindex].ax - ppoints[pindex-1].ax;
+    ady1 = ppoints[pindex].ay - ppoints[pindex-1].ay;
+    
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1rlineto %% pindex = %ld\n", dx1*up, dy1*up, pindex);
+#endif
+    if ( ProcessHints ) {
+      IfTrace2((FontDebug), "RLineTo(h) %f %f\n", adx1, ady1);
+      B = Loc(CharSpace, adx1, ady1);
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL ) {
+	fprintf( psfile, "%f %f t1hintedrlineto %% pindex = %ld\n", adx1*up, ady1*up, pindex);
+      }
+#endif
+    }
+    else {
+      IfTrace2((FontDebug), "RLineTo %f %f\n", dx1, dy1);
+      B = Loc(CharSpace, dx1, dy1);
+    }
+    path = Join(path, Line(B));
+    break;
+
+
+  case PPOINT_BEZIER_B:
+    /* handle a bezier segment (given by this and the following points) */
+    dx1  = ppoints[pindex].x - ppoints[pindex-1].x;
+    dy1  = ppoints[pindex].y - ppoints[pindex-1].y;
+    adx1 = ppoints[pindex].ax - ppoints[pindex-1].ax;
+    ady1 = ppoints[pindex].ay - ppoints[pindex-1].ay;
+    dx2  = ppoints[pindex+1].x - ppoints[pindex].x;
+    dy2  = ppoints[pindex+1].y - ppoints[pindex].y;
+    adx2 = ppoints[pindex+1].ax - ppoints[pindex].ax;
+    ady2 = ppoints[pindex+1].ay - ppoints[pindex].ay;
+    dx3  = ppoints[pindex+2].x - ppoints[pindex+1].x;
+    dy3  = ppoints[pindex+2].y - ppoints[pindex+1].y;
+    adx3 = ppoints[pindex+2].ax - ppoints[pindex+1].ax;
+    ady3 = ppoints[pindex+2].ay - ppoints[pindex+1].ay;
+
+
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f %f %f %f %f t1rrcurveto %% pindex = %ld\n",
+	       dx1*up, dy1*up,
+	       dx2*up, dy2*up,
+	       dx3*up, dy3*up,
+	       pindex);
+#endif
+    if (ProcessHints) {
+      IfTrace4((FontDebug), "RRCurveTo %f %f %f %f ",
+	       adx1, ady1, adx2, ady2);
+      IfTrace2((FontDebug), "%f %f\n", adx3, ady3);
+      B = Loc(CharSpace, adx1, ady1);
+      C = Loc(CharSpace, adx2, ady2);
+      D = Loc(CharSpace, adx3, ady3);
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL ) {
+	fprintf( psfile, "%f %f %f %f %f %f t1hintedrrcurveto %% pindex = %ld\n",
+		 adx1*up, ady1*up,
+		 adx2*up, ady2*up,
+		 adx3*up, ady3*up,
+		 pindex);
+      }
+#endif
+    }
+    else {
+      IfTrace4((FontDebug), "RRCurveTo %f %f %f %f ",
+	       dx1, dy1, dx2, dy2);
+      IfTrace2((FontDebug), "%f %f\n", dx3, dy3);
+      B = Loc(CharSpace, dx1, dy1);
+      C = Loc(CharSpace, dx2, dy2);
+      D = Loc(CharSpace, dx3, dy3);
+    }
+    
+    /* Since XIMAGER is not completely relative, */
+    /* we need to add up the delta values */
+    C = Join(C, (struct segment *)Dup(B));
+    D = Join(D, (struct segment *)Dup(C));
+    path = Join(path, (struct segment *)Bezier(B, C, D));
+    break;
+
+
+  case PPOINT_SBW:
+#ifdef DUMPDEBUGPATH
+  if ( psfile != NULL )
+    fprintf( psfile, "%f %f %f %f t1sbw %% pindex = %ld\n",
+	     ppoints[pindex].x*up, ppoints[pindex].y*up,   /* sidebearings */
+	     ppoints[pindex].ax*up, ppoints[pindex].ay*up,  /* escapements  */
+	     pindex
+	     );
+#endif
+    path = Join(path, Loc(CharSpace, ppoints[pindex].x, ppoints[pindex].y));
+    break;
+    
+    
+  case PPOINT_CLOSEPATH:
+    IfTrace0((FontDebug), "DoClosePath\n");
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL ) {
+      fprintf( psfile, "t1closepath %% pindex = %ld\n", pindex);
+      if ( ProcessHints )
+	fprintf( psfile, "t1hintedclosepath %% pindex = %ld\n", pindex);
+    }
+#endif
+    
+    tmpseg = Phantom(path);
+    path = ClosePath(path);
+    path = Join(Snap(path), tmpseg);
+    break;
+    
+    
+  case PPOINT_ENDCHAR:
+    /* Perform a Closepath just in case the command was left out */
+    path = ClosePath(path);
+    
+    /* Set character width / escapement. It is stored in the vars for
+       hinted coordinates. */
+    path = Join(Snap(path), Loc(CharSpace, ppoints[pindex].ax, ppoints[pindex].ay));
+    
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "t1FinishPage\ngrestore %% pindex = %ld\n", pindex);
+#endif
+    break;
+    
+
+  case PPOINT_SEAC:
+    /* return to origin of accent */
+    apath = Snap(path);
+    /* reset path to NULL */
+    path  = NULL;
+    break;
+    
+    
+  default:
+    /* We must be at the beginning of the path, that is, there is
+       nothing to do! */
+    ;
+  }
+
+  return;
+  
+}
+
+
+#ifdef DUMPDEBUGPATH
+static void PSDumpProlog( FILE* fp)
+{
+#include "t1chardump"
+}
+
+
+static void PSDumpEpilog( FILE* fp)
+{
+  fputs( "\nend\n", fp);
+}
+
+#endif /* #ifdef DUMPDEBUGPATH */
+
+
+
+/* Take the accumulated path point list and construct the path that is
+   to be filled. */
+static void createFillPath( void)
+{
+  long i;
+  
+  for ( i=0; i<numppoints; i++ ) {
+    handleCurrentSegment( i);
+  }
+  return;
+}
+
+
+/* Take the accumulated path point list and construct a path so that the
+   character appears as a stroked outline, where the virtual pen has a diameter
+   of strokewidth (measured in big points [bp]). This function works analogously
+   to PostScripts charpath operator. */
+static void createStrokePath( double strokewidth, int subpathclosed)
+{
+  long pindex   = 0;
+  long startind = 0;
+  long stopind  = 0;
+
+
+  /* For each subpath in the path list (some sub path is closed!), we construct 
+     one path interior and one path exterior to the path under consideration in
+     a way, that the resulting thick curve has a thickness of strokewidth. */
+
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "\ncreateStrokePath(strokewidth=%f, subpathclosed=%d): Searching partial paths ...\n\n",
+	   strokewidth, subpathclosed);
+#endif
+  if ( subpathclosed == 0 ) {
+    /* We have a stroked font */
+    /* loop through all subpaths */
+    while ( pindex < numppoints ) {
+      /* First, handle any non-subpath commands. */
+      if ( handleNonSubPathSegments( pindex) != 0 ) {
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "PPoint %ld: (%f,%f), Type=%s\n", pindex,
+		 ppoints[pindex].x, ppoints[pindex].y, pptypes[ppoints[pindex].type]);
+#endif
+	++pindex;
+	continue;
+      }
+      
+      if ( ppoints[pindex].type == PPOINT_LINE ||
+	   ppoints[pindex].type == PPOINT_BEZIER_B ) {
+	if ( ppoints[pindex-1].type == PPOINT_MOVE ) {
+	  /* A line or curve segment following a move segment indicates a
+	     new subpath. */
+	  startind = pindex - 1;
+	  while ( (pindex < numppoints) &&
+		  (ppoints[pindex].type != PPOINT_CLOSEPATH) &&
+		  (ppoints[pindex].type != PPOINT_MOVE) && 
+		  (ppoints[pindex].type != PPOINT_ENDCHAR) 
+		  ) {
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	    fprintf( stderr, "PPoint %ld: (%f,%f), Type=%s\n", pindex,
+		   ppoints[pindex].x, ppoints[pindex].y, pptypes[ppoints[pindex].type]);
+#endif
+	    ++pindex;
+	  }
+	  if ( (ppoints[pindex].type == PPOINT_ENDCHAR) ||  /* for outline fonts */
+	       (ppoints[pindex].type == PPOINT_MOVE)          /* for stroked fonts */
+	       ) {
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	    fprintf( stderr, "PPoint %ld: (%f,%f), Type=%s\n", pindex,
+		   ppoints[pindex].x, ppoints[pindex].y, pptypes[ppoints[pindex].type]);
+#endif
+	    stopind = --pindex;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	    fprintf( stderr, "Found subpath from index %ld to %ld inclusively\n", startind, stopind);
+#endif
+	    /* We have found a subpath defined by the path points indexed by
+	       the interval from startind to stopind. */
+	    createClosedStrokeSubPath( startind, stopind, strokewidth, subpathclosed);
+	  }
+	}
+      }
+      ++pindex;
+    }
+  }
+  else {
+    /* We have a filled font */
+    /* loop through all subpaths */
+    while ( pindex < numppoints ) {
+      /* First, handle any non-subpath commands. */
+      if ( handleNonSubPathSegments( pindex) != 0 ) {
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "PPoint %ld: (%f,%f), Type=%s\n", pindex,
+	       ppoints[pindex].x, ppoints[pindex].y, pptypes[ppoints[pindex].type]);
+#endif
+	++pindex;
+	continue;
+      }
+      
+      if ( ppoints[pindex].type == PPOINT_LINE ||
+	   ppoints[pindex].type == PPOINT_BEZIER_B ) {
+	if ( ppoints[pindex-1].type == PPOINT_MOVE ) {
+	  /* A line or curve segment following a move segment indicates a
+	     new subpath. */
+	  startind = --pindex;
+	  while ( (pindex < numppoints) &&
+		  (ppoints[pindex].type != PPOINT_CLOSEPATH) 
+		  ) {
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	    fprintf( stderr, "PPoint %ld: (%f,%f), Type=%s\n", pindex,
+		   ppoints[pindex].x, ppoints[pindex].y, pptypes[ppoints[pindex].type]);
+#endif
+	    ++pindex;
+	  }
+	  if ( ppoints[pindex].type == PPOINT_CLOSEPATH ) {
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	    fprintf( stderr, "PPoint %ld: (%f,%f), Type=%s\n", pindex,
+		   ppoints[pindex].x, ppoints[pindex].y, pptypes[ppoints[pindex].type]);
+#endif
+	    stopind = pindex;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	    fprintf( stderr, "Found subpath from index %ld to %ld inclusively\n", startind, stopind);
+#endif
+	    /* We have found a subpath defined by the path points indexed by
+	       the interval from startind to stopind. */
+	    createClosedStrokeSubPath( startind, stopind, strokewidth, subpathclosed);
+	  }
+	}
+      }
+      ++pindex;
+    }
+  }
+  
+  return;
+  
+}
+
+
+
+/* Create two closed paths that surround the the current subpath of the
+   charpath in a centered fashion. */
+static void createClosedStrokeSubPath( long startind, long stopind,
+				       double strokewidth, int subpathclosed)
+{
+  long i;
+  long inext;
+  long iprev;
+  long ip = 0;
+  long in = 0;
+  long segstartind;
+  long segendind;
+  
+  long lastind     = 0; /* Index of last point whose location is different from first
+			   point. After this point there may follow an explicit line-
+			   or curveto to the starting point and also the ClosePath-point
+			   may be and usually is identical to the starting point. */
+
+  double dx1;
+  double dy1;
+  double dx2;
+  double dy2;
+  double dx3;
+  double dy3;
+  
+  struct segment* B;
+  struct segment* C;
+  struct segment* D;
+  struct segment* tmpseg;
+
+  int type;
+  
+
+  /* The ClosePath operator is somewhat problematic, because it adds a point
+     to the defining points of a path, without actually having a distance to
+     the previous or the next point. This causes problems with the distance
+     handling. As a remedy, we check whether ClosePath is located at the first
+     point or the last point of the path. In the latter case, ClosePath causes
+     an additional line segment. */
+  if ( (ppoints[stopind].x == ppoints[startind].x) &&
+       (ppoints[stopind].y == ppoints[startind].y)
+       ) {
+    closepathatfirst = 1;
+  }
+  else {
+    closepathatfirst = 0;
+  }
+  
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  if ( closepathatfirst == 1 ) {
+    fprintf( stderr, "createClosedStrokeSubPath(): Starting up, ClosePath is at first PPoint (does not cause a line segment) ...\n");
+  }
+  else {
+    fprintf( stderr, "createClosedStrokeSubPath(): Starting up, ClosePath is not at first PPoint (causes a closing line segment) ...\n");
+  }
+#endif
+
+  
+  /* For each path point in the list, we have to define a set of points, to the
+     left and to the right of the current curve. The positions of these
+     new points depend on the coordinates of the previous path point, the current
+     path and the next path point. */
+
+  /* For the computations, the distance from the start and end points of curves
+     and lines to the neighbouring points is required. We start by calculating
+     these and by filling in the path point entries dist2prev and dist2next for
+     the respective points. */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "Computing geometric distances between path points ...\n");
+#endif
+  lastind = computeDistances( startind, stopind, subpathclosed);
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "startind=%ld, lastind=%ld, stopind=%ld\n", startind, lastind, stopind);
+#endif
+
+
+  /********************************************************************************
+   ********************************************************************************
+   ***** 
+   ***** Path point transformation
+   ***** 
+   ********************************************************************************
+   ********************************************************************************/
+
+  /* Next we step through the path points of the current subpath and compute the 
+     points' transformations. From these newly computed points,
+     the path is constructed. */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "Computing geometric transformation points and resulting intersection points for right path ...\n\n");
+#endif
+  for ( i=startind; i<=lastind; ) {
+    /* Be aware of cycling! */
+    if ( i == startind ) {
+      iprev = lastind;
+      inext = i + 1;
+    }
+    else if ( i == lastind ) {
+      iprev = i - 1;
+      inext = startind;
+    }
+    else {
+      iprev = i - 1;
+      inext = i + 1;
+    }
+    
+    
+    switch ( ppoints[i].type ) {
+    case PPOINT_MOVE:
+      /* The first segment always is of type PPOINT_MOVE. It is defined by the first,
+	 the second and the last point. */
+      transformOnCurvePathPoint( strokewidth, iprev, i, inext);
+
+      /* Compute one point which results from prolongating the linked segment and
+	 and computing the intersection. The result values are stored in dxres,
+	 dyres. */
+      if ( subpathclosed == 0 ) {
+	/* open subpath --> stroked font */
+	if ( i == startind ) {
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_NEXT);
+	}
+	else if ( i == lastind ) {
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_PREVIOUS);
+	}
+	else {
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_BOTH);
+	}
+      }
+      else {
+	intersectRight( i, 0.5*strokewidth, INTERSECT_BOTH);
+      }
+
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "\nCurrent PathPoint: PP %ld (%s): (%f,%f), shape=%s;\n", i, pptypes[ppoints[i].type], 
+	       ppoints[i].x, ppoints[i].y, ppshapes[ppoints[i].shape]);
+      fprintf( stderr, "    RightPath: prev (%f,%f); next (%f,%f); res (%f,%f)\n",
+	       ppoints[i].x+ppoints[i].dxpr, ppoints[i].y+ppoints[i].dypr,
+	       ppoints[i].x+ppoints[i].dxnr, ppoints[i].y+ppoints[i].dynr,
+	       ppoints[i].x+ppoints[i].dxir, ppoints[i].y+ppoints[i].dyir);
+      fprintf( stderr, "    LeftPath:  prev (%f,%f); next (%f,%f); res (%f,%f)\n\n",
+	       ppoints[i].x-ppoints[i].dxpr, ppoints[i].y-ppoints[i].dypr,
+	       ppoints[i].x-ppoints[i].dxnr, ppoints[i].y-ppoints[i].dynr,
+	       ppoints[i].x-ppoints[i].dxir, ppoints[i].y-ppoints[i].dyir);
+#endif
+      
+      break;
+
+      
+    case PPOINT_LINE:
+      transformOnCurvePathPoint( strokewidth, iprev, i, inext);
+      if ( subpathclosed == 0 ) {
+	/* open subpath --> stroked font */
+	if ( i == startind )
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_NEXT);
+	else if ( i == lastind )
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_PREVIOUS);
+	else
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_BOTH);
+      }
+      else {
+	intersectRight( i, 0.5*strokewidth, INTERSECT_BOTH);
+      }
+      
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "\nCurrent PathPoint: PP %ld (%s): (%f,%f), shape=%s;\n", i, pptypes[ppoints[i].type], 
+	       ppoints[i].x, ppoints[i].y, ppshapes[ppoints[i].shape]);
+      fprintf( stderr, "    RightPath: prev (%f,%f); next (%f,%f); res (%f,%f)\n",
+	       ppoints[i].x+ppoints[i].dxpr, ppoints[i].y+ppoints[i].dypr,
+	       ppoints[i].x+ppoints[i].dxnr, ppoints[i].y+ppoints[i].dynr,
+	       ppoints[i].x+ppoints[i].dxir, ppoints[i].y+ppoints[i].dyir);
+      fprintf( stderr, "    LeftPath:  prev (%f,%f); next (%f,%f); res (%f,%f)\n\n",
+	       ppoints[i].x-ppoints[i].dxpr, ppoints[i].y-ppoints[i].dypr,
+	       ppoints[i].x-ppoints[i].dxnr, ppoints[i].y-ppoints[i].dynr,
+	       ppoints[i].x-ppoints[i].dxir, ppoints[i].y-ppoints[i].dyir);
+#endif
+
+      break;
+
+      
+    case PPOINT_BEZIER_B:
+      break;
+
+    case PPOINT_BEZIER_C:
+      break;
+
+    case PPOINT_BEZIER_D:
+      transformOnCurvePathPoint( strokewidth, iprev, i, inext);
+      if ( subpathclosed == 0 ) {
+	/* open subpath --> stroked font */
+	if ( i == startind )
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_NEXT);
+	else if ( i == lastind )
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_PREVIOUS);
+	else
+	  intersectRight( i, 0.5*strokewidth, INTERSECT_BOTH);
+      }
+      else {
+	intersectRight( i, 0.5*strokewidth, INTERSECT_BOTH);
+      }
+      
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "\nCurrent PathPoint: PP %ld (%s): (%f,%f), shape=%s;\n", i, pptypes[ppoints[i].type], 
+	       ppoints[i].x, ppoints[i].y, ppshapes[ppoints[i].shape]);
+      fprintf( stderr, "    RightPath: prev (%f,%f); next (%f,%f); res (%f,%f)\n",
+	       ppoints[i].x+ppoints[i].dxpr, ppoints[i].y+ppoints[i].dypr,
+	       ppoints[i].x+ppoints[i].dxnr, ppoints[i].y+ppoints[i].dynr,
+	       ppoints[i].x+ppoints[i].dxir, ppoints[i].y+ppoints[i].dyir);
+      fprintf( stderr, "    LeftPath:  prev (%f,%f); next (%f,%f); res (%f,%f)\n\n",
+	       ppoints[i].x-ppoints[i].dxpr, ppoints[i].y-ppoints[i].dypr,
+	       ppoints[i].x-ppoints[i].dxnr, ppoints[i].y-ppoints[i].dynr,
+	       ppoints[i].x-ppoints[i].dxir, ppoints[i].y-ppoints[i].dyir);
+#endif
+      
+      /* transform the preceding two offCurve points */
+      transformOffCurvePathPoint( strokewidth, i-2);
+
+      break;
+      
+    case PPOINT_CLOSEPATH:
+
+      break;
+      
+    default:
+      break;
+    }
+    ++i;
+  }
+
+  /* copy the shift values from starting point to ending points that
+     have not yet been handled */
+  for ( ; i<=stopind; i++) {
+    ppoints[i].dxpr      = ppoints[startind].dxpr;
+    ppoints[i].dypr      = ppoints[startind].dypr;
+    ppoints[i].dxnr      = ppoints[startind].dxnr;
+    ppoints[i].dynr      = ppoints[startind].dynr;
+    ppoints[i].dxir      = ppoints[startind].dxir;
+    ppoints[i].dyir      = ppoints[startind].dyir;
+    ppoints[i].dist2prev = ppoints[startind].dist2prev;
+    ppoints[i].dist2next = ppoints[startind].dist2next;
+    if ( ppoints[i].type == PPOINT_BEZIER_D ) {
+      transformOffCurvePathPoint( strokewidth, i-2);
+    }
+    ppoints[i].shape     = ppoints[startind].shape;
+  }
+  
+
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "\nTransformation of PathPoints finished. Starting to construct paths ...\n\n");
+#endif
+  
+  /* We now have computed the resulting shift values for each path point of the current
+     subpath's right path. The values for the left path follow by negation.
+     The path is still to be build!
+  */
+
+  /********************************************************************************
+   ********************************************************************************
+   ***** 
+   ***** Construction of right path
+   ***** 
+   ********************************************************************************
+   ********************************************************************************/
+
+  /* The leading move segment is treated separately. First check from which
+     point the leading Moveto was called. This is safe even in cases where
+     multiple moveto appear in a series. */
+  i = startind;
+  while ( ppoints[i].type == PPOINT_MOVE )
+    --i;
+  dx1  = ppoints[startind].x - (ppoints[i].x);
+  dy1  = ppoints[startind].y - (ppoints[i].y);
+  /* If the first node in the subpath is not concave, we may directly jump
+     to the intersection right path point. Otherwise, we remain at the onCurve
+     point because later, prolongation will happen. */
+  if ( ppoints[startind].shape != CURVE_CONCAVE ) {
+    dx1  += ppoints[startind].dxir;
+    dy1  += ppoints[startind].dyir;
+  }
+  
+#ifdef DUMPDEBUGPATH
+  if ( psfile != NULL )
+    fprintf( psfile, "%f %f t1srmoveto %% pindex = %ld\n", dx1*up, dy1*up, startind);
+#endif
+  B = Loc(CharSpace, dx1, dy1);
+  path = Join(path, B);
+  
+  
+  /* Now, handle the remaining path in a loop */
+  for ( i=startind+1; i<=stopind; ) {
+    switch ( ppoints[i].type ) {
+    case PPOINT_LINE:
+      /* handle a line segment */
+      
+      /* 1. Check and handle starting node */
+      linkNode( i-1, PATH_START, PATH_RIGHT);
+
+      /* 2. Draw ideal isolated line segment */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "RP:  Line from point %ld to %ld\n", i-1, i);
+#endif
+      dx1  = ppoints[i].x + ppoints[i].dxpr - (ppoints[i-1].x + ppoints[i-1].dxnr);
+      dy1  = ppoints[i].y + ppoints[i].dypr - (ppoints[i-1].y + ppoints[i-1].dynr);
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL )
+	fprintf( psfile, "%f %f t1srlineto %% pindex = %ld\n", dx1*up, dy1*up, i);
+#endif
+      B = Loc(CharSpace, dx1, dy1);
+      path = Join(path, Line(B));
+
+      /* 3. Check and handle ending node */
+      linkNode( i, PATH_END, PATH_RIGHT);
+
+      break;
+
+    case PPOINT_BEZIER_B:
+      break;
+    case PPOINT_BEZIER_C:
+      break;
+    case PPOINT_BEZIER_D:
+      /* handle a bezier segment (given by this and the previous 3 path points)! */
+
+      /* 1. Check and handle starting node */
+      linkNode( i-3, PATH_START, PATH_RIGHT);
+
+      /* 2. Draw curve based on ideal point locations */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "RP:  Curve from PP %ld to PP %ld to PP %ld to PP %ld\n",
+	       i-3, i-2, i-1, i);
+#endif
+      dx1  = ppoints[i-2].x + ppoints[i-2].dxir - (ppoints[i-3].x + ppoints[i-3].dxnr);
+      dy1  = ppoints[i-2].y + ppoints[i-2].dyir - (ppoints[i-3].y + ppoints[i-3].dynr);
+      dx2  = ppoints[i-1].x + ppoints[i-1].dxir - (ppoints[i-2].x + ppoints[i-2].dxir);
+      dy2  = ppoints[i-1].y + ppoints[i-1].dyir - (ppoints[i-2].y + ppoints[i-2].dyir);
+      dx3  = ppoints[i].x +   ppoints[i].dxpr   - (ppoints[i-1].x + ppoints[i-1].dxir);
+      dy3  = ppoints[i].y +   ppoints[i].dypr   - (ppoints[i-1].y + ppoints[i-1].dyir);
+      
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL )
+	fprintf( psfile, "%f %f %f %f %f %f t1srrcurveto %% pindex = %ld\n",
+		 dx1*up, dy1*up,
+		 dx2*up, dy2*up,
+		 dx3*up, dy3*up,
+		 i);
+#endif
+      IfTrace4((FontDebug), "RRCurveTo %f %f %f %f ",
+	       dx1, dy1, dx2, dy2);
+      IfTrace2((FontDebug), "%f %f\n", dx3, dy3);
+      B = Loc(CharSpace, dx1, dy1);
+      C = Loc(CharSpace, dx2, dy2);
+      D = Loc(CharSpace, dx3, dy3);
+    
+      C = Join(C, (struct segment *)Dup(B));
+      D = Join(D, (struct segment *)Dup(C));
+      path = Join(path, (struct segment *)Bezier(B, C, D));
+
+      /* 3. Check and handle starting node */
+      linkNode( i, PATH_END, PATH_RIGHT);
+
+      break;
+
+      
+    case PPOINT_CLOSEPATH:
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "RP:  ClosePath command ignored\n");
+#endif
+      
+      break;
+
+    default:
+      break;
+      
+    }
+    ++i;
+  }
+
+  /********************************************************************************
+   ********************************************************************************
+   ***** 
+   ***** Close right path
+   ***** 
+   ********************************************************************************
+   ********************************************************************************/
+
+  if ( subpathclosed != 0 ) {
+    /* We are stroking an outline font to be filled */ 
+    if ( closepathatfirst == 0 ) {
+      /* Because of the concavity issue, we may not simply use
+	 the closepath operator here. Instead we have to manage a possible
+	 prolongation manually if the closepath would cause a line segment. */
+
+      /* 1. Check and handle starting node */
+      linkNode( lastind, PATH_START, PATH_RIGHT);
+
+      /* 2. Draw ideal isolated line segment */
+      dx1  = ppoints[startind].x + ppoints[startind].dxpr - (ppoints[lastind].x + ppoints[lastind].dxnr);
+      dy1  = ppoints[startind].y + ppoints[startind].dypr - (ppoints[lastind].y + ppoints[lastind].dynr);
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL )
+	fprintf( psfile, "%f %f t1srlineto %% pindex = %ld\n", dx1*up, dy1*up, startind);
+#endif
+      B = Loc(CharSpace, dx1, dy1);
+      path = Join(path, Line(B));
+
+      /* 3. Check and handle ending node */
+      linkNode( startind, PATH_END, PATH_RIGHT);
+
+    } /* if ( closepathatfirst == 0) */
+
+    /* Now close path formally. Anyhow, this won't cause a line segment! */
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL ) {
+      fprintf( psfile, "t1sclosepath %% Right Path finished, stepping to Left Path\n");
+    }
+#endif
+    tmpseg = Phantom(path);
+    path = ClosePath(path);
+    path = Join(Snap(path), tmpseg);
+
+    
+    /********************************************************************************
+     ********************************************************************************
+     ***** 
+     ***** Stepping to beginning of left path
+     ***** 
+     ********************************************************************************
+     ********************************************************************************/
+    
+    /* If curve is concave at the subpath's starting point, the location is onCurve
+       and the left path is convex, there. Conversely, if the curve is convex, the
+       location is at the right intersection point and the left path will be concave
+       so that the initial location must be onCurve. Hence, for both cases, we have
+       to translate back once the intersection shift.
+
+       If the curve is straight at the starting point, we directly jump from the right
+       intersection point ot he left intersection point.
+    */
+    if ( (ppoints[startind].shape == CURVE_CONCAVE) ||
+	 (ppoints[startind].shape == CURVE_CONVEX) ) { 
+      dx1 = - ppoints[startind].dxir;
+      dy1 = - ppoints[startind].dyir;
+    }
+    else {
+      dx1 = - 2.0 * ppoints[startind].dxir;
+      dy1 = - 2.0 * ppoints[startind].dyir;
+    }
+
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1srmoveto %% pindex = %ld\n", dx1*up, dy1*up, startind);
+#endif
+    B = Loc(CharSpace, dx1, dy1);
+    path = Join(path, B);
+  } /* if ( subpathclose != 0 */
+  else {
+    /* We have a stroked font. In this case, a line segment has to be drawn */
+    if ( (ppoints[stopind].shape == CURVE_CONCAVE) ||
+	 (ppoints[stopind].shape == CURVE_CONVEX) ) { 
+      dx1 = - ppoints[stopind].dxir;
+      dy1 = - ppoints[stopind].dyir;
+    }
+    else {
+      dx1 = - 2.0 * ppoints[stopind].dxir;
+      dy1 = - 2.0 * ppoints[stopind].dyir;
+    }
+
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1srlineto %% pindex = %ld\n", dx1*up, dy1*up, stopind);
+#endif
+    B = Loc(CharSpace, dx1, dy1);
+    path = Join(path, Line(B));
+    
+  }
+  
+  
+  /********************************************************************************
+   ********************************************************************************
+   ***** 
+   ***** Construction of left path
+   ***** 
+   ********************************************************************************
+   ********************************************************************************/
+  
+  /* Create left path. This is somewhat more complicated, because the
+     order/direction has to be exchanged. */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "Constructing LeftPath: stopind=%ld, lastind=%ld, closepathatfirst=%d\n",
+	   stopind, lastind, closepathatfirst);
+#endif
+  for ( i=stopind; i>=startind; ) {
+    if ( subpathclosed != 0 ) {
+      /* closed subpath --> filled font */
+      if ( i == stopind ) {
+	ip   = startind;
+	if ( (closepathatfirst != 0) )
+	  type = ppoints[ip].type;
+	else
+	  type = PPOINT_NONE;
+      }
+      else if ( i == startind ) {
+	ip   = startind + 1;
+	type = ppoints[ip].type;
+      }
+      else {
+	ip   = i + 1;
+	type = ppoints[ip].type;
+      }
+    }
+    else {
+      /* open subpath --> stroked font */
+      type   = ppoints[i].type;
+      in     = i - 1;
+    }
+
+    /* Step through path in inverted direction.
+       Note: - ip is the index of the starting point, i the index of the
+               ending point of the current segment.
+             - If the path point is flagged "concave", then this reverts into
+               "convex" in the left path and vice versa!
+	     - there is an index shift of 1 between closed and open subpaths.
+    */
+    switch ( type ) {
+    case PPOINT_MOVE:
+      
+      break;
+      
+    case PPOINT_LINE:
+
+      /* handle a line segment */
+      if ( subpathclosed != 0 ) {
+	segendind    = i;
+	segstartind  = ip;
+      }
+      else {
+	segstartind  = i;
+	segendind    = in;
+      }
+      
+      /* 1. Check and handle starting node */
+      linkNode( segstartind, PATH_START, PATH_LEFT);
+
+      /* 2. Draw ideal isolated line segment */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "LP:  Line from point %ld to %ld\n", segstartind, segendind);
+#endif
+      dx1  = ppoints[segendind].x - ppoints[segendind].dxnr -
+	(ppoints[segstartind].x - ppoints[segstartind].dxpr);
+      dy1  = ppoints[segendind].y - ppoints[segendind].dynr -
+	(ppoints[segstartind].y - ppoints[segstartind].dypr);
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL )
+	fprintf( psfile, "%f %f t1srlineto %% pindex = %ld\n", dx1*up, dy1*up, segendind);
+#endif
+      B = Loc(CharSpace, dx1, dy1);
+      path = Join(path, Line(B));
+
+      /* 3. Check and handle ending node */
+      linkNode( segendind, PATH_END, PATH_LEFT);
+
+      break;
+
+      
+    case PPOINT_BEZIER_B:
+      break;
+
+    case PPOINT_BEZIER_C:
+      break;
+
+    case PPOINT_BEZIER_D:
+      /* handle a bezier segment (given by this and the previous 3 path points)!
+	 For bezier segments, we may not simply apply the intersection of previous
+	 and next candidate because that would damage the curve's layout. Instead,
+	 in cases where the candidate produced by intersection is not identical to
+	 the ideal point, we prolongate and link the distance with a line segment.
+      */
+
+      /* 1. Check and handle starting node */
+      linkNode( ip, PATH_START, PATH_LEFT);
+
+      /* 2. Draw ideal curve segment */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "LP:  Curve from PP %ld to PP %ld to PP %ld to PP %ld\n",
+	       ip, ip-1, ip-2, ip-3);
+#endif
+      /* Use ideal point locations for curve at starting and ending point: */
+      dx1  = ppoints[ip-1].x - ppoints[ip-1].dxir - (ppoints[ip].x   - ppoints[ip].dxpr);
+      dy1  = ppoints[ip-1].y - ppoints[ip-1].dyir - (ppoints[ip].y   - ppoints[ip].dypr);
+      dx2  = ppoints[ip-2].x - ppoints[ip-2].dxir - (ppoints[ip-1].x - ppoints[ip-1].dxir);
+      dy2  = ppoints[ip-2].y - ppoints[ip-2].dyir - (ppoints[ip-1].y - ppoints[ip-1].dyir);
+      dx3  = ppoints[ip-3].x - ppoints[ip-3].dxnr - (ppoints[ip-2].x - ppoints[ip-2].dxir);
+      dy3  = ppoints[ip-3].y - ppoints[ip-3].dynr - (ppoints[ip-2].y - ppoints[ip-2].dyir);
+
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL )
+	fprintf( psfile, "%f %f %f %f %f %f t1srrcurveto %% pindex = %ld\n",
+		 dx1*up, dy1*up,
+		 dx2*up, dy2*up,
+		 dx3*up, dy3*up,
+		 i);
+#endif
+      IfTrace4((FontDebug), "RRCurveTo %f %f %f %f ",
+	       dx1, dy1, dx2, dy2);
+      IfTrace2((FontDebug), "%f %f\n", dx3, dy3);
+      B = Loc(CharSpace, dx1, dy1);
+      C = Loc(CharSpace, dx2, dy2);
+      D = Loc(CharSpace, dx3, dy3);
+    
+      C = Join(C, (struct segment *)Dup(B));
+      D = Join(D, (struct segment *)Dup(C));
+      path = Join(path, (struct segment *)Bezier(B, C, D));
+
+      /* 3. Check and handle ending node */
+      linkNode( ip-3, PATH_END, PATH_LEFT);
+
+      break;
+
+      
+    case PPOINT_CLOSEPATH:
+      
+      /* Handle a ClosePath segment, if it had
+	 caused a line segment. Hence, actually, we handle
+	 a line segment here. */
+      if ( closepathatfirst == 1 ) {
+	/* ignore this command */
+	break;
+      }
+
+      /* 1. Check and handle starting node */
+      linkNode( startind, PATH_START, PATH_LEFT);
+
+      /* 2. Draw ideal isolated line segment */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "LP:  Inverted ClosePath from point %ld to %ld\n", startind, lastind);
+#endif
+      if ( subpathclosed != 0 ) {
+	dx1  = ppoints[lastind].x - ppoints[lastind].dxnr - (ppoints[startind].x - ppoints[startind].dxpr);
+	dy1  = ppoints[lastind].y - ppoints[lastind].dynr - (ppoints[startind].y - ppoints[startind].dypr);
+      }
+      else {
+	dx1  = -(ppoints[i].x - ppoints[i].dxnr - (ppoints[ip].x - ppoints[ip].dxpr));
+	dy1  = -(ppoints[i].y - ppoints[i].dynr - (ppoints[ip].y - ppoints[ip].dypr));
+      }
+      
+#ifdef DUMPDEBUGPATH
+      if ( psfile != NULL ) {
+	if ( subpathclosed != 0 ) {
+	  fprintf( psfile, "%f %f t1srlineto %% (Inverted ClosePath, subpathclosed=1) pindex = %ld\n",
+		   dx1*up, dy1*up, lastind);
+	}
+	else {
+	  fprintf( psfile, "%f %f t1srlineto %% (Inverted ClosePath, subpathclosed=0) pindex = %ld\n",
+		   dx1*up, dy1*up, i);
+	}
+      }
+#endif
+      B = Loc(CharSpace, dx1, dy1);
+      path = Join(path, Line(B));
+
+      /* 3. Check and handle ending node */
+      linkNode( lastind, PATH_END, PATH_LEFT);
+      
+      break;
+      
+    default:
+      break;
+      
+    }
+    --i;
+  }
+
+#ifdef DUMPDEBUGPATH
+  if ( psfile != NULL ) {
+    fprintf( psfile, "t1sclosepath\n");
+  }
+#endif
+  tmpseg = Phantom(path);
+  path = ClosePath(path);
+  path = Join(Snap(path), tmpseg);
+  
+  
+  /********************************************************************************
+   ********************************************************************************
+   ***** 
+   ***** Move to final position
+   ***** 
+   ********************************************************************************
+   ********************************************************************************/
+  
+  /* Step to back to starting point of this subpath. If closepathatfirst==0, the
+     final closepath caused a line segment. In this case, we first have to step
+     back that segment and proceed from this point. */
+  if ( ppoints[startind].shape == CURVE_CONVEX ) {
+    /* In this case, left path is concave and the current location is at
+       the onCurve point */
+    dx1  = 0.0;
+    dy1  = 0.0;
+  }
+  else {
+    /* OK, it seems to be the intersection point */
+    dx1  = ppoints[startind].dxir;
+    dy1  = ppoints[startind].dyir;
+  }
+  /* We are now onCurve. If necessary step to the point where the closepath
+     appeared. */
+  if ( closepathatfirst == 0 ) {
+    dx1 += ppoints[lastind].x - ppoints[startind].x;
+    dy1 += ppoints[lastind].y - ppoints[startind].y;
+  }
+
+  
+#ifdef DUMPDEBUGPATH
+  if ( psfile != NULL )
+    fprintf( psfile, "%f %f t1srmoveto %% pindex = %ld\n", dx1*up, dy1*up, lastind);
+#endif
+  B = Loc(CharSpace, dx1, dy1);
+  path = Join(path, B);
+
+  return;
+  
+}
+
+
+
+/* Compute distance from OnCurve-points to their neighbouring points, fill in
+   the respective entries dist2prev and dist2next in the ppoints[] structures
+   and return the index of the last point in the current subpath which has
+   a location different from the starting point of the subpath. */
+static long computeDistances( long startind, long stopind, int subpathclosed)
+{
+  long   lastind       = 0;
+  double dx            = 0.0;
+  double dy            = 0.0;
+  long   i             = 0;
+  int    neighboured   = 0;
+
+
+  /* Handle first point as a special case */
+  /* distance to previous point. First, get index of previous point. */
+  lastind = stopind;
+
+  if ( subpathclosed != 0 ) {
+    if ( (ppoints[startind].x == ppoints[stopind].x) &&
+	 (ppoints[startind].y == ppoints[stopind].y) ) {
+      while ( (ppoints[lastind].x == ppoints[stopind].x) &&
+	      (ppoints[lastind].y == ppoints[stopind].y))
+	--lastind;
+    }
+    else {
+      lastind = stopind - 1;
+    }
+  }
+  
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr,
+	   "computeDistance(): startind=%ld stopind=%ld, lastind=%ld, start.x=%f, start.y=%f, last.x=%f, last.y=%f\n",
+	   startind, stopind, lastind, ppoints[startind].x, ppoints[startind].y,
+	   ppoints[lastind].x, ppoints[lastind].y);
+#endif
+  
+  dx = ppoints[startind].x - ppoints[lastind].x;
+  dy = ppoints[startind].y - ppoints[lastind].y;
+  ppoints[startind].dist2prev = sqrt( dx*dx + dy*dy );
+  
+  /* distance to next point */
+  dx = ppoints[startind+1].x - ppoints[startind].x;
+  dy = ppoints[startind+1].y - ppoints[startind].y;
+  ppoints[startind].dist2next = sqrt( dx*dx + dy*dy );
+  
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr,
+	   "Pre: Distance at point %ld: Prev=%f Next=%f\n",
+	   startind, ppoints[startind].dist2prev, ppoints[startind].dist2next);
+#endif
+  
+  for ( i = startind+1; i < lastind; i++ ) {
+    if ( (ppoints[i].type == PPOINT_MOVE) ||
+	 (ppoints[i].type == PPOINT_LINE) ||
+	 (ppoints[i].type == PPOINT_BEZIER_D) ) {
+      if ( neighboured ) {
+	ppoints[i].dist2prev = ppoints[i-1].dist2next;
+      }
+      else {
+	/* distance to previous point */
+	dx = ppoints[i].x - ppoints[i-1].x;
+	dy = ppoints[i].y - ppoints[i-1].y;
+	/* Take care of degenerated curves */
+	if ( (dx == 0.0) && (dy == 0.0) ) {
+	  dx = ppoints[i].x - ppoints[i-2].x;
+	  dy = ppoints[i].y - ppoints[i-2].y;
+	  if ( (dx == 0.0) && (dy == 0.0) ) {
+	    dx = ppoints[i].x - ppoints[i-3].x;
+	    dy = ppoints[i].y - ppoints[i-3].y;
+	  }
+	}
+	ppoints[i].dist2prev = sqrt( dx*dx + dy*dy );
+      }
+      /* distance to next point */
+      dx = ppoints[i+1].x - ppoints[i].x;
+      dy = ppoints[i+1].y - ppoints[i].y;
+      /* Take care of degenerated curves */
+      if ( (dx == 0.0) && (dy == 0.0) ) {
+	dx = ppoints[i+2].x - ppoints[i].x;
+	dy = ppoints[i+2].y - ppoints[i].y;
+	if ( (dx == 0.0) && (dy == 0.0) ) {
+	  dx = ppoints[i+3].x - ppoints[i].x;
+	  dy = ppoints[i+3].y - ppoints[i].y;
+	}
+      }
+      ppoints[i].dist2next = sqrt( dx*dx + dy*dy );
+      neighboured = 1;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "     Distance at point %ld: Prev=%f Next=%f\n",
+	       i, ppoints[i].dist2prev, ppoints[i].dist2next);
+#endif
+    }
+    else {
+      neighboured = 0;
+    }
+    
+  }
+  /* We still have to handle the last point */
+  /* distance to previous point */
+  dx = ppoints[lastind].x - ppoints[lastind-1].x;
+  dy = ppoints[lastind].y - ppoints[lastind-1].y;
+  /* Take care of degenerated curves */
+  if ( (dx == 0.0) && (dy == 0.0) ) {
+    dx = ppoints[lastind].x - ppoints[lastind-2].x;
+    dy = ppoints[lastind].y - ppoints[lastind-2].y;
+    if ( (dx == 0.0) && (dy == 0.0) ) {
+      dx = ppoints[lastind].x - ppoints[lastind-3].x;
+      dy = ppoints[lastind].y - ppoints[lastind-3].y;
+    }
+  }
+  ppoints[lastind].dist2prev = sqrt( dx*dx + dy*dy );
+  /* distance to next point */
+  ppoints[lastind].dist2next = ppoints[startind].dist2prev;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "End: Distance at point %ld: Prev=%f Next=%f\n",
+	   lastind, ppoints[lastind].dist2prev, ppoints[lastind].dist2next);
+#endif
+  
+  return lastind;
+  
+}
+
+
+
+/*
+
+ */
+static long handleNonSubPathSegments( long pindex)
+{
+
+  /* handle the different segment types in a switch-statement */
+  switch ( ppoints[pindex].type ) {
+
+  case PPOINT_SBW:
+#ifdef DUMPDEBUGPATH
+  if ( psfile != NULL )
+    fprintf( psfile, "%f %f %f %f t1sbw %% pindex = %ld\n",
+	     ppoints[pindex].x*up, ppoints[pindex].y*up,   /* sidebearings */
+	     ppoints[pindex].ax*up, ppoints[pindex].ay*up,  /* escapements  */
+	     pindex
+	     );
+#endif
+    path = Join(path, Loc(CharSpace, ppoints[pindex].x, ppoints[pindex].y));
+    return 1;
+    break;
+    
+
+  case PPOINT_ENDCHAR:
+    /* Perform a Closepath just in case the command was left out */
+    path = ClosePath(path);
+    
+    /* Set character width / escapement. It is stored in the vars for
+       hinted coordinates. */
+    path = Join(Snap(path), Loc(CharSpace, ppoints[pindex].ax, ppoints[pindex].ay));
+    
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fputs( "t1FinishPage\n", psfile);
+#endif
+    return 1;
+    break;
+    
+
+  case PPOINT_SEAC:
+    /* return to origin of accent */
+    apath = Snap(path);
+    /* reset path to NULL */
+    path  = NULL;
+    return 1;
+    break;
+    
+    
+  default:
+    /* not handled, return 0! */
+    ;
+  }
+  
+  return 0;
+  
+}
+
+
+
+/* Transform a path point according to the path's incoming angle, the path's
+   outgoing angle and the parameter strokewidth. The computation is based on
+   simple geometric considerations and makes use of the distance from the
+   current point to the previous point and the next point respectively.
+
+   Generally, each link to a path point induces its own candidate by simply
+   widening the respective link orthogonally to strokewidth/2. This yields
+   two displacement vectors (dx,dy) for the link from the previous point to the
+   point under consideration (dxp, dyp) and and for the link from the current
+   point to the next point (dxn, dyn).
+
+   Later on, the two candidates are used to compute the resulting displacement
+   as the intersection of the prolongated lines from before and behind the
+   current point.
+
+   Additionally, check whether the curve is concave or convex at this point.
+   This is required for prolongation in the context of stroking.
+*/
+static void transformOnCurvePathPoint( double strokewidth,
+				       long prevind, long currind, long nextind)
+{
+  double distxp;
+  double distyp;
+  double distxn;
+  double distyn;
+  double det;
+
+  /*
+  distxp =  (ppoints[currind].y - ppoints[prevind].y);
+  distyp = -(ppoints[currind].x - ppoints[prevind].x);
+  distxn =  (ppoints[nextind].y - ppoints[currind].y);
+  distyn = -(ppoints[nextind].x - ppoints[currind].x);
+
+  ppoints[currind].dxpr = distxp * strokewidth * 0.5 / ppoints[currind].dist2prev;
+  ppoints[currind].dypr = distyp * strokewidth * 0.5 / ppoints[currind].dist2prev;
+
+  ppoints[currind].dxnr = distxn * strokewidth * 0.5 / ppoints[currind].dist2next;
+  ppoints[currind].dynr = distyn * strokewidth * 0.5 / ppoints[currind].dist2next;
+  */
+  /* Note: When computing transformations of OnCurve points, we consider two
+           special cases:
+
+	   1) The OnCurve beginning or end point is equal to the neighboring
+	      control point of a Bezier-Segment.
+
+	   2) This holds for beginning *and* end point. In this case the curve
+	      degenerates to a straight lines.
+
+	   Although this is deprecated by Adobe, fonts that use such constructions
+	   exist (e.g.m lower case 'n' of Univers 55). However, we do not care
+	   for segments that do not any escapement at all!
+  */
+  
+  distxp =  (ppoints[currind].y - ppoints[prevind].y);
+  distyp = -(ppoints[currind].x - ppoints[prevind].x);
+  if ( (distxp == 0.0) && (distyp == 0.0) ) {
+    distxp =  (ppoints[currind].y - ppoints[prevind-1].y);
+    distyp = -(ppoints[currind].x - ppoints[prevind-1].x);
+    if ( (distxp == 0.0) && (distyp == 0.0) ) {
+      distxp =  (ppoints[currind].y - ppoints[prevind-2].y);
+      distyp = -(ppoints[currind].x - ppoints[prevind-2].x);
+    }
+  }
+  ppoints[currind].dxpr = distxp * strokewidth * 0.5 / ppoints[currind].dist2prev;
+  ppoints[currind].dypr = distyp * strokewidth * 0.5 / ppoints[currind].dist2prev;
+  
+  distxn =  (ppoints[nextind].y - ppoints[currind].y);
+  distyn = -(ppoints[nextind].x - ppoints[currind].x);
+  if ( (distxn == 0.0) && (distyn == 0.0) ) {
+    distxn =  (ppoints[nextind+1].y - ppoints[currind].y);
+    distyn = -(ppoints[nextind+1].x - ppoints[currind].x);
+    if ( (distxn == 0.0) && (distyn == 0.0) ) {
+      distxn =  (ppoints[nextind+2].y - ppoints[currind].y);
+      distyn = -(ppoints[nextind+2].x - ppoints[currind].x);
+    }
+  }
+  ppoints[currind].dxnr = distxn * strokewidth * 0.5 / ppoints[currind].dist2next;
+  ppoints[currind].dynr = distyn * strokewidth * 0.5 / ppoints[currind].dist2next;
+  
+  /* Consider determinant of the two tangent vectors at this node in order to
+     decide whether the curve is convex or cancave at this point. */
+  if ( (det = ((distxp * distyn) - (distxn * distyp))) < 0.0 ) {
+    /* curve turns to the right */
+    ppoints[currind].shape = CURVE_CONCAVE;
+  }
+  else if ( det > 0.0 ) {
+    /* curve turns to the left */
+    ppoints[currind].shape = CURVE_CONVEX;
+  }
+  else {
+    /* curve is straight */
+    ppoints[currind].shape = CURVE_STRAIGHT;
+  }
+  
+  return;
+}
+
+
+/* Compute a displacement for offCurve points, that is, for Bezier B and C points.
+   
+   This computation is not as simple as it might appear at a first glance and,
+   depending on the actual curve parameters and the parameter strokewidth, it might
+   be necessary to subdivide the curve. My mathematical background is not actually
+   reliable in this context but it seems that in particular the angle that the curve
+   runs through is important in this context. Since the Adobe Type 1 recommendations
+   on font design include a rule which states that curves' end points should be located
+   at extreme values, and consequently, that the angle of a curve segment should not
+   be larger than 90 degrees, I have decided not to implement curve subdivision. This
+   might lead to some deviations if fonts do not adhere to the Adobe recommendations.
+   Anyways, I have never seen such fonts.
+
+   This function is called for Bezier_B points and computes displacements for the B
+   and C points at once. Fortunately, index cycling cannot happen here. When
+   computing the B' C' off-curve points, special care against numerical instability
+   is required. We assume that at least one of the two points can be computed
+   in a stable way.
+
+   The new Bezier B' and C' points can be considered as four degrees of freedom and we have
+   to find 4 equations to be able to compute them. 
+
+   1) We require the tangents slope at point A' to be identical to the slope at the
+      point A of the ideally thin mathematical curve.
+
+   2) The same holds for the tangents slope at point D' with respect to point D.
+
+   3) We compute the following points
+
+      P1:       Equally subdivides the line A - B
+      P2:       Equally subdivides the line B - C
+      P3:       Equally subdivides the line C - D
+
+      P4:       Equally subdivides the line P1 - P2
+      P5:       Equally subdivides the line P1 - P3
+
+      P6:       Equally subdivides the line P4 - P5
+
+      This latter point is part of the curve and, moreover, the line P4 - P5 is
+      tangent to the curve at that point.
+      From this point, we compute a displacement for P6, orthogonally to the curve
+      at that point and with length strokewidth/2. The resulting point is part of
+      the delimiting path that makes up the thick curve.
+
+   4) We require that the tangent's slope at P6' equals the tangents slope at P6.
+
+   Then, under certain further constraints as mentioned above, we compute the points
+   B' and C' making use of the points A' and D' which have been transformed as onCurve
+   points. By definition, for offCurve points, there is only one candidate.
+
+ */
+static void transformOffCurvePathPoint( double strokewidth, long currind)
+{
+  double dtmp;
+  double diameter;
+  double dx;
+  double dy;
+  
+  /* points defining the curve */
+  double pax;
+  double pay;
+  double pbx;
+  double pby;
+  double pcx;
+  double pcy;
+  double pdx;
+  double pdy;
+  
+  /* auxiliary points from iterative Bezier construction */
+  double p1x;
+  double p1y;
+  double p2x;
+  double p2y;
+  double p3x;
+  double p3y;
+  double p4x;
+  double p4y;
+  double p5x;
+  double p5y;
+  double p6x;
+  double p6y;
+  
+  /* already displaced / shifted onCurve points and the ones we are going
+     to compute. */
+  double paxs;
+  double pays;
+  double pbxs;
+  double pbys;
+  double pcxs;
+  double pcys;
+  double pdxs;
+  double pdys;
+
+  /* The normal vector on the curve at t=1/2 */
+  double nabs;
+  double nx;
+  double ny;
+
+  /* some variables for computations at point B' */
+  double bloc1x;         
+  double bloc1y;
+  double bdir1x;
+  double bdir1y;
+  double bloc2x;
+  double bloc2y;
+  double bdir2x;
+  double bdir2y;
+  double bdet;
+  double binvdet;
+  double binvdir1x;
+  double binvdir1y; /**/
+  double binvdir2x;
+  double binvdir2y; /**/
+  double bmu;
+  double bnu; /**/
+
+  /* some variables for computations at point C' */
+  double cloc1x;         
+  double cloc1y;
+  double cdir1x;
+  double cdir1y;
+  double cloc2x;
+  double cloc2y;
+  double cdir2x;
+  double cdir2y;
+  double cdet;
+  double cinvdet;
+  double cinvdir1x;
+  double cinvdir1y; /**/
+  double cinvdir2x;
+  double cinvdir2y; /**/
+  double cmu;
+  double cnu; /**/
+  
+  diameter = strokewidth * 0.5;
+  
+  pax = ppoints[currind-1].x;
+  pay = ppoints[currind-1].y;
+  pbx = ppoints[currind].x;
+  pby = ppoints[currind].y;
+  pcx = ppoints[currind+1].x;
+  pcy = ppoints[currind+1].y;
+  pdx = ppoints[currind+2].x;
+  pdy = ppoints[currind+2].y;
+  
+  p1x = (pax + pbx) * 0.5;
+  p1y = (pay + pby) * 0.5;
+  p2x = (pbx + pcx) * 0.5;
+  p2y = (pby + pcy) * 0.5;
+  p3x = (pcx + pdx) * 0.5;
+  p3y = (pcy + pdy) * 0.5;
+  p4x = (p1x + p2x) * 0.5;
+  p4y = (p1y + p2y) * 0.5;
+  p5x = (p2x + p3x) * 0.5;
+  p5y = (p2y + p3y) * 0.5;
+  p6x = (p4x + p5x) * 0.5;
+  p6y = (p4y + p5y) * 0.5;
+
+  
+  /* We start by computing the shift of the onCurve points. It is not possible
+     to use  dxr / dyr of the ppoints-stucture entries. These values have been
+     computed by intersection of both links to a path point. Here we need the
+     ideal points of the thick isolated curve segment. We are aware that for
+     Bezier splines, control point and OnCurve point might be identical! */
+  dx   =   (ppoints[currind].y - ppoints[currind-1].y) * strokewidth * 0.5 / ppoints[currind-1].dist2next;
+  dy   = - (ppoints[currind].x - ppoints[currind-1].x) * strokewidth * 0.5 / ppoints[currind-1].dist2next;
+  if ( (dx == 0.0) && (dy == 0.0) ) {
+    /* Bezier_A and Bezier_B are identical */
+    dx   =   (ppoints[currind+1].y - ppoints[currind-1].y) * strokewidth * 0.5 / ppoints[currind-1].dist2next;
+    dy   = - (ppoints[currind+1].x - ppoints[currind-1].x) * strokewidth * 0.5 / ppoints[currind-1].dist2next;
+  }
+  paxs = ppoints[currind-1].x + dx;
+  pays = ppoints[currind-1].y + dy;
+  dx   =   (ppoints[currind+2].y - ppoints[currind+1].y) * strokewidth * 0.5 / ppoints[currind+2].dist2prev;
+  dy   = - (ppoints[currind+2].x - ppoints[currind+1].x) * strokewidth * 0.5 / ppoints[currind+2].dist2prev;
+  if ( (dx == 0.0) && (dy == 0.0) ) {
+    /* Bezier_C and Bezier_D are identical */
+    dx   =   (ppoints[currind+2].y - ppoints[currind].y) * strokewidth * 0.5 / ppoints[currind+2].dist2prev;
+    dy   = - (ppoints[currind+2].x - ppoints[currind].x) * strokewidth * 0.5 / ppoints[currind+2].dist2prev;
+  }
+  pdxs = ppoints[currind+2].x + dx;
+  pdys = ppoints[currind+2].y + dy;
+
+  /* Next, we compute the right side normal vector at the curve point t=1/2,
+   that is, at P6. */
+  nabs    = diameter / sqrt(((p5x - p4x) * (p5x - p4x)) + ((p5y - p4y) * (p5y - p4y)));
+  nx      = (p5y - p4y) * nabs;
+  ny      = (p4x - p5x) * nabs;
+
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "transformOffCurvePathPoint():\n");
+  fprintf( stderr, "    A=(%f,%f), B=(%f,%f), C=(%f,%f), D=(%f,%f)\n",
+	   pax, pay, pbx, pby, pcx, pcy, pdx, pdy);
+  fprintf( stderr, "    PathInfo: Curve from PP %ld ... PP %ld ... PP %ld ... PP %ld. StrokeWidth=%f.\n",
+	   currind-1, currind, currind+1, currind+2, strokewidth);
+  /*
+  fprintf( stderr, "/xa %f def\n/ya %f def\n/xb %f def\n/yb %f def\n/xc %f def\n/yc %f def\n/xd %f def\n/yd %f def\n",
+	   pax, pay, pbx, pby, pcx, pcy, pdx, pdy);
+  */
+  fprintf( stderr, "    As=(%f,%f), Ds=(%f,%f)\n",
+	   paxs, pays, pdxs, pdys);
+  fprintf( stderr, "    p6=(%f,%f)\n", p6x, p6y);
+  fprintf( stderr, "    nx=%f, ny=%f, nabs=%f\n", nx, ny, nabs);
+  fprintf( stderr, "    p6s=(%f,%f)\n", p6x+nx, p6y+ny);
+#endif
+
+  /* Compute two lines whose intersection will define point B' */
+  bloc1x = (4.0 * (nx + p6x) - (2 * paxs) + pdxs) / 3.0;
+  bloc1y = (4.0 * (ny + p6y) - (2 * pays) + pdys) / 3.0;
+  bdir1x = pcx + pdx - pax - pbx;
+  bdir1y = pcy + pdy - pay - pby;
+  bloc2x = paxs;
+  bloc2y = pays;
+  bdir2x = pbx - pax;
+  bdir2y = pby - pay;
+  bdet   = (bdir2x * bdir1y) - (bdir2y * bdir1x);
+
+#define DET_QUOTIENT_UPPER_THRESHOLD      (1.05)
+#define DET_QUOTIENT_LOWER_THRESHOLD      (1.0/DET_QUOTIENT_UPPER_THRESHOLD)
+
+  /* Life has shown, that the "reliability" of the determinant has to be
+     ensured. Otherwise, serious distortions might be introduced.
+     In order to ensure numerical stability, we do not only check whether
+     the detrminant is about zero, but we also check whether the two partial
+     expressions that are subtracted when computing the determinant are of
+     about the same size. If this is the case, we explicitly reset the
+     determinant and eventually compute this off-curve point based on the
+     other off-curve point later. */
+  if ( (bdir2x != 0.0) && (bdir1y != 0.0) ) {
+    dtmp = (bdir2y*bdir1x)/(bdir2x*bdir1y);
+    if ( (DET_QUOTIENT_LOWER_THRESHOLD < dtmp) &&
+	 (DET_QUOTIENT_UPPER_THRESHOLD > dtmp)
+	 ) {
+      /* Determinant appears to be unreliable, reset it exactly to zero. */
+      bdet = 0.0;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "    Warning: Determinant quotient check for bdet failed: dtmp=%16.16f, lower limit=%f, upper limit=%f.\n    --> Determinant does not seem to be stable, resetting to zero.\n",
+	       dtmp, DET_QUOTIENT_LOWER_THRESHOLD, DET_QUOTIENT_UPPER_THRESHOLD);
+#endif
+    }
+  }
+  else if ( (bdir2y != 0.0) && (bdir1x != 0.0) ) {
+    dtmp = (bdir2x*bdir1y)/(bdir2y*bdir1x);
+    if ( (DET_QUOTIENT_LOWER_THRESHOLD < dtmp) &&
+	 (DET_QUOTIENT_UPPER_THRESHOLD > dtmp)
+	 ) {
+      /* Determinant appears to be unreliable, reset it exactly to zero. */
+      bdet = 0.0;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "    Warning: Determinant quotient check for bdet failed: dtmp=%16.16f, lower limit=%f, upper limit=%f.\n    --> Determinant does not seem to be stable, resetting to zero.\n",
+	       dtmp, DET_QUOTIENT_LOWER_THRESHOLD, DET_QUOTIENT_UPPER_THRESHOLD);
+#endif
+    }
+  }
+      
+  
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "    bloc1x=%f, bloc1y=%f, bloc2x,=%f bloc2y=%f\n",
+	   bloc1x, bloc1y, bloc2x, bloc2y);
+  fprintf( stderr, "    bdir1x=%f, bdir1y=%f, bdir2x,=%f bdir2y=%f\n",
+	   bdir1x, bdir1y, bdir2x, bdir2y);
+#endif
+
+  /* Switch if determinant is zero; we then actually have a straight line */
+  if ( fabs(bdet) < 0.001 ) {
+    pbxs   = pbx + nx;
+    pbys   = pby + ny;
+    bmu    = 0.0;
+    bnu    = 0.0;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "    Warning: Determinant check for bdet failed: bdet=%16.16f. Computing Bs based on normal vector, resetting bmu, bnu.\n",
+	     bdet);
+#endif
+  }
+  else {
+    /* Calculate required part of inverse matrix */
+    binvdet   =   1.0 / bdet;
+    binvdir2x =   bdir1y * binvdet;
+    binvdir2y = - bdir2y * binvdet; /**/
+    binvdir1x = - bdir1x * binvdet;
+    binvdir1y =   bdir2x * binvdet; /**/
+
+    /* Calculate coefficient that describes intersection */
+    bmu       =   (binvdir2x * (bloc1x - bloc2x)) + (binvdir1x * (bloc1y - bloc2y));
+    bnu       =   (binvdir2y * (bloc1x - bloc2x)) + (binvdir1y * (bloc1y - bloc2y)); /**/
+
+    /* Calculate B' */
+    pbxs      =   bloc2x + (bmu * bdir2x);
+    pbys      =   bloc2y + (bmu * bdir2y);
+  }
+
+  /* Compute two lines whose intersection will define point C' */
+  cloc1x = (4.0 * (nx + p6x) - (2 * pdxs) + paxs) / 3.0;
+  cloc1y = (4.0 * (ny + p6y) - (2 * pdys) + pays) / 3.0;
+  cdir1x = bdir1x;
+  cdir1y = bdir1y;
+  cloc2x = pdxs;
+  cloc2y = pdys;
+  cdir2x = pcx - pdx;
+  cdir2y = pcy - pdy;
+  cdet   = (cdir2x * cdir1y) - (cdir2y * cdir1x);
+
+  /* Life has shown, that the "reliability" of the determinant has to be
+     ensured. Otherwise, serious distortions might be introduced.
+     In order to ensure numerical stability, we do not only check whether
+     the detrminant is about zero, but we also check whether the two partial
+     expressions that are subtracted when computing the determinant are of
+     about the same size. If this is the case, we explicitly reset the
+     determinant and eventually compute this off-curve point based on the
+     other off-curve point later. */
+  if ( (cdir2x != 0.0) && (cdir1y != 0.0) ) {
+    dtmp = (cdir2y*cdir1x)/(cdir2x*cdir1y);
+    if ( (DET_QUOTIENT_LOWER_THRESHOLD < dtmp) &&
+	 (DET_QUOTIENT_UPPER_THRESHOLD > dtmp)
+	 ) {
+      /* Determinant appears to be unreliable, reset it exactly to zero. */
+      cdet = 0.0;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "    Warning: Determinant quotient check for cdet failed: dtmp=%16.16f, lower limit=%f, upper limit=%f.\n    --> Determinant does not seem to be stable, resetting to zero.\n",
+	       dtmp, DET_QUOTIENT_LOWER_THRESHOLD, DET_QUOTIENT_UPPER_THRESHOLD);
+#endif
+    }
+  }
+  else if ( (cdir2y != 0.0) && (cdir1x != 0.0) ) {
+    dtmp = (cdir2x*cdir1y)/(cdir2y*cdir1x);
+    if ( (DET_QUOTIENT_LOWER_THRESHOLD < dtmp) &&
+	 (DET_QUOTIENT_UPPER_THRESHOLD > dtmp)
+	 ) {
+      /* Determinant appears to be unreliable, reset it exactly to zero. */
+      cdet = 0.0;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+      fprintf( stderr, "    Warning: Determinant quotient check for cdet failed: dtmp=%16.16f, lower limit=%f, upper limit=%f.\n    --> Determinant does not seem to be stable, resetting to zero.\n",
+	       dtmp, DET_QUOTIENT_LOWER_THRESHOLD, DET_QUOTIENT_UPPER_THRESHOLD);
+#endif
+    }
+  }
+      
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "    cloc1x=%f, cloc1y=%f, cloc2x,=%f cloc2y=%f\n",
+	   cloc1x, cloc1y, cloc2x, cloc2y);
+  fprintf( stderr, "    cdir1x=%f, cdir1y=%f, cdir2x,=%f cdir2y=%f\n",
+	   cdir1x, cdir1y, cdir2x, cdir2y);
+#endif
+
+  /* Switch if determinant is zero; we then actually have a straight line */
+  if ( fabs( cdet) < 0.001 ) {
+    pcxs   = pcx + nx;
+    pcys   = pcy + ny;
+    cmu    = 0.0;
+    cnu    = 0.0;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "    Warning: Determinant check for cdet failed: cdet=%16.16f. Computing Cs based on normal vector, resetting cmu, cnu.\n",
+	     cdet);
+#endif
+  }
+  else {
+    /* Calculate required part of inverse matrix */
+    cinvdet   =   1.0 / cdet;
+    cinvdir2x =   cdir1y * cinvdet;
+    cinvdir2y = - cdir2y * cinvdet; /**/
+    cinvdir1x = - cdir1x * cinvdet;
+    cinvdir1y =   cdir2x * cinvdet; /**/
+
+    /* Calculate coefficient that describes intersection */
+    cmu       =   (cinvdir2x * (cloc1x - cloc2x)) + (cinvdir1x * (cloc1y - cloc2y));
+    cnu       =   (cinvdir2y * (cloc1x - cloc2x)) + (cinvdir1y * (cloc1y - cloc2y)); /**/
+
+    /* Calculate C' */
+    pcxs      =   cloc2x + (cmu * cdir2x);
+    pcys      =   cloc2y + (cmu * cdir2y);
+  }
+
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "    bdet=%f, cdet=%f, bmu=%f, bnu=%f, cmu=%f, cnu=%f\n",
+	   bdet, cdet, bmu, bnu, cmu, cnu);
+#endif
+
+  /* Analyse coefficients and decide on numerical stability. If suggesting,
+     overwrite, using another relation. Here, we assume that at least the
+     solution at *one* end of the curve is stable. */
+  if ( fabs(bmu) < 0.1 ) {
+    pbxs = ((8 * (nx + p6x) - paxs - pdxs) / 3.0) - pcxs;
+    pbys = ((8 * (ny + p6y) - pays - pdys) / 3.0) - pcys;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "    Warning: Coefficient check for bmu failed: bmu=%16.16f. Computing Bs based on Cs.\n",
+	     bmu);
+#endif
+  }
+  if ( fabs(cmu) < 0.1 ) {
+    pcxs = ((8 * (nx + p6x) - paxs - pdxs) / 3.0) - pbxs;
+    pcys = ((8 * (ny + p6y) - pays - pdys) / 3.0) - pbys;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "    Warning: Coefficient check for cmu failed: cmu=%16.16f. Computing Cs based on Bs.\n",
+	     cmu);
+#endif
+  }
+  
+  
+  /* Store the resulting displacement values in the ppoints-struct so
+     they can be used for path construction. We use the "intersect" member
+     because in this case nothing is related to "previous" or "next".*/
+#ifdef DEBUG_OUTLINE_SURROUNDING
+  fprintf( stderr, "    pbx=%f, pbxs=%f, bxshift=%f, pby=%f, pbys=%f, byshift=%f\n",
+	   pbx, pbxs, pbxs-pbx, pby, pbys, pbys-pby);
+  fprintf( stderr, "    pcx=%f, pcxs=%f, cxshift=%f, pcy=%f, pcys=%f, cyshift=%f\n",
+	   pcx, pcxs, pcxs-pcx, pcy, pcys, pcys-pcy);
+  fprintf( stderr, "    Summary:    A =(%f,%f), B =(%f,%f), C =(%f,%f), D =(%f,%f)\n",
+	   pax, pay, pbx, pby, pcx, pcy, pdx, pdy);
+  fprintf( stderr, "                As=(%f,%f), Bs=(%f,%f), Cs=(%f,%f), Ds=(%f,%f)\n\n",
+	   paxs, pays, pbxs, pbys, pcxs, pcys, pdxs, pdys);
+#endif
+  ppoints[currind].dxir    = pbxs - pbx;
+  ppoints[currind].dyir    = pbys - pby;
+  ppoints[currind+1].dxir  = pcxs - pcx;
+  ppoints[currind+1].dyir  = pcys - pcy;
+
+  return;
+  
+}
+
+
+static void intersectRight( long index, double halfwidth, long flag)
+{
+  double r2  = 0.0;
+  double det = 0.0;
+  double dxprev;
+  double dyprev;
+  double dxnext;
+  double dynext;
+  
+  
+  /* In order to determine the intersection between the two
+     prolongations at the path point under consideration, we use
+     the Hesse Normal Form, multiplied with r.
+
+     dx * x + dy * y + r^2 = 0
+
+     Here, r is the distance from the origin, that is, from the path point
+     under consideration. */
+
+  /* Check for start and ending of non-closed paths */
+  if ( flag == INTERSECT_PREVIOUS ) {
+    ppoints[index].dxir = ppoints[index].dxpr;
+    ppoints[index].dyir = ppoints[index].dypr;
+    /* Correct shape to be "straight" at ending point! */
+    ppoints[index].shape = CURVE_STRAIGHT;
+    return;
+  }
+  if ( flag == INTERSECT_NEXT ) {
+    ppoints[index].dxir = ppoints[index].dxnr;
+    ppoints[index].dyir = ppoints[index].dynr;
+    /* Correct shape to be "straight" at starting point! */
+    ppoints[index].shape = CURVE_STRAIGHT;
+    return;
+  }
+
+  /* OK, we actually compute an intersection */
+  dxprev = ppoints[index].dxpr;
+  dyprev = ppoints[index].dypr;
+  dxnext = ppoints[index].dxnr;
+  dynext = ppoints[index].dynr;
+
+  /* Compute distance square */
+  r2 = halfwidth * halfwidth;
+
+  /* Check the determinant. If it is zero, the two lines are parallel
+     and also must touch at atleast one location,
+     so that there are an infinite number of solutions. In this case,
+     we compute the average position and are done. */
+  if ( fabs( (det = ((dyprev * dxnext) - (dynext * dxprev))) ) < 0.00001 ) {
+    ppoints[index].dxir = 0.5 * (dxprev + dxnext);
+    ppoints[index].dyir = 0.5 * (dyprev + dynext);
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "intersectRight(0):\n    dxprev=%f, dxnext=%f, dxres=%f,\n    dyprev=%f, dynext=%f, dyres=%f,\n    det=%16.16f\n",
+	     dxprev, dxnext, ppoints[index].dxir, dyprev, dynext, ppoints[index].dyir, det);
+    fprintf( stderr, "    --> Computation based on averaging [dxprev,dyprev] and [dxnext,dynext]\n");
+    fprintf( stderr, "    Right intersection point shift: (%f,%f), absolute shift length: %f.\n\n",
+	     ppoints[index].dxir, ppoints[index].dyir,
+	     sqrt(ppoints[index].dxir*ppoints[index].dxir + ppoints[index].dyir*ppoints[index].dyir));
+#endif
+    return;
+  }
+  /* OK, there seems to be a unique solution, compute it */
+  if ( dxprev != 0.0 ) {
+    ppoints[index].dyir =  r2 * (dxnext - dxprev) / det;
+    ppoints[index].dxir = (r2 - (dyprev * ppoints[index].dyir)) / dxprev; /* - ? */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "intersectRight(1):\n    dxprev=%f, dxnext=%f, dxres=%f,\n    dyprev=%f, dynext=%f, dyres=%f,\n    det=%16.16f\n",
+	     dxprev, dxnext, ppoints[index].dxir, dyprev, dynext, ppoints[index].dyir, det);
+    fprintf( stderr, "    --> Computation based on previous path point.\n");
+    fprintf( stderr, "    Right intersection point shift: (%f,%f), absolute shift length: %f.\n\n",
+	     ppoints[index].dxir, ppoints[index].dyir,
+	     sqrt(ppoints[index].dxir*ppoints[index].dxir + ppoints[index].dyir*ppoints[index].dyir));
+#endif
+  }
+  else {
+    ppoints[index].dyir = -r2 * (dxprev - dxnext) / det;
+    ppoints[index].dxir = (r2 - (dynext * ppoints[index].dyir)) / dxnext; /* - ? */
+#ifdef DEBUG_OUTLINE_SURROUNDING
+    fprintf( stderr, "intersectRight(2):\n    dxprev=%f, dxnext=%f, dxres=%f,\n    dyprev=%f, dynext=%f, dyres=%f,\n    det=%16.16f\n",
+	     dxprev, dxnext, ppoints[index].dxir, dyprev, dynext, ppoints[index].dyir, det);
+    fprintf( stderr, "    --> Computation based on next path point.\n");
+    fprintf( stderr, "    Right intersection point shift: (%f,%f), absolute shift length: %f.\n\n",
+	     ppoints[index].dxir, ppoints[index].dyir,
+	     sqrt(ppoints[index].dxir*ppoints[index].dxir + ppoints[index].dyir*ppoints[index].dyir));
+#endif
+  }
+  
+  return;
+     
+}
+
+
+
+/* linkNode(): Insert prolongation lines at nodes. */
+static void linkNode( long index, int position, int orientation)
+{
+  struct segment* B;
+  double dx = 0.0;
+  double dy = 0.0;
+
+  if ( orientation == PATH_RIGHT ) {
+    /* We are constructing the right hand side path */
+    if ( position == PATH_START ) {
+      /* We are starting a new segment. Link from current point to ideally
+	 next-shifted point of segment. */
+      if ( ppoints[index].shape == CURVE_CONCAVE ) {
+	/* prolongate from original curve point to ideally next-shifted point */
+	dx = ppoints[index].dxnr;
+	dy = ppoints[index].dynr;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "RP:  Concave at PP %ld. Prolongation from onCurve to ideal: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+      else if ( ppoints[index].shape == CURVE_CONVEX ) {
+	/* prolongate from intersecion point to ideally next-shifted point */
+	dx = ppoints[index].dxnr - ppoints[index].dxir;
+	dy = ppoints[index].dynr - ppoints[index].dyir;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "RP:  Convex at PP %ld. Prolongation from intersection to ideal: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+    }
+    else if ( position == PATH_END ) {
+      /* We are ending the current segment. Link from ideally prev-shifted point
+	 to the appropriate ending point. */
+      if ( ppoints[index].shape == CURVE_CONCAVE ) {
+	/* prolongate from ideally prev-shifted point to original curve point. */
+	dx = - ppoints[index].dxpr;
+	dy = - ppoints[index].dypr;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "RP:  Concave at PP %ld. Prolongation from ideal to onCurve: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+      else if ( ppoints[index].shape == CURVE_CONVEX ) {
+	/* prolongate from ideally prev-shifted point to intersection point. */
+	dx = ppoints[index].dxir - ppoints[index].dxpr;
+	dy = ppoints[index].dyir - ppoints[index].dypr;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "RP:  Convex at PP %ld. Prolongation from ideal to intersection: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+    } /* if ( PATH_END ) */
+  } /* if ( PATH_RIGHT ) */
+  else if ( orientation == PATH_LEFT ) {
+
+    /* We are constructing the left hand side path. Some notions have to be
+       reverted (e.g. concavity vs. convexity and next vs. previous)! */
+    if ( position == PATH_START ) {
+      /* We are starting a new segment. Link from current point to ideally
+	 next-shifted point of segment. */
+      if ( ppoints[index].shape == CURVE_CONVEX ) {
+	/* prolongate from original curve point to ideally next-shifted point.
+	   Remember: next --> prev! */
+	dx = - (ppoints[index].dxpr);
+	dy = - (ppoints[index].dypr);
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "LP:  Concave at PP %ld. Prolongation from onCurve to ideal: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+      else if ( ppoints[index].shape == CURVE_CONCAVE ) {
+	/* prolongate from intersecion point to ideally next-shifted point */
+	dx = - (ppoints[index].dxpr - ppoints[index].dxir);
+	dy = - (ppoints[index].dypr - ppoints[index].dyir);
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "LP:  Convex at PP %ld. Prolongation from intersection to ideal: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+    }/* if ( PATH_START ) */
+    else if ( position == PATH_END ) {
+      /* We are ending the current segment. Link from ideally prev-shifted point
+	 to the appropriate ending point. */
+      if ( ppoints[index].shape == CURVE_CONVEX ) {
+	/* prolongate from ideally prev-shifted point to original curve point. */
+	dx = ppoints[index].dxnr;
+	dy = ppoints[index].dynr;
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "LP:  Concave at PP %ld. Prolongation from ideal to onCurve: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+      else if ( ppoints[index].shape == CURVE_CONCAVE ) {
+	/* prolongate from ideally prev-shifted point to intersection point. */
+	dx = - (ppoints[index].dxir - ppoints[index].dxnr);
+	dy = - (ppoints[index].dyir - ppoints[index].dynr);
+#ifdef DEBUG_OUTLINE_SURROUNDING
+	fprintf( stderr, "LP:  Convex at PP %ld. Prolongation from ideal to intersection: (%f,%f)\n",
+		 index, dx, dy);
+#endif
+      }
+    } /* if ( PATH_END ) */
+  } /* if ( PATH_LEFT ) */
+
+  if ( (dx != 0.0) || (dy != 0.0) ) {
+#ifdef DUMPDEBUGPATH
+    if ( psfile != NULL )
+      fprintf( psfile, "%f %f t1sprolongate %% pindex = %ld\n", dx*up, dy*up, index);
+#endif
+    B = Loc( CharSpace, dx, dy);
+    path = Join(path, Line(B));
+  }
+  
+  return;
+  
+}
+
+
+int T1int_Type1QuerySEAC( unsigned char* base,
+			  unsigned char* accent)
+{
+  if ( isseac == 0 ) {
+    return 0;
+  }
+  
+  *base   = seacbase;
+  *accent = seacaccent;
+
+  return isseac;
+}
+
