]> git.imager.perl.org - imager.git/blobdiff - T1/imt1.c
freetype-config might not be available, allow pkg-config to work
[imager.git] / T1 / imt1.c
index 3027e424373c3aef7405d51c30ef58acad9b5095..306e22189bd1aad63bda2d3860ea4194ca0d7f8d 100644 (file)
--- a/T1/imt1.c
+++ b/T1/imt1.c
@@ -5,11 +5,33 @@
 
 static int t1_get_flags(char const *flags);
 static char *t1_from_utf8(char const *in, size_t len, int *outlen);
-
+static undef_int i_init_t1_low(int t1log);
 static void t1_push_error(void);
+static void i_t1_set_aa(int st);
 
 static int t1_active_fonts = 0;
 static int t1_initialized = 0;
+static int t1_aa = -1;
+
+struct i_t1_font_tag {
+  int font_id;
+};
+
+static i_mutex_t mutex;
+
+/*
+=item i_t1_start()
+
+Initialize the font driver.  This does not actually initialize T1Lib,
+it just allocates the mutex we use to gate access to it.
+
+=cut
+*/
+
+void
+i_t1_start(void) {
+  mutex = i_mutex_new();
+}
 
 /* 
 =item i_init_t1(t1log)
@@ -21,8 +43,21 @@ Initializes the t1lib font rendering engine.
 
 undef_int
 i_init_t1(int t1log) {
+  undef_int result;
+  i_mutex_lock(mutex);
+
+  result = i_init_t1_low(t1log);
+
+  i_mutex_unlock(mutex);
+
+  return result;
+}
+
+static undef_int
+i_init_t1_low(int t1log) {
   int init_flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE;
-  mm_log((1,"init_t1()\n"));
+
+  mm_log((1,"init_t1(%d)\n", t1log));
 
   i_clear_error();
 
@@ -45,7 +80,6 @@ i_init_t1(int t1log) {
     return(1);
   }
   T1_SetLogLevel(T1LOG_DEBUG);
-  i_t1_set_aa(1); /* Default Antialias value */
 
   ++t1_initialized;
 
@@ -64,8 +98,10 @@ Shuts the t1lib font rendering engine down.
 
 void
 i_close_t1(void) {
+  i_mutex_lock(mutex);
   T1_CloseLib();
   t1_initialized = 0;
+  i_mutex_unlock(mutex);
 }
 
 
@@ -80,21 +116,27 @@ Loads the fonts with the given filenames, returns its font id
 =cut
 */
 
-int
+i_t1_font_t
 i_t1_new(char *pfb,char *afm) {
   int font_id;
+  i_t1_font_t font;
+
+  i_mutex_lock(mutex);
 
   i_clear_error();
 
-  if (!t1_initialized && i_init_t1(0))
-    return -1;
+  if (!t1_initialized && i_init_t1_low(0)) {
+    i_mutex_unlock(mutex);
+    return NULL;
+  }
 
   mm_log((1,"i_t1_new(pfb %s,afm %s)\n",pfb,(afm?afm:"NULL")));
   font_id = T1_AddFont(pfb);
   if (font_id<0) {
     mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id));
     t1_push_error();
-    return font_id;
+    i_mutex_unlock(mutex);
+    return NULL;
   }
   
   if (afm != NULL) {
@@ -107,33 +149,48 @@ i_t1_new(char *pfb,char *afm) {
     t1_push_error();
     i_push_error(0, "loading font");
     T1_DeleteFont(font_id);
-    return -1;
+    i_mutex_unlock(mutex);
+    return NULL;
   }
 
   ++t1_active_fonts;
 
-  mm_log((1, "i_t1_new() -> %d\n", font_id));
+  i_mutex_unlock(mutex);
+
+  font = mymalloc(sizeof(*font));
+  font->font_id = font_id;
+
+  mm_log((1, "i_t1_new() -> %p (%d)\n", font, font_id));
 
-  return font_id;
+  return font;
 }
 
 /*
-=item i_t1_destroy(font_id)
+=item i_t1_destroy(font)
 
 Frees resources for a t1 font with given font id.
 
-   font_id - number of the font to free
+   font - font to free
 
 =cut
 */
 
 int
