Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2007,2008,2009  Red Hat, Inc.
      3  * Copyright  2012  Google, Inc.
      4  *
      5  *  This is part of HarfBuzz, a text shaping library.
      6  *
      7  * Permission is hereby granted, without written agreement and without
      8  * license or royalty fees, to use, copy, modify, and distribute this
      9  * software and its documentation for any purpose, provided that the
     10  * above copyright notice and the following two paragraphs appear in
     11  * all copies of this software.
     12  *
     13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     17  * DAMAGE.
     18  *
     19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     24  *
     25  * Red Hat Author(s): Behdad Esfahbod
     26  * Google Author(s): Behdad Esfahbod
     27  */
     28 
     29 #ifndef HB_OPEN_FILE_PRIVATE_HH
     30 #define HB_OPEN_FILE_PRIVATE_HH
     31 
     32 #include "hb-open-type-private.hh"
     33 
     34 
     35 namespace OT {
     36 
     37 
     38 /*
     39  *
     40  * The OpenType Font File
     41  *
     42  */
     43 
     44 
     45 /*
     46  * Organization of an OpenType Font
     47  */
     48 
     49 struct OpenTypeFontFile;
     50 struct OffsetTable;
     51 struct TTCHeader;
     52 
     53 
     54 typedef struct TableRecord
     55 {
     56   inline bool sanitize (hb_sanitize_context_t *c) {
     57     TRACE_SANITIZE (this);
     58     return TRACE_RETURN (c->check_struct (this));
     59   }
     60 
     61   Tag		tag;		/* 4-byte identifier. */
     62   CheckSum	checkSum;	/* CheckSum for this table. */
     63   ULONG		offset;		/* Offset from beginning of TrueType font
     64 				 * file. */
     65   ULONG		length;		/* Length of this table. */
     66   public:
     67   DEFINE_SIZE_STATIC (16);
     68 } OpenTypeTable;
     69 
     70 typedef struct OffsetTable
     71 {
     72   friend struct OpenTypeFontFile;
     73 
     74   inline unsigned int get_table_count (void) const
     75   { return numTables; }
     76   inline const TableRecord& get_table (unsigned int i) const
     77   {
     78     if (unlikely (i >= numTables)) return Null(TableRecord);
     79     return tables[i];
     80   }
     81   inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
     82   {
     83     Tag t;
     84     t.set (tag);
     85     unsigned int count = numTables;
     86     for (unsigned int i = 0; i < count; i++)
     87     {
     88       if (t == tables[i].tag)
     89       {
     90         if (table_index) *table_index = i;
     91         return true;
     92       }
     93     }
     94     if (table_index) *table_index = Index::NOT_FOUND_INDEX;
     95     return false;
     96   }
     97   inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
     98   {
     99     unsigned int table_index;
    100     find_table_index (tag, &table_index);
    101     return get_table (table_index);
    102   }
    103 
    104   public:
    105   inline bool sanitize (hb_sanitize_context_t *c) {
    106     TRACE_SANITIZE (this);
    107     return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
    108   }
    109 
    110   protected:
    111   Tag		sfnt_version;	/* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
    112   USHORT	numTables;	/* Number of tables. */
    113   USHORT	searchRange;	/* (Maximum power of 2 <= numTables) x 16 */
    114   USHORT	entrySelector;	/* Log2(maximum power of 2 <= numTables). */
    115   USHORT	rangeShift;	/* NumTables x 16-searchRange. */
    116   TableRecord	tables[VAR];	/* TableRecord entries. numTables items */
    117   public:
    118   DEFINE_SIZE_ARRAY (12, tables);
    119 } OpenTypeFontFace;
    120 
    121 
    122 /*
    123  * TrueType Collections
    124  */
    125 
    126 struct TTCHeaderVersion1
    127 {
    128   friend struct TTCHeader;
    129 
    130   inline unsigned int get_face_count (void) const { return table.len; }
    131   inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
    132 
    133   inline bool sanitize (hb_sanitize_context_t *c) {
    134     TRACE_SANITIZE (this);
    135     return TRACE_RETURN (table.sanitize (c, this));
    136   }
    137 
    138   protected:
    139   Tag		ttcTag;		/* TrueType Collection ID string: 'ttcf' */
    140   FixedVersion	version;	/* Version of the TTC Header (1.0),
    141 				 * 0x00010000 */
    142   LongOffsetLongArrayOf<OffsetTable>
    143 		table;		/* Array of offsets to the OffsetTable for each font
    144 				 * from the beginning of the file */
    145   public:
    146   DEFINE_SIZE_ARRAY (12, table);
    147 };
    148 
    149 struct TTCHeader
    150 {
    151   friend struct OpenTypeFontFile;
    152 
    153   private:
    154 
    155   inline unsigned int get_face_count (void) const
    156   {
    157     switch (u.header.version.major) {
    158     case 2: /* version 2 is compatible with version 1 */
    159     case 1: return u.version1.get_face_count ();
    160     default:return 0;
    161     }
    162   }
    163   inline const OpenTypeFontFace& get_face (unsigned int i) const
    164   {
    165     switch (u.header.version.major) {
    166     case 2: /* version 2 is compatible with version 1 */
    167     case 1: return u.version1.get_face (i);
    168     default:return Null(OpenTypeFontFace);
    169     }
    170   }
    171 
    172   inline bool sanitize (hb_sanitize_context_t *c) {
    173     TRACE_SANITIZE (this);
    174     if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
    175     switch (u.header.version.major) {
    176     case 2: /* version 2 is compatible with version 1 */
    177     case 1: return TRACE_RETURN (u.version1.sanitize (c));
    178     default:return TRACE_RETURN (true);
    179     }
    180   }
    181 
    182   protected:
    183   union {
    184   struct {
    185   Tag		ttcTag;		/* TrueType Collection ID string: 'ttcf' */
    186   FixedVersion	version;	/* Version of the TTC Header (1.0 or 2.0),
    187 				 * 0x00010000 or 0x00020000 */
    188   }			header;
    189   TTCHeaderVersion1	version1;
    190   } u;
    191 };
    192 
    193 
    194 /*
    195  * OpenType Font File
    196  */
    197 
    198 struct OpenTypeFontFile
    199 {
    200   static const hb_tag_t CFFTag		= HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
    201   static const hb_tag_t TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
    202   static const hb_tag_t TTCTag		= HB_TAG ('t','t','c','f'); /* TrueType Collection */
    203   static const hb_tag_t TrueTag		= HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
    204   static const hb_tag_t Typ1Tag		= HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
    205 
    206   inline hb_tag_t get_tag (void) const { return u.tag; }
    207 
    208   inline unsigned int get_face_count (void) const
    209   {
    210     switch (u.tag) {
    211     case CFFTag:	/* All the non-collection tags */
    212     case TrueTag:
    213     case Typ1Tag:
    214     case TrueTypeTag:	return 1;
    215     case TTCTag:	return u.ttcHeader.get_face_count ();
    216     default:		return 0;
    217     }
    218   }
    219   inline const OpenTypeFontFace& get_face (unsigned int i) const
    220   {
    221     switch (u.tag) {
    222     /* Note: for non-collection SFNT data we ignore index.  This is because
    223      * Apple dfont container is a container of SFNT's.  So each SFNT is a
    224      * non-TTC, but the index is more than zero. */
    225     case CFFTag:	/* All the non-collection tags */
    226     case TrueTag:
    227     case Typ1Tag:
    228     case TrueTypeTag:	return u.fontFace;
    229     case TTCTag:	return u.ttcHeader.get_face (i);
    230     default:		return Null(OpenTypeFontFace);
    231     }
    232   }
    233 
    234   inline bool sanitize (hb_sanitize_context_t *c) {
    235     TRACE_SANITIZE (this);
    236     if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
    237     switch (u.tag) {
    238     case CFFTag:	/* All the non-collection tags */
    239     case TrueTag:
    240     case Typ1Tag:
    241     case TrueTypeTag:	return TRACE_RETURN (u.fontFace.sanitize (c));
    242     case TTCTag:	return TRACE_RETURN (u.ttcHeader.sanitize (c));
    243     default:		return TRACE_RETURN (true);
    244     }
    245   }
    246 
    247   protected:
    248   union {
    249   Tag			tag;		/* 4-byte identifier. */
    250   OpenTypeFontFace	fontFace;
    251   TTCHeader		ttcHeader;
    252   } u;
    253   public:
    254   DEFINE_SIZE_UNION (4, tag);
    255 };
    256 
    257 
    258 } /* namespace OT */
    259 
    260 
    261 #endif /* HB_OPEN_FILE_PRIVATE_HH */
    262