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