-i_t1_destroy(int font_id) {
-  mm_log((1,"i_t1_destroy(font_id %d)\n",font_id));
+i_t1_destroy(i_t1_font_t font) {
+  int result;
+
+  i_mutex_lock(mutex);
+
+  mm_log((1,"i_t1_destroy(font %p (%d))\n", font, font->font_id));
 
   --t1_active_fonts;
 
-  return T1_DeleteFont(font_id);
+  result = T1_DeleteFont(font->font_id);
+  myfree(font);
+
+  i_mutex_unlock(mutex);
+
+  return result;
 }
 
 
@@ -144,13 +201,21 @@ Sets the antialiasing level of the t1 library.
 
    st - 0 =  NONE, 1 = LOW, 2 =  HIGH.
 
+Must be called with the mutex locked.
+
 =cut
 */
 
-void
+static void
 i_t1_set_aa(int st) {
   int i;
   unsigned long cst[17];
+
+  mm_log((1, "i_t1_set_aa(%d)\n", st));
+
+  if (t1_aa == st)
+    return;
+
   switch(st) {
   case 0:
     T1_AASetBitsPerPixel( 8 );
@@ -171,11 +236,13 @@ i_t1_set_aa(int st) {
     T1_AAHSetGrayValues( cst );
     mm_log((1,"setting T1 antialias to high\n"));
   }
+  
+  t1_aa = st;
 }
 
 
 /* 
-=item i_t1_cp(im, xb, yb, channel, fontnum, points, str, len, align)
+=item i_t1_cp(im, xb, yb, channel, fontnum, points, str, len, align,aa)
 
 Interface to text rendering into a single channel in an image
 
@@ -188,37 +255,60 @@ Interface to text rendering into a single channel in an image
    str     - string to render
    len     - string length
    align   - (0 - top of font glyph | 1 - baseline )
+   aa      - anti-aliasing level
 
 =cut
 */
 
 undef_int
-i_t1_cp(i_img *im,i_img_dim xb,i_img_dim yb,int channel,int fontnum,double points,char* str,size_t len,int align, int utf8, char const *flags) {
+i_t1_cp(i_t1_font_t font, i_img *im,i_img_dim xb,i_img_dim yb,int channel,double points,char* str,size_t len,int align, int utf8, char const *flags, int aa) {
   GLYPH *glyph;
   int xsize,ysize,x,y;
   i_color val;
   int mod_flags = t1_get_flags(flags);
+  int fontnum = font->font_id;
 
   unsigned int ch_mask_store;
   
-  if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); }
+  i_clear_error();
+
+  mm_log((1, "i_t1_cp(font %p (%d), im %p, (xb,yb)=" i_DFp ", channel %d, points %g, str %p, len %u, align %d, utf8 %d, flags '%s', aa %d)\n",
+         font, fontnum, im, i_DFcp(xb, yb), channel, points, str, (unsigned)len, align, utf8, flags, aa));
+
+  if (im == NULL) {
+    mm_log((1,"i_t1_cp: Null image in input\n"));
+    i_push_error(0, "null image");
+    return(0);
+  }
+
+  i_mutex_lock(mutex);
+
+  i_t1_set_aa(aa);
 
   if (utf8) {
     int worklen;
     char *work = t1_from_utf8(str, len, &worklen);
+    if (work == NULL) {
+      i_mutex_unlock(mutex);
+      return 0;
+    }
     glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
     myfree(work);
   }
   else {
     glyph=T1_AASetString( fontnum, str, len, 0, mod_flags, points, NULL);
   }
-  if (glyph == NULL)
+  if (glyph == NULL) {
+    t1_push_error();
+    i_push_error(0, "i_t1_cp: T1_AASetString failed");
+    i_mutex_unlock(mutex);
     return 0;
+  }
 
   mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
   mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
   mm_log((1," advanceX: %d  advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
-  mm_log((1,"bpp: %d\n",glyph->bpp));
+  mm_log((1,"bpp: %lu\n", (unsigned long)glyph->bpp));
   
   xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
   ysize=glyph->metrics.ascent-glyph->metrics.descent;
@@ -236,6 +326,9 @@ i_t1_cp(i_img *im,i_img_dim xb,i_img_dim yb,int channel,int fontnum,double point
   }
   
   im->ch_mask=ch_mask_store;
+
+  i_mutex_unlock(mutex);
+
   return 1;
 }
 
@@ -267,15 +360,27 @@ function to get a strings bounding box given the font id and sizes
 */
 
 int
-i_t1_bbox(int fontnum, double points,const char *str,size_t len, i_img_dim cords[6], int utf8,char const *flags) {
+i_t1_bbox(i_t1_font_t font, double points,const char *str,size_t len, i_img_dim *cords, int utf8,char const *flags) {
   BBox bbox;
   BBox gbbox;
   int mod_flags = t1_get_flags(flags);
   i_img_dim advance;
-  int space_position = T1_GetEncodingIndex(fontnum, "space");
+  int fontnum = font->font_id;
+  int space_position;
+
+  i_clear_error();
+
+  i_mutex_lock(mutex);
+
+  space_position = T1_GetEncodingIndex(fontnum, "space");
   
-  mm_log((1,"i_t1_bbox(fontnum %d,points %.2f,str '%.*s', len %d)\n",fontnum,points,len,str,len));
-  T1_LoadFont(fontnum);  /* FIXME: Here a return code is ignored - haw haw haw */ 
+  mm_log((1,"i_t1_bbox(font %p (%d),points %.2f,str '%.*s', len %u)\n",
+         font, fontnum,points,(int)len,str,(unsigned)len));
+  if (T1_LoadFont(fontnum) == -1) {
+    t1_push_error();
+    i_mutex_unlock(mutex);
+    return 0;
+  }
 
   if (len == 0) {
     /* len == 0 has special meaning to T1lib, but it means there's
@@ -287,6 +392,10 @@ i_t1_bbox(int fontnum, double points,const char *str,size_t len, i_img_dim cords
     if (utf8) {
       int worklen;
       char *work = t1_from_utf8(str, len, &worklen);
+      if (!work) {
+       i_mutex_unlock(mutex);
+       return 0;
+      }
       advance = T1_GetStringWidth(fontnum, work, worklen, 0, mod_flags);
       bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags);
       t1_fix_bbox(&bbox, work, worklen, advance, space_position);
@@ -300,7 +409,7 @@ i_t1_bbox(int fontnum, double points,const char *str,size_t len, i_img_dim cords
   }
   gbbox = T1_GetFontBBox(fontnum);
   
-  mm_log((1,"bbox: (%d,%d,%d,%d)\n",
+  mm_log((1,"bbox: (%d, %d, %d, %d, %d, %d)\n",
          (int)(bbox.llx*points/1000),
          (int)(gbbox.lly*points/1000),
          (int)(bbox.urx*points/1000),
@@ -322,12 +431,14 @@ i_t1_bbox(int fontnum, double points,const char *str,size_t len, i_img_dim cords
   cords[BBOX_RIGHT_BEARING] = 
     cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH];
 
+  i_mutex_unlock(mutex);
+
   return BBOX_RIGHT_BEARING+1;
 }
 
 
 /*
-=item i_t1_text(im, xb, yb, cl, fontnum, points, str, len, align)
+=item i_t1_text(im, xb, yb, cl, fontnum, points, str, len, align, utf8, flags, aa)
 
 Interface to text rendering in a single color onto an image
 
@@ -340,22 +451,43 @@ Interface to text rendering in a single color onto an image
    str     - char pointer to string to render
    len     - string length
    align   - (0 - top of font glyph | 1 - baseline )
+   utf8    - str is utf8
+   flags   - formatting flags
+   aa      - anti-aliasing level
 
 =cut
 */
 
 undef_int
-i_t1_text(i_img *im, i_img_dim xb, i_img_dim yb,const i_color *cl,int fontnum, double points,const char* str,size_t len,int align, int utf8, char const *flags) {
+i_t1_text(i_t1_font_t font, i_img *im, i_img_dim xb, i_img_dim yb,const i_color *cl, double points,const char* str,size_t len,int align, int utf8, char const *flags, int aa) {
   GLYPH *glyph;
   int xsize,ysize,y;
   int mod_flags = t1_get_flags(flags);
   i_render *r;
+  int fontnum = font->font_id;
 
-  if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); }
+  mm_log((1, "i_t1_text(font %p (%d), im %p, (xb,yb)=" i_DFp ", cl (%d,%d,%d,%d), points %g, str %p, len %u, align %d, utf8 %d, flags '%s', aa %d)\n",
+         font, fontnum, im, i_DFcp(xb, yb), cl->rgba.r, cl->rgba.g, cl->rgba.b, cl->rgba.a, points, str, (unsigned)len, align, utf8, flags, aa));
+
+  i_clear_error();
+
+  if (im == NULL) {
+    i_push_error(0, "null image");
+    mm_log((1,"i_t1_text: Null image in input\n"));
+    return(0);
+  }
+
+  i_mutex_lock(mutex);
+
+  i_t1_set_aa(aa);
 
   if (utf8) {
     int worklen;
     char *work = t1_from_utf8(str, len, &worklen);
+    if (!work) {
+      i_mutex_unlock(mutex);
+      return 0;
+    }
     glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
     myfree(work);
   }
@@ -363,13 +495,18 @@ i_t1_text(i_img *im, i_img_dim xb, i_img_dim yb,const i_color *cl,int fontnum, d
     /* T1_AASetString() accepts a char * not a const char */
     glyph=T1_AASetString( fontnum, (char *)str, len, 0, mod_flags, points, NULL);
   }
-  if (glyph == NULL)
+  if (glyph == NULL) {
+    mm_log((1, "T1_AASetString failed\n"));
+    t1_push_error();
+    i_push_error(0, "i_t1_text(): T1_AASetString failed");
+    i_mutex_unlock(mutex);
     return 0;
+  }
 
   mm_log((1,"metrics:  ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
   mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
   mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
-  mm_log((1,"bpp: %d\n",glyph->bpp));
+  mm_log((1,"bpp: %lu\n",(unsigned long)glyph->bpp));
   
   xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
   ysize=glyph->metrics.ascent-glyph->metrics.descent;
@@ -383,6 +520,8 @@ i_t1_text(i_img *im, i_img_dim xb, i_img_dim yb,const i_color *cl,int fontnum, d
     i_render_color(r, xb, yb+y, xsize, (unsigned char *)glyph->bits+y*xsize, cl);
   }
   i_render_delete(r);
+
+  i_mutex_unlock(mutex);
     
   return 1;
 }
@@ -467,16 +606,20 @@ Returns the number of characters that were checked.
 */
 
 int
-i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
+i_t1_has_chars(i_t1_font_t font, const char *text, size_t len, int utf8,
                char *out) {
   int count = 0;
+  int font_num = font->font_id;
   
-  mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %d, utf8 %d)\n", 
-          font_num, text, len, utf8));
+  i_mutex_lock(mutex);
+
+  mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %u, utf8 %d)\n", 
+          font_num, text, (unsigned)len, utf8));
 
   i_clear_error();
   if (T1_LoadFont(font_num)) {
     t1_push_error();
+    i_mutex_unlock(mutex);
     return 0;
   }
 
@@ -486,6 +629,7 @@ i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
       c = i_utf8_advance(&text, &len);
       if (c == ~0UL) {
         i_push_error(0, "invalid UTF8 character");
+       i_mutex_unlock(mutex);
         return 0;
       }
     }
@@ -512,11 +656,13 @@ i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
     ++count;
   }
 
