Back to index

tetex-bin  3.0
writeenc.c
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
00003 
00004 This file is part of pdfTeX.
00005 
00006 pdfTeX is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 pdfTeX is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with pdfTeX; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 $Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writeenc.c#10 $
00021 */
00022 
00023 #include "ptexlib.h"
00024 #include "avlstuff.h"
00025 
00026 static const char perforce_id[] = 
00027     "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writeenc.c#10 $";
00028 
00029 void read_enc(enc_entry *e)
00030 {
00031     assert(e != NULL);
00032     if (e->loaded)
00033         return;
00034     load_enc(e->name, e->glyph_names);
00035     e->loaded = true;
00036 }
00037 
00038 /* write_enc is used to write either external encoding (given in map file) or
00039  * internal encoding (read from the font file); when glyph_names is NULL
00040  * the 2nd argument is a pointer to the encoding entry; otherwise the 3rd is 
00041  * the object number of the Encoding object
00042  */
00043 void write_enc(char **glyph_names, enc_entry *e, integer eobjnum)
00044 {
00045     boolean is_notdef;
00046     int i;
00047     char **g;
00048     if (glyph_names == NULL) {
00049         assert(e != NULL);
00050         if (e->objnum != 0) /* the encoding has been written already */
00051             return;
00052         pdfnewdict(0, 0);
00053         e->objnum = objptr;
00054         g = e->glyph_names;
00055     }
00056     else {
00057         pdfbegindict(eobjnum);
00058         g = glyph_names;
00059     }
00060     pdf_printf("/Type /Encoding\n/Differences [ 0 /%s", g[0]);
00061     is_notdef = (g[0] == notdef);
00062     for (i = 1; i <= MAX_CHAR_CODE; i++) {
00063         if (g[i] == notdef) {
00064             if (!is_notdef) {
00065                 pdf_printf(" %i/%s", i, notdef);
00066                 is_notdef = true;
00067             }
00068         }
00069         else {
00070             if (is_notdef) {
00071                 pdf_printf(" %i", i);
00072                 is_notdef = false;
00073             }
00074             pdf_printf("/%s", g[i]);
00075         }
00076     }
00077     pdf_puts("]\n");
00078     pdfenddict();
00079 }
00080 
00081 /**********************************************************************/
00082 /* All encoding entries go into linked list. The named ones (s != NULL)
00083 are also registered into AVL tree for quicker search. */
00084 
00085 typedef struct encstruct_ {
00086     enc_entry entry;
00087     struct encstruct_ *next;
00088 } encstruct;
00089 
00090 static encstruct *epstart = NULL;  /* start of linked list */
00091 
00092 /* handle named encodings through AVL tree */
00093 
00094 struct avl_table *enc_tree = NULL;
00095 
00096 /* AVL sort enc_entry into enc_tree by name */
00097 
00098 static int comp_enc_entry(const void *pa, const void *pb, void *p)
00099 {
00100     return strcmp(((const enc_entry *) pa)->name,
00101                 ((const enc_entry *) pb)->name);
00102 }
00103 
00104 enc_entry *add_enc(char *s)
00105 {                           /* built-in encodings have s == NULL */
00106     int i;
00107     enc_entry *enc_ptr, etmp;
00108     static encstruct *ep;   /* pointer into linked list of encodings */
00109     void **aa;
00110 
00111     if (enc_tree == NULL) {
00112        enc_tree = avl_create(comp_enc_entry, NULL, &avl_xallocator);
00113        assert(enc_tree != NULL);
00114     }
00115     if (s != NULL) {
00116        etmp.name = s;
00117        enc_ptr = (enc_entry *) avl_find(enc_tree, &etmp);
00118        if (enc_ptr != NULL) /* encoding already registered */
00119            return enc_ptr;
00120     }
00121     if (epstart == NULL) {
00122        epstart = xtalloc(1, encstruct);
00123        ep = epstart;
00124     } else {
00125        ep->next = xtalloc(1, encstruct);
00126        ep = ep->next;
00127     }
00128     ep->next = NULL;
00129     enc_ptr = &(ep->entry);
00130     if (s != NULL) {
00131        enc_ptr->name = xstrdup(s);
00132        aa = avl_probe(enc_tree, enc_ptr);
00133        assert(aa != NULL);
00134     } else
00135        enc_ptr->name = NULL;
00136     enc_ptr->loaded = false;
00137     enc_ptr->updated = false;
00138     enc_ptr->firstfont = getnullfont();
00139     enc_ptr->objnum = 0;
00140     enc_ptr->glyph_names = xtalloc(MAX_CHAR_CODE + 1, char *);
00141     for (i = 0; i <= MAX_CHAR_CODE; i++)
00142        enc_ptr->glyph_names[i] = (char *) notdef;
00143 
00144     return enc_ptr;
00145 }
00146 
00147 /**********************************************************************/
00148 
00149 /* get encoding for map entry fm. When encoding vector is not given, try to
00150  * get it from T1 font file, in this case t1_read_enc sets the font being
00151  * reencoded, so next calls for the same entry doesn't cause reading the font
00152  * again
00153  */
00154 boolean get_enc(fm_entry *fm)
00155 {
00156     int i;
00157     char **glyph_names;
00158     if (is_reencoded(fm)) { /* external encoding vector available */
00159         read_enc(fm->encoding);
00160         return true;
00161     }
00162     if (!is_t1fontfile(fm)) /* get built-in encoding for T1 fonts only */
00163         return false;
00164     if (t1_read_enc(fm)) { /* encoding read into t1_builtin_glyph_names */
00165         fm->encoding = add_enc(NULL);
00166         glyph_names = (fm->encoding)->glyph_names;
00167         for (i = 0; i <= MAX_CHAR_CODE; i++)
00168             glyph_names[i] = t1_builtin_glyph_names[i];
00169         (fm->encoding)->loaded = true;
00170         return true;
00171     }
00172     return false;
00173 }
00174 
00175 /* check whether an encoding contains indexed glyph in form "/index123" */
00176 /* boolean indexed_enc(fm_entry *fm) */
00177 /* { */
00178 /*     char **s = enc_array[fm->encoding].glyph_names; */
00179 /*     int i, n; */
00180 /*     for (i = 0; i <= MAX_CHAR_CODE; i++, s++) */
00181 /*         if (*s != NULL && *s != notdef &&  */
00182 /*             sscanf(*s,  INDEXED_GLYPH_PREFIX "%i", &n) == 1) */
00183 /*                 return true; */
00184 /*     return false; */
00185 /* } */
00186 
00187 void setcharmap(internalfontnumber f)
00188 {
00189     fm_entry *fm;
00190     enc_entry *e;
00191     char **glyph_names;
00192     int i, k;
00193     if (pdfmovechars == 0 || fontbc[f] > 32 || !hasfmentry(f))
00194         return;
00195     if (fontec[f] < 128) {
00196         for (i = fontbc[f]; i <= 32; i++)
00197             pdfcharmap[f][i] = i + MOVE_CHARS_OFFSET;
00198         return;
00199     }
00200     fm = (fm_entry *) pdffontmap[f];
00201     if (pdfmovechars == 1 || !get_enc(fm))
00202         return;
00203     e = fm->encoding;
00204     if (e->firstfont != getnullfont()) {
00205         for (i = fontbc[f]; i <= 32; i++)
00206             pdfcharmap[f][i] = pdfcharmap[e->firstfont][i];
00207         return;
00208     }
00209     e->firstfont = f;
00210     glyph_names = e->glyph_names;
00211     for (i = 32, k = MAX_CHAR_CODE; i >= fontbc[f] && k > 127; i--) {
00212         if (glyph_names[i] == notdef)
00213             continue;
00214         while (glyph_names[k] != notdef && k > 127)
00215             k--;
00216         if (k < 128)
00217             return;
00218         glyph_names[k] = glyph_names[i];
00219         glyph_names[i] = (char*) notdef;
00220         pdfcharmap[f][i] = k;
00221     }
00222 }
00223 
00224 /**********************************************************************/
00225 /* cleaning up... */
00226 
00227 void enc_free()
00228 {
00229     int k;
00230     encstruct *p, *pn;
00231     enc_entry *e;
00232 
00233     for (p = epstart; p != NULL; p = pn) {
00234        e = &(p->entry);
00235        pn = p->next;
00236        xfree(e->name);
00237        if (e->loaded)              /* encoding has been loaded */
00238            for (k = 0; k <= MAX_CHAR_CODE; k++)
00239               if (e->glyph_names[k] != notdef)
00240                   xfree(e->glyph_names[k]);
00241        xfree(e->glyph_names);
00242        xfree(p);
00243     }
00244     if (enc_tree != NULL)
00245        avl_destroy(enc_tree, NULL);
00246 }
00247 
00248 /**********************************************************************/