"Fossies" - the Fresh Open Source Software Archive

Member "PDFlib-Lite-7.0.5p3/libs/pdflib/p_type1.c" (6 Jun 2012, 13131 Bytes) of package /linux/misc/old/PDFlib-Lite-7.0.5p3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "p_type1.c" see the Fossies "Dox" file reference documentation.

    1 /*---------------------------------------------------------------------------*
    2  |              PDFlib - A library for generating PDF on the fly             |
    3  +---------------------------------------------------------------------------+
    4  | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
    5  +---------------------------------------------------------------------------+
    6  |                                                                           |
    7  |    This software is subject to the PDFlib license. It is NOT in the       |
    8  |    public domain. Extended versions and commercial licenses are           |
    9  |    available, please check http://www.pdflib.com.                         |
   10  |                                                                           |
   11  *---------------------------------------------------------------------------*/
   12 
   13 /* $Id: p_type1.c,v 1.93.2.30 2010/04/23 09:47:22 kurt Exp $
   14  *
   15  * PDFlib Type1 font handling routines
   16  *
   17  */
   18 
   19 
   20 #include "p_intern.h"
   21 #include "p_font.h"
   22 
   23 #include "pc_ctype.h"
   24 #include "pc_strconst.h"
   25 #include "pc_string.h"
   26 
   27 
   28 /* Type 1 font portions: ASCII, encrypted, zeros */
   29 typedef enum
   30 {
   31     t1_ascii,
   32     t1_encrypted,
   33     t1_zeros,
   34     t1_eof
   35 }
   36 pdf_t1portion;
   37 
   38 static const pdc_keyconn pdf_t1portion_keylist[] =
   39 {
   40     {"ascii",      t1_ascii},
   41     {"encrypted",  t1_encrypted},
   42     {"zeros",      t1_zeros}
   43 };
   44 
   45 typedef struct
   46 {
   47     pdf_t1portion  portion;
   48     size_t         length[4];
   49     pdc_file      *fontfile;
   50     pdc_byte      *img;            /* in-core Type1 font file image   */
   51     pdc_byte      *end;            /* first byte above image buf   */
   52     pdc_byte      *pos;            /* current "file" position      */
   53 }
   54 t1_private_data;
   55 
   56 #define PFA_TESTBYTE    4
   57 
   58 #define PDF_CURRENTFILE "currentfile eexec"
   59 
   60 
   61 /* ---------------------------- General platforms --------------------------- */
   62 
   63 
   64 /*
   65  * PFA files are assumed to be encoded in host format. Therefore
   66  * we must use literal strings and characters for interpreting the
   67  * font file.
   68  */
   69 
   70 static int
   71 PFA_data_fill(PDF *p, PDF_data_source *src)
   72 {
   73     static const char *fn = "PFA_data_fill";
   74     pdc_bool logg6 = pdc_logg_is_enabled(p->pdc, 6, trc_font);
   75 #ifndef PDFLIB_EBCDIC
   76     static const char HexToBin['F' - '0' + 1] = {
   77         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
   78         0, 10, 11, 12, 13, 14, 15
   79     };
   80 #else
   81 #endif
   82     char *s, *c;
   83     int i;
   84     int len;
   85     t1_private_data *t1;
   86     pdf_t1portion t1portion;
   87 
   88     t1 = (t1_private_data *) src->private_data;
   89 
   90     if (t1->portion == t1_eof)
   91         return pdc_false;
   92 
   93     if (src->buffer_start == NULL)
   94     {
   95         src->buffer_start = (pdc_byte *)
   96                                 pdc_malloc(p->pdc, PDC_BUFSIZE + 1, fn);
   97         src->buffer_length = PDC_BUFSIZE;
   98     }
   99 
  100     if (logg6)
  101         pdc_logg(p->pdc, "\t\t\tdata fill: portion=%s\n",
  102                  pdc_get_keyword(t1->portion, pdf_t1portion_keylist));
  103 
  104     s = pdc_fgetline((char *) src->buffer_start, PDC_BUFSIZE, t1->fontfile);
  105     if (s == NULL)
  106         return pdc_false;
  107 
  108     /* set unix line end */
  109     len = (int) strlen(s);
  110     s[len] = '\n';
  111     len++;
  112     s[len] = 0;
  113 
  114     /* check for line of zeros: set t1_zero flag if found */
  115     if (*s == '0')
  116     {
  117         for (i = 0; s[i] == '0'; i++)
  118         {
  119             /* */ ;
  120         }
  121         if (s[i] == '\n')
  122         {
  123             t1->portion = t1_zeros;
  124 
  125             if (logg6)
  126                 pdc_logg(p->pdc, "\t\t\tlinefeed detected: set portion %s\n",
  127                          pdc_get_keyword(t1->portion,
  128                                          pdf_t1portion_keylist));
  129         }
  130     }
  131 
  132     /* check whether font data portion follows: set t1_encrypted flag later */
  133     t1portion = t1->portion;
  134     if (t1->portion != t1_encrypted &&
  135         !strncmp((const char *)s, PDF_CURRENTFILE, strlen(PDF_CURRENTFILE)))
  136     {
  137         t1portion = t1_encrypted;
  138 
  139         if (logg6)
  140             pdc_logg(p->pdc, "\t\t\t\"%s\" detected\n", PDF_CURRENTFILE);
  141     }
  142 
  143     src->next_byte = src->buffer_start;
  144 
  145     switch (t1->portion)
  146     {
  147         case t1_ascii:
  148         {
  149             t1->length[1] += (size_t) len;
  150             src->bytes_available = (size_t) len;
  151         }
  152         break;
  153 
  154         case t1_encrypted:
  155         {
  156             src->bytes_available = 0;
  157 
  158             /* Convert to upper case for safe binary conversion */
  159             for (c = s; *c != '\n'; c++)
  160             {
  161                 *c = (char) pdc_toupper(*c);
  162             }
  163 
  164             /* convert ASCII to binary in-place */
  165             for (i = 0; s[i] != '\n'; i += 2)
  166             {
  167                 if ((!pdc_isxdigit(s[i]) && !pdc_isspace(s[i])) ||
  168                     (!pdc_isxdigit(s[i+1]) && !pdc_isspace(s[i+1])))
  169                 {
  170                     pdc_fclose(t1->fontfile);
  171                     pdc_error(p->pdc, PDF_E_FONT_CORRUPT_PFA, 0, 0, 0, 0);
  172                 }
  173                 s[i/2] = (char) (16*HexToBin[s[i]-'0'] + HexToBin[s[i+1]-'0']);
  174 
  175                 src->bytes_available++;
  176             }
  177             t1->length[2] += src->bytes_available;
  178         }
  179         break;
  180 
  181         case t1_zeros:
  182         {
  183             t1->length[3] += (size_t) len;
  184             src->bytes_available = (size_t) len;
  185         }
  186         break;
  187 
  188         default:
  189         break;
  190     }
  191 
  192     t1->portion = t1portion;
  193 
  194     if (logg6)
  195         pdc_logg(p->pdc, "\t\t\tset portion %s\n",
  196                  pdc_get_keyword(t1->portion, pdf_t1portion_keylist));
  197     return pdc_true;
  198 }
  199 
  200 #define PFB_MARKER      0x80
  201 #define PFB_ASCII       1
  202 #define PFB_BINARY      2
  203 #define PFB_EOF         3
  204 
  205 static int
  206 pdf_t1getc(t1_private_data *t1)
  207 {
  208     int val;
  209 
  210     if (t1->fontfile)
  211     {
  212         return pdc_fgetc(t1->fontfile);
  213     }
  214     val = (int) *t1->pos;
  215     t1->pos++;
  216 
  217     return val;
  218 }
  219 
  220 static pdc_bool
  221 pdf_read_pfb_segment(PDF *p, PDF_data_source *src, t1_private_data *t1, int i)
  222 {
  223     static const char *fn = "pdf_read_pfb_segment";
  224     size_t length, len;
  225 
  226     length  = (size_t) (pdf_t1getc(t1) & 0xff);
  227     length |= (size_t) (pdf_t1getc(t1) & 0xff) << 8;
  228     length |= (size_t) (pdf_t1getc(t1) & 0xff) << 16;
  229     length |= (size_t) (pdf_t1getc(t1) & 0xff) << 24;
  230 
  231     pdc_logg_cond(p->pdc, 5, trc_font,
  232         " and length x%04X", length);
  233 
  234     if (src->buffer_start)
  235         pdc_free(p->pdc, (void *) src->buffer_start);
  236     src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, length, fn);
  237 
  238     if (t1->fontfile)
  239     {
  240         len = pdc_fread(src->buffer_start, 1, length, t1->fontfile);
  241     }
  242     else
  243     {
  244         len = length;
  245         if (t1->pos + len > t1->end)
  246             len = (unsigned int)(t1->end - t1->pos);
  247         memcpy(src->buffer_start, t1->pos, len);
  248         t1->pos += len;
  249     }
  250 
  251     t1->length[i] = len;
  252     src->next_byte = src->buffer_start;
  253     src->bytes_available = len;
  254 
  255     return (len != length) ? pdc_false : pdc_true;
  256 }
  257 
  258 static pdc_bool
  259 PFB_data_fill(PDF *p, PDF_data_source *src)
  260 {
  261     pdc_bool logg = pdc_logg_is_enabled(p->pdc, 5, trc_font);
  262     t1_private_data *t1 = (t1_private_data *) src->private_data;
  263     pdc_bool succ = pdc_false;
  264     pdc_byte c, type;
  265     int i;
  266 
  267     c = (pdc_byte) pdf_t1getc(t1);
  268 
  269     if (c == PFB_MARKER)
  270     {
  271         type = (pdc_byte) pdf_t1getc(t1);
  272 
  273         if (logg)
  274             pdc_logg(p->pdc, "\t\t\treading segment of type x%02X", type);
  275 
  276         for (i = 1; i < 4; i++)
  277         {
  278             if (t1->length[i] == (size_t) 0)
  279             {
  280                 succ = pdf_read_pfb_segment(p, src, t1, i);
  281                 break;
  282             }
  283         }
  284 
  285         if (i < 4)
  286         {
  287             if (succ)
  288             {
  289                 if (logg)
  290                     pdc_logg(p->pdc, " successful\n");
  291                 return pdc_true;
  292             }
  293         }
  294         else
  295         {
  296             if (logg)
  297                 pdc_logg(p->pdc, " (EOF)\n");
  298             return pdc_false;
  299         }
  300     }
  301 
  302     if (logg)
  303         pdc_logg(p->pdc, " unsuccessful\n");
  304 
  305     if (t1->fontfile)
  306         pdc_fclose(t1->fontfile);
  307     pdc_error(p->pdc, PDF_E_FONT_CORRUPT, "PFB", "", 0, 0);
  308 
  309     return pdc_false;
  310 }
  311 
  312 static void
  313 t1data_terminate(PDF *p, PDF_data_source *src)
  314 {
  315     pdc_free(p->pdc, (void *) src->buffer_start);
  316 }
  317 
  318 static void
  319 t1data_init(PDF *p, PDF_data_source *src)
  320 {
  321     t1_private_data *t1;
  322 
  323     (void) p;
  324 
  325     t1 = (t1_private_data *) src->private_data;
  326 
  327     t1->portion = t1_ascii;
  328     t1->length[1] = (size_t) 0;
  329     t1->length[2] = (size_t) 0;
  330     t1->length[3] = (size_t) 0;
  331 
  332     src->buffer_start = NULL;
  333 }
  334 
  335 
  336 pdc_bool
  337 pdf_t1open_fontfile(PDF *p, pdf_font *font, const char *filename,
  338                     PDF_data_source *t1src, pdc_bool requested)
  339 {
  340     static const char *fn = "pdf_t1open_fontfile";
  341     t1_private_data  *t1 = NULL;
  342     pdc_file *fp = NULL;
  343     const char *stemp = NULL;
  344     pdc_byte magic[PFA_TESTBYTE];
  345     char fullname[PDC_FILENAMELEN];
  346     int fflags = PDC_FILE_BINARY;
  347     pdc_bool ispfb = pdc_true;
  348 
  349     if (filename)
  350     {
  351         pdc_bool retval = pdc_true;
  352         pdc_bool fnamegiven = (strcmp(filename, FNT_MISSING_FILENAME) == 0) ?
  353                               pdc_false : pdc_true;
  354         (void) retval;
  355 
  356         if (fnamegiven)
  357         {
  358             fp = pdc_fsearch_fopen(p->pdc, filename, fullname,
  359                                    "PostScript Type1 ", fflags);
  360             if (fp == NULL)
  361             {
  362                 if (t1src)
  363                     PDC_RETHROW(p->pdc);
  364                 return pdc_check_fopen_errmsg(p->pdc, requested);
  365             }
  366 
  367             pdc_logg_cond(p->pdc, 1, trc_font,
  368                 "\tLoading PostScript Type1 fontfile \"%s\":\n", fullname);
  369         }
  370 
  371     }
  372 
  373     if (fp)
  374     {
  375         pdc_fread(magic, 1, PFA_TESTBYTE, fp);
  376         stemp = filename;
  377     }
  378     else if (font->ft.img)
  379     {
  380         strncpy((char *) magic, (const char *)font->ft.img, PFA_TESTBYTE);
  381         stemp = font->ft.name;
  382     }
  383 
  384     /* try to identify PFA files */
  385     if (magic[0] != PFB_MARKER)
  386     {
  387         char startsequ[PFA_TESTBYTE + 1];
  388 
  389         strcpy(startsequ, FNT_PFA_STARTSEQU);
  390 
  391         if (strncmp((const char *) magic, startsequ, PFA_TESTBYTE))
  392         {
  393             if (fp)
  394                 pdc_fclose(fp);
  395             pdc_set_errmsg(p->pdc, PDF_E_T1_NOFONT, stemp, 0, 0, 0);
  396             if (t1src)
  397                 PDC_RETHROW(p->pdc);
  398             return pdc_false;
  399         }
  400         ispfb = pdc_false;
  401     }
  402 
  403     pdc_logg_cond(p->pdc, 1, trc_font,
  404         "\tPostScript Type1 font of format \"%s\" detected\n",
  405         ispfb ? "PFB" : "PFA");
  406 
  407     if (t1src)
  408     {
  409         t1src->private_data = (unsigned char *)
  410                 pdc_malloc(p->pdc, sizeof(t1_private_data), fn);
  411         t1 = (t1_private_data *) t1src->private_data;
  412 
  413         if (filename)
  414         {
  415             pdc_fclose(fp);
  416             if (ispfb)
  417             {
  418                 t1->fontfile =
  419                     pdc_fsearch_fopen(p->pdc, fullname, NULL, "PFB ", fflags);
  420             }
  421             else
  422             {
  423                 t1->fontfile =
  424                     pdc_fsearch_fopen(p->pdc, fullname, NULL, "PFA ",
  425                                       PDC_FILE_TEXT);
  426             }
  427 
  428             if (t1->fontfile == NULL)
  429                 PDC_RETHROW(p->pdc);
  430         }
  431         else if (font->ft.img)
  432         {
  433             /* only for virtual PFB files */
  434             t1->fontfile = NULL;
  435             t1->img = font->ft.img;
  436             t1->pos = font->ft.img;
  437             t1->end = font->ft.img + font->ft.filelen;
  438         }
  439 
  440         t1src->init = t1data_init;
  441         t1src->fill = ispfb ? PFB_data_fill : PFA_data_fill;
  442         t1src->terminate = t1data_terminate;
  443     }
  444     else if (fp != NULL)
  445     {
  446         if (pdc_file_isvirtual(fp) == pdc_true)
  447         {
  448             if (ispfb)
  449                 font->ft.img =
  450                     (pdc_byte *) pdc_freadall(fp, &font->ft.filelen, NULL);
  451             font->ft.imgname = pdc_strdup(p->pdc, fullname);
  452             pdc_lock_pvf(p->pdc, font->ft.imgname);
  453         }
  454         font->ft.filename = pdc_strdup(p->pdc, fullname);
  455         pdc_fclose(fp);
  456     }
  457 
  458     return pdc_true;
  459 }
  460 
  461 pdc_bool
  462 pdf_make_t1src (PDF *p, pdf_font *font, PDF_data_source *t1src)
  463 {
  464     return pdf_t1open_fontfile(p, font, font->filename, t1src, pdc_true);
  465 }
  466 
  467 void
  468 pdf_put_length_objs(PDF *p, PDF_data_source *t1src,
  469                     pdc_id length1_id, pdc_id length2_id, pdc_id length3_id)
  470 {
  471     pdc_begin_obj(p->out, length1_id);              /* Length1 object */
  472     pdc_printf(p->out, "%ld\n",
  473             (long) ((t1_private_data *) t1src->private_data)->length[1]);
  474     pdc_end_obj(p->out);
  475 
  476     pdc_begin_obj(p->out, length2_id);              /* Length2 object */
  477     pdc_printf(p->out, "%ld\n",
  478             (long) ((t1_private_data *) t1src->private_data)->length[2]);
  479     pdc_end_obj(p->out);
  480 
  481     pdc_begin_obj(p->out, length3_id);              /* Length3 object */
  482     pdc_printf(p->out, "%ld\n",
  483             (long) ((t1_private_data *) t1src->private_data)->length[3]);
  484     pdc_end_obj(p->out);
  485 
  486     if (((t1_private_data *) t1src->private_data)->fontfile)
  487         pdc_fclose(((t1_private_data *) t1src->private_data)->fontfile);
  488 
  489     pdc_free(p->pdc, (void *) t1src->private_data);
  490 }