+  i_mutex_unlock(mutex);
+
   return count;
 }
 
 /*
-=item i_t1_face_name(font_num, name_buf, name_buf_size)
+=item i_t1_face_name(font, name_buf, name_buf_size)
 
 Copies the face name of the given C<font_num> to C<name_buf>.  Returns
 the number of characters required to store the name (which can be
@@ -530,53 +676,69 @@ will be truncated.  name_buf will always be NUL termintaed.
 */
 
 int
-i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size) {
+i_t1_face_name(i_t1_font_t font, char *name_buf, size_t name_buf_size) {
   char *name;
+  int font_num = font->font_id;
+
+  i_mutex_lock(mutex);
 
   T1_errno = 0;
   if (T1_LoadFont(font_num)) {
     t1_push_error();
+    i_mutex_unlock(mutex);
     return 0;
   }
   name = T1_GetFontName(font_num);
 
   if (name) {
+    size_t len = strlen(name);
     strncpy(name_buf, name, name_buf_size);
     name_buf[name_buf_size-1] = '\0';
-    return strlen(name) + 1;
+    i_mutex_unlock(mutex);
+    return len + 1;
   }
   else {
     t1_push_error();
+    i_mutex_unlock(mutex);
     return 0;
   }
 }
 
 int
-i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf, 
+i_t1_glyph_name(i_t1_font_t font, unsigned long ch, char *name_buf, 
                  size_t name_buf_size) {
   char *name;
+  int font_num = font->font_id;
 
   i_clear_error();
   if (ch > 0xFF) {
     return 0;
   }
+
+  i_mutex_lock(mutex);
+
   if (T1_LoadFont(font_num)) {
     t1_push_error();
+    i_mutex_unlock(mutex);
     return 0;
   }
   name = T1_GetCharName(font_num, (unsigned char)ch);
   if (name) {
     if (strcmp(name, ".notdef")) {
+      size_t len = strlen(name);
       strncpy(name_buf, name, name_buf_size);
       name_buf[name_buf_size-1] = '\0';
-      return strlen(name) + 1;
+      i_mutex_unlock(mutex);
+      return len + 1;
     }
     else {
+      i_mutex_unlock(mutex);
       return 0;
     }
   }
   else {
     t1_push_error();
+    i_mutex_unlock(mutex);
     return 0;
   }
 }
@@ -594,103 +756,109 @@ t1_push_error(void) {
 
 #ifdef T1ERR_SCAN_FONT_FORMAT
   case T1ERR_SCAN_FONT_FORMAT:
-    i_push_error(T1ERR_SCAN_FONT_FORMAT, "SCAN_FONT_FORMAT"); 
+    i_push_error(T1ERR_SCAN_FONT_FORMAT, "Attempt to Load Multiple Master Font"); 
     break;
 #endif
 
 #ifdef T1ERR_SCAN_FILE_OPEN_ERR
   case T1ERR_SCAN_FILE_OPEN_ERR:
-    i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "SCAN_FILE_OPEN_ERR"); 
+    i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "Type 1 Font File Open Error"); 
     break;
 #endif
 
 #ifdef T1ERR_SCAN_OUT_OF_MEMORY
   case T1ERR_SCAN_OUT_OF_MEMORY:
