1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "head.h" 6 7 #include <cstring> 8 9 // head - Font Header 10 // http://www.microsoft.com/opentype/otspec/head.htm 11 12 namespace ots { 13 14 bool ots_head_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { 15 Buffer table(data, length); 16 file->head = new OpenTypeHEAD; 17 18 uint32_t version = 0; 19 if (!table.ReadU32(&version) || 20 !table.ReadU32(&file->head->revision)) { 21 return OTS_FAILURE(); 22 } 23 24 if (version >> 16 != 1) { 25 return OTS_FAILURE(); 26 } 27 28 // Skip the checksum adjustment 29 if (!table.Skip(4)) { 30 return OTS_FAILURE(); 31 } 32 33 uint32_t magic; 34 if (!table.ReadTag(&magic) || 35 std::memcmp(&magic, "\x5F\x0F\x3C\xF5", 4)) { 36 return OTS_FAILURE(); 37 } 38 39 if (!table.ReadU16(&file->head->flags)) { 40 return OTS_FAILURE(); 41 } 42 43 // We allow bits 0..4, 11..13 44 file->head->flags &= 0x381f; 45 46 if (!table.ReadU16(&file->head->ppem)) { 47 return OTS_FAILURE(); 48 } 49 50 // ppem must be in range 51 if (file->head->ppem < 16 || 52 file->head->ppem > 16384) { 53 return OTS_FAILURE(); 54 } 55 56 // ppem must be a power of two 57 #if 0 58 // We don't call ots_failure() for now since lots of TrueType fonts are 59 // not following this rule. Putting OTS_WARNING here is too noisy. 60 if ((file->head->ppem - 1) & file->head->ppem) { 61 return OTS_FAILURE(); 62 } 63 #endif 64 65 if (!table.ReadR64(&file->head->created) || 66 !table.ReadR64(&file->head->modified)) { 67 return OTS_FAILURE(); 68 } 69 70 if (!table.ReadS16(&file->head->xmin) || 71 !table.ReadS16(&file->head->ymin) || 72 !table.ReadS16(&file->head->xmax) || 73 !table.ReadS16(&file->head->ymax)) { 74 return OTS_FAILURE(); 75 } 76 77 if (file->head->xmin > file->head->xmax) { 78 return OTS_FAILURE(); 79 } 80 if (file->head->ymin > file->head->ymax) { 81 return OTS_FAILURE(); 82 } 83 84 if (!table.ReadU16(&file->head->mac_style)) { 85 return OTS_FAILURE(); 86 } 87 88 // We allow bits 0..6 89 file->head->mac_style &= 0x7f; 90 91 if (!table.ReadU16(&file->head->min_ppem)) { 92 return OTS_FAILURE(); 93 } 94 95 // We don't care about the font direction hint 96 if (!table.Skip(2)) { 97 return OTS_FAILURE(); 98 } 99 100 if (!table.ReadS16(&file->head->index_to_loc_format)) { 101 return OTS_FAILURE(); 102 } 103 if (file->head->index_to_loc_format < 0 || 104 file->head->index_to_loc_format > 1) { 105 return OTS_FAILURE(); 106 } 107 108 int16_t glyph_data_format; 109 if (!table.ReadS16(&glyph_data_format) || 110 glyph_data_format) { 111 return OTS_FAILURE(); 112 } 113 114 return true; 115 } 116 117 bool ots_head_should_serialise(OpenTypeFile *file) { 118 return file->head != NULL; 119 } 120 121 bool ots_head_serialise(OTSStream *out, OpenTypeFile *file) { 122 if (!out->WriteU32(0x00010000) || 123 !out->WriteU32(file->head->revision) || 124 !out->WriteU32(0) || // check sum not filled in yet 125 !out->WriteU32(0x5F0F3CF5) || 126 !out->WriteU16(file->head->flags) || 127 !out->WriteU16(file->head->ppem) || 128 !out->WriteR64(file->head->created) || 129 !out->WriteR64(file->head->modified) || 130 !out->WriteS16(file->head->xmin) || 131 !out->WriteS16(file->head->ymin) || 132 !out->WriteS16(file->head->xmax) || 133 !out->WriteS16(file->head->ymax) || 134 !out->WriteU16(file->head->mac_style) || 135 !out->WriteU16(file->head->min_ppem) || 136 !out->WriteS16(2) || 137 !out->WriteS16(file->head->index_to_loc_format) || 138 !out->WriteS16(0)) { 139 return OTS_FAILURE(); 140 } 141 142 return true; 143 } 144 145 void ots_head_free(OpenTypeFile *file) { 146 delete file->head; 147 } 148 149 } // namespace 150