Back to index

tetex-bin  3.0
writefont.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/writefont.c#13 $
00021 */
00022 
00023 #include "ptexlib.h"
00024 
00025 static const char perforce_id[] = 
00026     "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writefont.c#13 $";
00027 
00028 key_entry font_keys[FONT_KEYS_NUM] = {
00029     {"Ascent",       "Ascender",     0, false},
00030     {"CapHeight",    "CapHeight",    0, false},
00031     {"Descent",      "Descender",    0, false},
00032     {"FontName",     "FontName",     0, false},
00033     {"ItalicAngle",  "ItalicAngle",  0, false},
00034     {"StemV",        "StdVW",        0, false},
00035     {"XHeight",      "XHeight",      0, false},
00036     {"FontBBox",     "FontBBox",     0, false},
00037     {"",             "",             0, false},
00038     {"",             "",             0, false},
00039     {"",             "",             0, false}
00040 };
00041 
00042 internalfontnumber tex_font;
00043 boolean fontfile_found;
00044 boolean is_otf_font;
00045 boolean write_ttf_glyph_names;
00046 char fontname_buf[FONTNAME_BUF_SIZE];
00047 
00048 static int first_char, last_char;
00049 static integer char_widths[MAX_CHAR_CODE + 1];
00050 static boolean write_fontfile_only;
00051 static int char_widths_objnum,
00052            encoding_objnum;
00053 static char **cur_glyph_names;
00054 
00055 static void print_key(integer code, integer v)
00056 {
00057     pdf_printf("/%s ", font_keys[code].pdfname);
00058     if (font_keys[code].valid)
00059         pdf_printf("%i", (int)font_keys[code].value);
00060     else
00061         pdf_printf("%i", (int)dividescaled(v, pdffontsize[tex_font], 3));
00062     pdf_puts("\n");
00063 }
00064 
00065 static void print_italic_angle()
00066 {
00067     pdf_printf("/%s ", font_keys[ITALIC_ANGLE_CODE].pdfname);
00068     if (font_keys[ITALIC_ANGLE_CODE].valid)
00069         pdf_printf("%g", font_keys[ITALIC_ANGLE_CODE].value);
00070     else
00071         pdf_printf("%g", -atan(getslant(tex_font)/65536.0)*(180/M_PI));
00072     pdf_puts("\n");
00073 }
00074 
00075 static integer getstemv(void)
00076 {
00077     return getcharwidth(tex_font, '.')/3;
00078 }
00079 
00080 static void getbbox(void)
00081 {
00082     font_keys[FONTBBOX1_CODE].value = 0;
00083     font_keys[FONTBBOX2_CODE].value = 
00084         dividescaled(-getchardepth(tex_font, 'y'), pdffontsize[tex_font], 3);
00085     font_keys[FONTBBOX3_CODE].value =
00086         dividescaled(getquad(tex_font), pdffontsize[tex_font], 3);
00087     font_keys[FONTBBOX4_CODE].value =
00088         dividescaled(getcharheight(tex_font, 'H'), pdffontsize[tex_font], 3);
00089 }
00090 
00091 /*
00092  * update glyph names of an encoding (either external or internal) 
00093  * when fontec[f] < 128 
00094  */
00095 void update_enc(internalfontnumber f, char **glyph_names)
00096 {
00097     int i;
00098     fm_entry *fm = (fm_entry *) pdffontmap[f];
00099     if (fontec[f] > 127 || (hasfmentry(f) &&
00100          (is_reencoded(fm) && (fm->encoding)->updated)))
00101         return;
00102     for (i = fontbc[f]; i <= 32; i++)
00103         if (pdfcharmap[f][i] != i) {
00104             if (glyph_names[i + MOVE_CHARS_OFFSET] != notdef)
00105                 xfree(glyph_names[i + MOVE_CHARS_OFFSET]);
00106             if (glyph_names[i] != notdef)
00107                 glyph_names[i + MOVE_CHARS_OFFSET] = xstrdup(glyph_names[i]);
00108             else
00109                 glyph_names[i + MOVE_CHARS_OFFSET] = (char*) notdef;
00110         }
00111     if (is_reencoded(fm))
00112         (fm->encoding)->updated = true;
00113 }
00114 
00115 static void get_char_widths(void)
00116 {
00117     int i;
00118     for (i = 0; i <= MAX_CHAR_CODE; i++) {
00119         if (i < fontbc[tex_font] || i > fontec[tex_font])
00120             char_widths[i] = 0;
00121         else
00122             char_widths[i] = getcharwidth(tex_font, i);
00123     }
00124     for (i = fontbc[tex_font]; i <= 32; i++)
00125         char_widths[pdfcharmap[tex_font][i]] = char_widths[i];
00126     for (i = fontbc[tex_font]; i <= MAX_CHAR_CODE; i++)
00127         if (pdfcharmarked(tex_font, i))
00128             break;
00129     first_char = i;
00130     for (i = MAX_CHAR_CODE; i > first_char;  i--)
00131         if (pdfcharmarked(tex_font, i))
00132             break;
00133     last_char = i;
00134     if ((first_char > last_char) ||
00135         (first_char == last_char && !pdfcharmarked(tex_font, first_char))) { 
00136         write_fontfile_only = true; /* the font is used in PDF images only */
00137         return;
00138     }
00139     for (i = first_char; i <= last_char; i++)
00140         if (pdfcharmarked(tex_font, i))
00141             char_widths[i] = dividescaled(char_widths[i], 
00142                                           pdffontsize[tex_font], 3);
00143         else
00144             char_widths[i] = 0;
00145     if (is_reencoded(fm_cur) && pdfmovechars > 0) {
00146         read_enc(fm_cur->encoding);
00147         update_enc(f, (fm_cur->encoding)->glyph_names);
00148     }
00149 }
00150 
00151 static void write_char_widths(void)
00152 {
00153     int i;
00154     pdfbeginobj(char_widths_objnum); 
00155     pdf_puts("[");
00156     for (i = first_char; i <= last_char; i++)
00157         pdf_printf("%i ", char_widths[i]);
00158     pdf_puts("]\n");
00159     pdfendobj();
00160 }
00161 
00162 static void write_fontname(boolean as_reference)
00163 {
00164     if (as_reference && fm_cur->fn_objnum != 0) {
00165         pdf_printf("%i 0 R\n", (int)fm_cur->fn_objnum);
00166         return;
00167     }
00168     pdf_puts("/");
00169     if (fm_cur->subset_tag != NULL)
00170         pdf_printf("%s+", fm_cur->subset_tag);
00171     if (font_keys[FONTNAME_CODE].valid)
00172         pdf_printf("%s", fontname_buf);
00173     else if (fm_cur->ps_name != NULL)
00174         pdf_printf("%s", fm_cur->ps_name);
00175     else
00176         pdf_printf("%s", fm_cur->tfm_name);
00177     pdf_puts("\n");
00178 }
00179 
00180 static void write_fontobj(integer font_objnum)
00181 {
00182     pdfbegindict(font_objnum);
00183     pdf_puts("/Type /Font\n");
00184     pdf_printf("/Subtype /%s\n", is_truetype(fm_cur) ? "TrueType" : "Type1");
00185     if (encoding_objnum != 0)
00186         pdf_printf("/Encoding %i 0 R\n", (int)encoding_objnum);
00187     if (pdffontattr[tex_font] != getnullstr()) {
00188         pdfprint(pdffontattr[tex_font]);
00189         pdf_puts("\n");
00190     }
00191     if (is_basefont(fm_cur) && !is_included(fm_cur)) {
00192         pdf_printf("/BaseFont /%s\n", fm_cur->ps_name);
00193         pdfenddict();
00194         return;
00195     }
00196     char_widths_objnum = pdfnewobjnum();
00197     pdf_printf("/FirstChar %i\n/LastChar %i\n/Widths %i 0 R\n",
00198                first_char, last_char, char_widths_objnum);
00199     pdf_printf("/BaseFont ");
00200     write_fontname(true);
00201     if (fm_cur->fd_objnum == 0)
00202         fm_cur->fd_objnum = pdfnewobjnum();
00203     pdf_printf("/FontDescriptor %i 0 R\n", fm_cur->fd_objnum);
00204     pdfenddict();
00205 }
00206 
00207 static void write_fontfile(void)
00208 {
00209     int i;
00210     for (i = 0; i < FONT_KEYS_NUM; i++)
00211         font_keys[i].valid = false;
00212     fontfile_found = false;
00213     is_otf_font = false;
00214     if (is_truetype(fm_cur))
00215         writettf();
00216     else
00217         writet1();
00218     if (!fontfile_found || !is_included(fm_cur))
00219         return;
00220     if (fm_cur->ff_objnum == 0)
00221         pdftex_fail("font file object number for `%s' not initialized",
00222                     fm_cur->tfm_name);
00223     pdfbegindict(fm_cur->ff_objnum); /* font file stream */
00224     if (is_truetype(fm_cur))
00225         pdf_printf("/Length1 %i\n", (int)ttf_length);
00226     else if (is_otf_font) 
00227         pdf_printf("/Subtype /Type1C\n");
00228     else
00229         pdf_printf("/Length1 %i\n/Length2 %i\n/Length3 %i\n",
00230                    (int)t1_length1, (int)t1_length2, (int)t1_length3);
00231     pdfbeginstream();
00232     fb_flush();
00233     pdfendstream();
00234 }
00235 
00236 static void write_fontdescriptor(void)
00237 {
00238     int i;
00239     pdfbegindict(fm_cur->fd_objnum); /* font descriptor */
00240     print_key(ASCENT_CODE, getcharheight(tex_font, 'h'));
00241     print_key(CAPHEIGHT_CODE, getcharheight(tex_font, 'H'));
00242     print_key(DESCENT_CODE, -getchardepth(tex_font, 'y'));
00243     pdf_printf("/FontName ");
00244     write_fontname(true);
00245     print_italic_angle();
00246     print_key(STEMV_CODE, getstemv());
00247     print_key(XHEIGHT_CODE, getxheight(tex_font));
00248     if (!font_keys[FONTBBOX1_CODE].valid) {
00249         getbbox();
00250     }
00251     pdf_printf("/%s [%i %i %i %i]\n",
00252                font_keys[FONTBBOX1_CODE].pdfname,
00253                (int)font_keys[FONTBBOX1_CODE].value,
00254                (int)font_keys[FONTBBOX2_CODE].value,
00255                (int)font_keys[FONTBBOX3_CODE].value,
00256                (int)font_keys[FONTBBOX4_CODE].value);
00257     if (!fontfile_found && fm_cur->flags == 4)
00258         pdf_puts("/Flags 34\n"); /* assumes a roman sans serif font */
00259     else
00260         pdf_printf("/Flags %i\n", (int)fm_cur->flags);
00261     if (is_included(fm_cur) && fontfile_found) {
00262         if (is_subsetted(fm_cur) && !is_truetype(fm_cur)) {
00263             cur_glyph_names = t1_glyph_names;
00264             pdf_puts("/CharSet (");
00265             for (i = 0; i <= MAX_CHAR_CODE; i++)
00266                 if (pdfcharmarked(tex_font, i) && cur_glyph_names[i] != notdef)
00267                     pdf_printf("/%s", cur_glyph_names[i]);
00268             pdf_puts(")\n");
00269         }
00270         if (is_truetype(fm_cur))
00271             pdf_printf("/FontFile2 %i 0 R\n", fm_cur->ff_objnum);
00272         else if (is_otf_font)
00273             pdf_printf("/FontFile3 %i 0 R\n", fm_cur->ff_objnum);
00274         else
00275             pdf_printf("/FontFile %i 0 R\n", fm_cur->ff_objnum);
00276     }
00277     pdfenddict();
00278 }
00279 
00280 void dopdffont(integer font_objnum, internalfontnumber f)
00281 {
00282     int i;
00283     tex_font = f;
00284     cur_glyph_names = NULL;
00285     encoding_objnum = 0;
00286     write_ttf_glyph_names = false;
00287     write_fontfile_only = false;
00288     if (pdffontmap[tex_font] == NULL)
00289         pdftex_fail("pdffontmap not initialized for font %s", 
00290                     makecstring(fontname[tex_font]));
00291     if (hasfmentry(tex_font))
00292         fm_cur = (fm_entry *) pdffontmap[tex_font];
00293     else
00294         fm_cur = NULL;
00295     if (fm_cur == NULL || (fm_cur->ps_name == NULL && fm_cur->ff_name == NULL)) {
00296         writet3(font_objnum, tex_font);
00297         return;
00298     }
00299 
00300     get_char_widths(); /* update char widths; also check whether this font is
00301                           used in embedded PDF only; if so then set
00302                           write_fontfile_only to true */
00303 
00304     if (!write_fontfile_only) { /* encoding vector needed */
00305         if ((is_reencoded(fm_cur))) {
00306             read_enc(fm_cur->encoding);
00307             if (!is_truetype(fm_cur)) {
00308                 write_enc(NULL, fm_cur->encoding, 0);
00309                 encoding_objnum = (fm_cur->encoding)->objnum;
00310             }
00311             else
00312                 write_ttf_glyph_names = true;
00313         }
00314         else if (is_fontfile(fm_cur) && !is_truetype(fm_cur)) {
00315             encoding_objnum = pdfnewobjnum();
00316         }
00317     }
00318     if (is_included(fm_cur))
00319         write_fontfile();
00320     if (fm_cur->fn_objnum != 0) {
00321         pdfbeginobj(fm_cur->fn_objnum);
00322         write_fontname(false);
00323         pdfendobj();
00324     }
00325     if (!write_fontfile_only)
00326         write_fontobj(font_objnum);
00327     if (is_basefont(fm_cur) && !is_included(fm_cur))
00328         return;
00329     if (!write_fontfile_only) {
00330         write_fontdescriptor();
00331         write_char_widths();
00332     }
00333     if (cur_glyph_names == t1_builtin_glyph_names) {
00334         if (!write_fontfile_only) {
00335             for (i = 0; i <= MAX_CHAR_CODE; i++)
00336                 if (!pdfcharmarked(tex_font, i) && cur_glyph_names[i] != notdef) {
00337                     xfree(cur_glyph_names[i]);
00338                     cur_glyph_names[i] = (char*) notdef;
00339                 }
00340             write_enc(cur_glyph_names, NULL, encoding_objnum);
00341         }
00342         for (i = 0; i <= MAX_CHAR_CODE; i++)
00343             if (cur_glyph_names[i] != notdef)
00344                 xfree(cur_glyph_names[i]);
00345     }
00346 }