-    i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "SCAN_OUT_OF_MEMORY"); 
+    i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "Virtual Memory Exceeded"); 
     break;
 #endif
 
 #ifdef T1ERR_SCAN_ERROR
   case T1ERR_SCAN_ERROR:
-    i_push_error(T1ERR_SCAN_ERROR, "SCAN_ERROR"); 
+    i_push_error(T1ERR_SCAN_ERROR, "Syntactical Error Scanning Font File"); 
     break;
 #endif
 
 #ifdef T1ERR_SCAN_FILE_EOF
   case T1ERR_SCAN_FILE_EOF:
-    i_push_error(T1ERR_SCAN_FILE_EOF, "SCAN_FILE_EOF"); 
+    i_push_error(T1ERR_SCAN_FILE_EOF, "Premature End of Font File Encountered"); 
     break;
 #endif
 
 #ifdef T1ERR_PATH_ERROR
   case T1ERR_PATH_ERROR:
-    i_push_error(T1ERR_PATH_ERROR, "PATH_ERROR"); 
+    i_push_error(T1ERR_PATH_ERROR, "Path Construction Error"); 
     break;
 #endif
 
 #ifdef T1ERR_PARSE_ERROR
   case T1ERR_PARSE_ERROR:
-    i_push_error(T1ERR_PARSE_ERROR, "PARSE_ERROR"); 
+    i_push_error(T1ERR_PARSE_ERROR, "Font is Corrupt"); 
     break;
 #endif
 
 #ifdef T1ERR_TYPE1_ABORT
   case T1ERR_TYPE1_ABORT:
