Back to index

texmacs  1.0.7.15
tt_aux.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/tt_aux.c,v 1.9 2008/05/17 04:18:47 chofchof Exp $
00002     
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007     
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012     
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017     
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif /* HAVE_CONFIG_H */
00026 
00027 #include "system.h"
00028 #include "mem.h"
00029 #include "error.h"
00030 #include "numbers.h"
00031 
00032 #include "pdfobj.h"
00033 
00034 #include "sfnt.h"
00035 #include "tt_table.h"
00036 #include "tt_post.h"
00037 #include "tt_aux.h"
00038 
00039 ULONG ttc_read_offset (sfnt *sfont, int ttc_idx)
00040 {
00041   LONG version;
00042   ULONG offset = 0, num_dirs = 0;
00043   
00044   if (sfont == NULL || sfont->stream == NULL)
00045     ERROR("file not opened");
00046 
00047   if (sfont->type != SFNT_TYPE_TTC)
00048     ERROR("ttc_read_offset(): invalid font type");
00049 
00050   sfnt_seek_set (sfont, 4); /* skip version tag */
00051 
00052   version = sfnt_get_ulong(sfont);
00053   num_dirs = sfnt_get_ulong(sfont);
00054   if (ttc_idx < 0 || ttc_idx > num_dirs - 1)
00055     ERROR("Invalid TTC index number");
00056 
00057   sfnt_seek_set (sfont, 12 + ttc_idx * 4);
00058   offset = sfnt_get_ulong (sfont);
00059 
00060   return offset;
00061 }
00062 
00063 /*
00064   Build FontDescriptor (except FontName) from TrueType tables:
00065 
00066    Most information found in FontDescriptor is used only when automatic
00067    font substitution is needed. (in the case of missing/broken font data) 
00068    Some PDF viewers may ignore embedded TrueType glyph data. Especially,
00069    any embedded TrueType data for CID-keyed (CIDFontType 2) font is ignored
00070    by PDF viewers that only support PDF versions 1.2 or earlier.
00071 
00072    We use those tables to obtain various values of FontDescriptor.
00073 
00074    head: required
00075 
00076     xMin, xMax, yMin, yMax - FontBBox
00077     unitsPerEm - conversion to PDF unit (points). see PDFUNIT bellow.
00078     The head table must exist in any TrueType font.
00079 
00080    hhea: required
00081 
00082     When the OS/2 table (Windows and OS/2 only) is not available,
00083     Ascender and Descender values can be used to estimate Ascent
00084     and Descent. The hhea table is required for all TrueType fonts.
00085     MaxWidth can be obtained from this table.
00086 
00087    OS/2: required for Windows and OS/2 TrueType, and OpenType
00088 
00089     fsType     - liscensing information
00090     sCapHeight - CapHeight (version 2 only)
00091 
00092      The sCapHeight is only available in newer TrueType fonts which has
00093      version 2 OS/2 table and generally not available. Instead, we can
00094      use height of uppercase letter `H'. But we don't use it, we simply
00095      use Ascent value.
00096 
00097     sTypoAscender, sTypoDescender - Ascent and Descent
00098     usWeightClass - roughly estimate StemV.
00099 
00100      Estimation is based on the following expression:
00101 
00102       stemv = (os2->usWeightClass/65)*(os2->usWeightClass/65)+50
00103 
00104      . I've found this expression in some Adobe document (lost). We use
00105      this expression also, otherwise, we must analyze glyph data.
00106 
00107     xAvgCharWidth - AvgWidth (optional)
00108     sFamilyClass - Flags
00109     sFamilyClass and panose - Panose in Style dictionary (optional)
00110 
00111    post: required
00112 
00113     italicAngle - ItalicAngle
00114 
00115 */
00116 
00117 
00118 #ifndef PDFUNIT
00119 #define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1))
00120 #endif
00121 
00122 /* Flags: should not come here */
00123 #define FIXEDWIDTH (1 << 0)  /* Fixed-width font */
00124 #define SERIF      (1 << 1)  /* Serif font */
00125 #define SYMBOLIC   (1 << 2)  /* Symbolic font */
00126 #define SCRIPT     (1 << 3)  /* Script font */
00127 #define STANDARD   (1 << 5)  /* Uses the Adobe Standard Character Set */
00128 #define ITALIC     (1 << 6)  /* Italic */
00129 #define ALLCAP     (1 << 16) /* All-cap font */
00130 #define SMALLCAP   (1 << 17) /* Small-cap font */
00131 #define FORCEBOLD  (1 << 18) /* Force bold at small text sizes */
00132 pdf_obj *tt_get_fontdesc (sfnt *sfont, int *embed, int stemv, int type)
00133 {
00134   pdf_obj *descriptor = NULL;
00135   pdf_obj *bbox = NULL;
00136   int flag = SYMBOLIC;
00137   /* TrueType tables */
00138   struct tt_head_table *head;
00139   struct tt_os2__table *os2;
00140   struct tt_post_table *post;
00141 
00142   if (!sfont) {
00143     ERROR("font file not opened");
00144   }
00145 
00146   os2  = tt_read_os2__table(sfont);
00147   head = tt_read_head_table(sfont);
00148   post = tt_read_post_table(sfont);
00149   if (!post) {
00150     RELEASE(os2);
00151     RELEASE(head);
00152     return NULL;
00153   }
00154 
00155   descriptor = pdf_new_dict();
00156   pdf_add_dict (descriptor,
00157               pdf_new_name ("Type"),
00158               pdf_new_name ("FontDescriptor"));
00159 
00160   if (*embed) {
00161     /*
00162       License:
00163 
00164        "Preview & Print embedding" (0x004) requires the document containing
00165        Preview & Print font to be opened in read-only mode. However, licensing
00166        information are lost when fonts are embedded in PDF document and
00167        the only way to make the PDF document "read-only" is to encrypt it.
00168        But we have no support for encryption yet. We do not embed any fonts
00169        with "Preview & Print embedding" setting.
00170 
00171        2001/11/22: Changed to allow `Preview & Print' only fonts embedding
00172     */
00173     if (os2->fsType == 0x0000 || (os2->fsType & 0x0008)) {
00174       /* the least restrictive license granted takes precedence. */
00175       *embed = 1;
00176     } else if (os2->fsType & 0x0004) {
00177       fprintf(stderr,
00178               "\n** NOTICE: This document contains `Preview & Print' only");
00179       fprintf(stderr, " licensed font **\n");
00180       *embed = 1;
00181     } else {
00182       fprintf(stderr,
00183               "\n*** Embedding disabled due to licensing restriction ***\n");
00184       *embed = 0;
00185     }
00186   }
00187 
00188   pdf_add_dict (descriptor,
00189               pdf_new_name ("Ascent"),
00190               pdf_new_number (PDFUNIT(os2->sTypoAscender)));
00191   pdf_add_dict (descriptor,
00192               pdf_new_name ("Descent"),
00193               pdf_new_number (PDFUNIT(os2->sTypoDescender)));
00194   if (stemv < 0) /* if not given by the option '-v' */
00195     stemv = (os2->usWeightClass/65.)*(os2->usWeightClass/65.)+50;
00196   pdf_add_dict (descriptor,
00197               pdf_new_name ("StemV"),
00198               pdf_new_number (stemv));
00199   if (os2->version == 0x0002) {
00200     pdf_add_dict (descriptor,
00201                 pdf_new_name("CapHeight"),
00202                 pdf_new_number(PDFUNIT(os2->sCapHeight))
00203                 );
00204     /* optional */
00205     pdf_add_dict (descriptor,
00206                 pdf_new_name("XHeight"),
00207                 pdf_new_number(PDFUNIT(os2->sxHeight))
00208                 );
00209   } else { /* arbitrary */
00210     pdf_add_dict (descriptor,
00211                 pdf_new_name("CapHeight"),
00212                 pdf_new_number(PDFUNIT(os2->sTypoAscender))
00213                 );
00214   }
00215   /* optional */
00216   if (os2->xAvgCharWidth != 0) {
00217     pdf_add_dict (descriptor,
00218                 pdf_new_name ("AvgWidth"),
00219                 pdf_new_number (PDFUNIT(os2->xAvgCharWidth)));
00220   }
00221 
00222   /* BoundingBox (array) */
00223   bbox = pdf_new_array ();
00224   pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->xMin)));
00225   pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->yMin)));
00226   pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->xMax)));
00227   pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->yMax)));
00228   pdf_add_dict (descriptor, pdf_new_name ("FontBBox"), bbox);
00229 
00230   /* post */
00231   pdf_add_dict (descriptor,
00232               pdf_new_name ("ItalicAngle"),
00233               pdf_new_number(fixed(post->italicAngle)));
00234 
00235   /* Flags */
00236   if (os2->fsSelection & (1 << 0))
00237     flag |= ITALIC;
00238   if (os2->fsSelection & (1 << 5))
00239     flag |= FORCEBOLD;
00240   if (((os2->sFamilyClass >> 8) & 0xff) != 8)
00241     flag |= SERIF;
00242   if (((os2->sFamilyClass >> 8) & 0xff) == 10)
00243     flag |= SCRIPT;
00244   if (post->isFixedPitch)
00245     flag |= FIXEDWIDTH;
00246 
00247   pdf_add_dict (descriptor,
00248               pdf_new_name ("Flags"),
00249               pdf_new_number (flag));
00250 
00251   /* insert panose if you want */
00252   if (type == 0) { /* cid-keyed font - add panose */
00253     pdf_obj *styledict = NULL;
00254     unsigned char panose[12];
00255     
00256     panose[0] = os2->sFamilyClass >> 8;
00257     panose[1] = os2->sFamilyClass & 0xff;
00258     memcpy(panose+2, os2->panose, 10);
00259 
00260     styledict = pdf_new_dict ();
00261     pdf_add_dict (styledict, pdf_new_name ("Panose"),
00262                 pdf_new_string (panose, 12));
00263     pdf_add_dict (descriptor, pdf_new_name ("Style"), styledict);
00264   }
00265 
00266   RELEASE(head);
00267   RELEASE(os2);
00268   tt_release_post_table(post);
00269 
00270   return descriptor;
00271 }
00272