Back to index

tetex-bin  3.0
encodings.c
Go to the documentation of this file.
00001 
00002 #include <stdio.h>
00003 #include "pdflimits.h"
00004 #include "pdfobj.h"
00005 #include "mem.h"
00006 #include "error.h"
00007 #include "mfileio.h"
00008 #include "pdfparse.h"
00009 #include "encodings.h"
00010 
00011 
00012 static unsigned char verbose = 0;
00013 
00014 void encoding_set_verbose(void)
00015 {
00016   if (verbose < 255) {
00017     verbose += 1;
00018   }
00019 }
00020 
00021 struct encoding {
00022   char *enc_name;
00023   /* The following array isn't very efficient. It is constructed
00024      by peeling the names from the encoding object.  It makes
00025      it easier to construct an array in this format when the
00026      encoding must be obtained directly from the PFB file */
00027   char *glyphs[256];
00028   pdf_obj *encoding_ref;
00029 } *encodings;
00030 int num_encodings = 0, max_encodings=0;
00031 
00032 #include "winansi.h"
00033 
00034 pdf_obj *find_encoding_differences (pdf_obj *encoding)
00035 {
00036   char filling = 0;
00037   int i;
00038   pdf_obj *result = pdf_new_array ();
00039   pdf_obj *tmp;
00040   for (i=0; i<256; i++) {
00041     tmp = pdf_get_array (encoding, i);
00042     if (tmp == NULL || tmp -> type != PDF_NAME) {
00043       ERROR ("Encoding file may be incorrect\n");
00044     }
00045     if (!strcmp (winansi_encoding[i],
00046                pdf_name_value(tmp)))
00047       filling = 0;
00048     else{
00049       if (!filling)
00050        pdf_add_array (result, pdf_new_number (i));
00051       filling = 1;
00052       pdf_add_array (result, pdf_link_obj(tmp));
00053     }
00054   }
00055   return result;
00056 }
00057 
00058 pdf_obj *make_differences_encoding (pdf_obj *encoding)
00059 {
00060   int i;
00061   int skipping = 1;
00062   pdf_obj *tmp, *result = pdf_new_array ();
00063   for (i=0; i<256; i++) {
00064     tmp = pdf_get_array (encoding, i);
00065     if (tmp && tmp -> type == PDF_NAME) {
00066       if (strcmp (".notdef", pdf_name_value (tmp))) { /* If not
00067                                                   .notdef */
00068        if (skipping) {
00069          pdf_add_array (result, pdf_new_number (i));
00070        }
00071        pdf_add_array (result, pdf_link_obj(tmp));
00072          skipping = 0;
00073       } else {
00074        skipping = 1;
00075       }
00076     } else {
00077       ERROR ("Encoding file may be incorrect\n");
00078     }
00079   }
00080   return result;
00081 }
00082 
00083 static void save_glyphs (char **glyph, pdf_obj *encoding)
00084 {
00085   int i;
00086   char *glyph_name;
00087   for (i=0; i<256; i++) {
00088     glyph_name = pdf_string_value (pdf_get_array(encoding, i));
00089     glyph[i] = NEW (strlen(glyph_name)+1, char);
00090     strcpy (glyph[i], glyph_name);
00091   }
00092 }
00093 
00094 int get_encoding (const char *enc_name)
00095 {
00096   FILE *encfile = NULL;
00097   char *full_enc_filename, *tmp;
00098   pdf_obj *result, *result_ref;
00099   long filesize;
00100   int i;
00101   /* See if we already have this saved */
00102   for (i=0; i<num_encodings; i++)
00103     if (!strcmp (enc_name, encodings[i].enc_name))
00104       return i;
00105   /* Guess not.. */
00106   /* Try base name before adding .enc.  Someday maybe kpse will do
00107      this */
00108   strcpy (tmp = NEW (strlen(enc_name)+5, char), enc_name);
00109   strcat (tmp, ".enc");
00110   if ((full_enc_filename = kpse_find_file (enc_name,
00111                                       kpse_enc_format,
00112                                       1)) == NULL &&
00113       (full_enc_filename = kpse_find_file (enc_name,
00114                                       kpse_program_text_format,
00115                                       1)) == NULL &&
00116       (full_enc_filename = kpse_find_file (tmp,
00117                                       kpse_enc_format,
00118                                       1)) == NULL &&
00119       (full_enc_filename = kpse_find_file (tmp,
00120                                       kpse_program_text_format,
00121                                       1)) == NULL) {
00122     sprintf (work_buffer, "Can't find encoding file: %s", enc_name) ;
00123     ERROR (work_buffer);
00124   }
00125   RELEASE (tmp);
00126   if ((encfile = MFOPEN (full_enc_filename, FOPEN_R_MODE)) == NULL ||
00127       (filesize = file_size (encfile)) == 0) {
00128     sprintf (work_buffer, "Error opening encoding file: %s", enc_name) ;
00129     ERROR (work_buffer);
00130   }
00131   if (verbose == 1)
00132     fprintf (stderr, "(ENC:%s", enc_name);
00133   if (verbose > 1)
00134     fprintf (stderr, "(ENC:%s", full_enc_filename);
00135   {  /* Got one and opened it */
00136     char *buffer, *start, *end, *junk_ident;
00137     pdf_obj *junk_obj, *encoding, *differences;
00138     buffer = NEW (filesize, char); 
00139     fread (buffer, sizeof (char), filesize, encfile);
00140     MFCLOSE (encfile);
00141     start = buffer;
00142     end = buffer + filesize;
00143     start[filesize-1] = 0;
00144     skip_white (&start, end);
00145     while (start < end && *start != '[') {
00146       if ((junk_ident = parse_ident (&start, end)) != NULL)
00147        RELEASE (junk_ident);
00148       else if ((junk_obj = parse_pdf_object (&start, end)) != NULL)
00149        pdf_release_obj (junk_obj);
00150       skip_white(&start, end);
00151     }
00152     if (start >= end ||
00153        (encoding = parse_pdf_array (&start, end)) == NULL) {
00154       fprintf (stderr, "%s: ", enc_name);
00155       ERROR ("Can't find an encoding in this file!\n");
00156     }
00157     RELEASE (buffer);
00158     /* Done reading file */
00159     if (verbose) {
00160       fprintf (stderr, ")");
00161     }
00162     /*    differences = find_encoding_differences (encoding); */
00163     differences = make_differences_encoding (encoding);
00164     /* Put the glyph names into a conventional array */
00165     if (num_encodings >= max_encodings) {
00166        max_encodings += MAX_ENCODINGS;
00167        encodings = RENEW (encodings, max_encodings, struct encoding);
00168     }
00169     save_glyphs (encodings[num_encodings].glyphs, encoding);
00170     pdf_release_obj (encoding);
00171     result = pdf_new_dict();
00172     pdf_add_dict (result, pdf_new_name ("Type"),
00173                 pdf_new_name ("Encoding"));
00174     /* Some software doesn't like BaseEncoding key (e.g., FastLane) 
00175        so this code is commented out for the moment.  It may reemerge in the
00176        future */
00177     /*    pdf_add_dict (result, pdf_new_name ("BaseEncoding"),
00178          pdf_new_name ("WinAnsiEncoding")); */
00179     pdf_add_dict (result, pdf_new_name ("Differences"),
00180                 differences);
00181   }
00182   {
00183     result_ref = pdf_ref_obj (result);
00184     pdf_release_obj (result);
00185     encodings[num_encodings].encoding_ref = result_ref;
00186     encodings[num_encodings].enc_name = NEW (strlen(enc_name)+1, char);
00187     strcpy (encodings[num_encodings].enc_name, enc_name);
00188     return num_encodings++;
00189   }
00190 }
00191 
00192 pdf_obj *encoding_ref (int encoding_id) 
00193 {
00194   pdf_obj *result = NULL;
00195   if (encoding_id >=0 && encoding_id < num_encodings) {
00196     result = pdf_link_obj (encodings[encoding_id].encoding_ref);
00197   }
00198   return result;
00199 }
00200 
00201 void encoding_flush_all (void) 
00202 {
00203   int i, j;
00204   for (i=0; i<num_encodings; i++) {
00205     RELEASE (encodings[i].enc_name);
00206     pdf_release_obj (encodings[i].encoding_ref);
00207     /* Release glyph names for this encoding */
00208     for (j=0; j<256; j++) {
00209       RELEASE ((encodings[i].glyphs)[j]);
00210     }
00211   }
00212   if (encodings)
00213     RELEASE (encodings);
00214 }
00215 
00216 char *encoding_glyph (int encoding_id, unsigned code) 
00217 {
00218   char *result = NULL;
00219   if (encoding_id >= 0 && encoding_id < num_encodings &&
00220       code < 256) {
00221     result = (encodings[encoding_id].glyphs)[code];
00222   }
00223   return result;
00224 }