-    i_push_error(T1ERR_TYPE1_ABORT, "TYPE1_ABORT"); 
+    i_push_error(T1ERR_TYPE1_ABORT, "Rasterization Aborted"); 
     break;
 #endif
 
 #ifdef T1ERR_INVALID_FONTID
   case T1ERR_INVALID_FONTID:
-    i_push_error(T1ERR_INVALID_FONTID, "INVALID_FONTID"); 
+    i_push_error(T1ERR_INVALID_FONTID, "Font ID Invalid in this Context"); 
     break;
 #endif
 
 #ifdef T1ERR_INVALID_PARAMETER
   case T1ERR_INVALID_PARAMETER:
-    i_push_error(T1ERR_INVALID_PARAMETER, "INVALID_PARAMETER"); 
+    i_push_error(T1ERR_INVALID_PARAMETER, "Invalid Argument in Function Call"); 
     break;
 #endif
 
 #ifdef T1ERR_OP_NOT_PERMITTED
   case T1ERR_OP_NOT_PERMITTED:
-    i_push_error(T1ERR_OP_NOT_PERMITTED, "OP_NOT_PERMITTED"); 
+    i_push_error(T1ERR_OP_NOT_PERMITTED, "Operation not Permitted"); 
     break;
 #endif
 
 #ifdef T1ERR_ALLOC_MEM
   case T1ERR_ALLOC_MEM:
-    i_push_error(T1ERR_ALLOC_MEM, "ALLOC_MEM"); 
+    i_push_error(T1ERR_ALLOC_MEM, "Memory Allocation Error"); 
     break;
 #endif
 
 #ifdef T1ERR_FILE_OPEN_ERR
   case T1ERR_FILE_OPEN_ERR:
-    i_push_error(T1ERR_FILE_OPEN_ERR, "FILE_OPEN_ERR"); 
+    i_push_error(T1ERR_FILE_OPEN_ERR, "Error Opening File"); 
     break;
 #endif
 
 #ifdef T1ERR_UNSPECIFIED
   case T1ERR_UNSPECIFIED:
-    i_push_error(T1ERR_UNSPECIFIED, "UNSPECIFIED"); 
+    i_push_error(T1ERR_UNSPECIFIED, "Unspecified T1Lib Error"); 
     break;
 #endif
 
 #ifdef T1ERR_NO_AFM_DATA
   case T1ERR_NO_AFM_DATA:
-    i_push_error(T1ERR_NO_AFM_DATA, "NO_AFM_DATA"); 
+    i_push_error(T1ERR_NO_AFM_DATA, "Missing AFM Data"); 
     break;
 #endif
 
 #ifdef T1ERR_X11
   case T1ERR_X11:
-    i_push_error(T1ERR_X11, "X11"); 
+    i_push_error(T1ERR_X11, "X11 Interface Error"); 
     break;
 #endif
 
 #ifdef T1ERR_COMPOSITE_CHAR
   case T1ERR_COMPOSITE_CHAR:
-    i_push_error(T1ERR_COMPOSITE_CHAR, "COMPOSITE_CHAR"); 
+    i_push_error(T1ERR_COMPOSITE_CHAR, "Missing Component of Composite Character"); 
+    break;
+#endif
+
+#ifdef T1ERR_SCAN_ENCODING
+  case T1ERR_SCAN_ENCODING:
+    i_push_error(T1ERR_SCAN_ENCODING, "Error Scanning Encoding File"); 
     break;
 #endif