FeatureMap.cpp (9431B)
1 /* GRAPHITE2 LICENSING 2 3 Copyright 2010, SIL International 4 All rights reserved. 5 6 This library is free software; you can redistribute it and/or modify 7 it under the terms of the GNU Lesser General Public License as published 8 by the Free Software Foundation; either version 2.1 of License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should also have received a copy of the GNU Lesser General Public 17 License along with this library in the file named "LICENSE". 18 If not, write to the Free Software Foundation, 51 Franklin Street, 19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 20 internet at http://www.fsf.org/licenses/lgpl.html. 21 22 Alternatively, the contents of this file may be used under the terms of the 23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public 24 License, as published by the Free Software Foundation, either version 2 25 of the License or (at your option) any later version. 26 */ 27 #include <cstring> 28 29 #include "inc/Main.h" 30 #include "inc/bits.h" 31 #include "inc/Endian.h" 32 #include "inc/FeatureMap.h" 33 #include "inc/FeatureVal.h" 34 #include "graphite2/Font.h" 35 #include "inc/TtfUtil.h" 36 #include <cstdlib> 37 #include "inc/Face.h" 38 39 40 using namespace graphite2; 41 42 namespace 43 { 44 static int cmpNameAndFeatures(const void *ap, const void *bp) 45 { 46 const NameAndFeatureRef & a = *static_cast<const NameAndFeatureRef *>(ap), 47 & b = *static_cast<const NameAndFeatureRef *>(bp); 48 return (a < b ? -1 : (b < a ? 1 : 0)); 49 } 50 51 const size_t FEAT_HEADER = sizeof(uint32) + 2*sizeof(uint16) + sizeof(uint32), 52 FEATURE_SIZE = sizeof(uint32) 53 + 2*sizeof(uint16) 54 + sizeof(uint32) 55 + 2*sizeof(uint16), 56 FEATURE_SETTING_SIZE = sizeof(int16) + sizeof(uint16); 57 58 uint16 readFeatureSettings(const byte * p, FeatureSetting * s, size_t num_settings) 59 { 60 uint16 max_val = 0; 61 for (FeatureSetting * const end = s + num_settings; s != end; ++s) 62 { 63 const int16 value = be::read<int16>(p); 64 ::new (s) FeatureSetting(value, be::read<uint16>(p)); 65 if (uint16(value) > max_val) max_val = value; 66 } 67 68 return max_val; 69 } 70 } 71 72 FeatureRef::FeatureRef(const Face & face, 73 unsigned short & bits_offset, uint32 max_val, 74 uint32 name, uint16 uiName, flags_t flags, 75 FeatureSetting *settings, uint16 num_set) throw() 76 : m_face(&face), 77 m_nameValues(settings), 78 m_mask(mask_over_val(max_val)), 79 m_max(max_val), 80 m_id(name), 81 m_nameid(uiName), 82 m_numSet(num_set), 83 m_flags(flags) 84 { 85 const uint8 need_bits = bit_set_count(m_mask); 86 m_index = (bits_offset + need_bits) / SIZEOF_CHUNK; 87 if (m_index > bits_offset / SIZEOF_CHUNK) 88 bits_offset = m_index*SIZEOF_CHUNK; 89 m_bits = bits_offset % SIZEOF_CHUNK; 90 bits_offset += need_bits; 91 m_mask <<= m_bits; 92 } 93 94 FeatureRef::~FeatureRef() throw() 95 { 96 free(m_nameValues); 97 } 98 99 bool FeatureMap::readFeats(const Face & face) 100 { 101 const Face::Table feat(face, TtfUtil::Tag::Feat); 102 const byte * p = feat; 103 if (!p) return true; 104 if (feat.size() < FEAT_HEADER) return false; 105 106 const byte *const feat_start = p, 107 *const feat_end = p + feat.size(); 108 109 const uint32 version = be::read<uint32>(p); 110 m_numFeats = be::read<uint16>(p); 111 be::skip<uint16>(p); 112 be::skip<uint32>(p); 113 114 // Sanity checks 115 if (m_numFeats == 0) return true; 116 if (version < 0x00010000 || 117 p + m_numFeats*FEATURE_SIZE > feat_end) 118 { //defensive 119 m_numFeats = 0; 120 return false; 121 } 122 123 m_feats = new FeatureRef [m_numFeats]; 124 uint16 * const defVals = gralloc<uint16>(m_numFeats); 125 if (!defVals || !m_feats) return false; 126 unsigned short bits = 0; //to cause overflow on first Feature 127 128 for (int i = 0, ie = m_numFeats; i != ie; i++) 129 { 130 const uint32 label = version < 0x00020000 ? be::read<uint16>(p) : be::read<uint32>(p); 131 const uint16 num_settings = be::read<uint16>(p); 132 if (version >= 0x00020000) 133 be::skip<uint16>(p); 134 const uint32 settings_offset = be::read<uint32>(p); 135 const uint16 flags = be::read<uint16>(p), 136 uiName = be::read<uint16>(p); 137 138 if (settings_offset > size_t(feat_end - feat_start) 139 || settings_offset + num_settings * FEATURE_SETTING_SIZE > size_t(feat_end - feat_start)) 140 { 141 free(defVals); 142 return false; 143 } 144 145 FeatureSetting *uiSet; 146 uint32 maxVal; 147 if (num_settings != 0) 148 { 149 uiSet = gralloc<FeatureSetting>(num_settings); 150 if (!uiSet) 151 { 152 free(defVals); 153 return false; 154 } 155 maxVal = readFeatureSettings(feat_start + settings_offset, uiSet, num_settings); 156 defVals[i] = uiSet[0].value(); 157 } 158 else 159 { 160 uiSet = 0; 161 maxVal = 0xffffffff; 162 defVals[i] = 0; 163 } 164 165 ::new (m_feats + i) FeatureRef (face, bits, maxVal, 166 label, uiName, 167 FeatureRef::flags_t(flags), 168 uiSet, num_settings); 169 } 170 new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this); 171 m_pNamedFeats = new NameAndFeatureRef[m_numFeats]; 172 if (!m_pNamedFeats) 173 { 174 free(defVals); 175 return false; 176 } 177 for (int i = 0; i < m_numFeats; ++i) 178 { 179 m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures); 180 m_pNamedFeats[i] = m_feats[i]; 181 } 182 183 free(defVals); 184 185 qsort(m_pNamedFeats, m_numFeats, sizeof(NameAndFeatureRef), &cmpNameAndFeatures); 186 187 return true; 188 } 189 190 bool SillMap::readFace(const Face & face) 191 { 192 if (!m_FeatureMap.readFeats(face)) return false; 193 if (!readSill(face)) return false; 194 return true; 195 } 196 197 198 bool SillMap::readSill(const Face & face) 199 { 200 const Face::Table sill(face, TtfUtil::Tag::Sill); 201 const byte *p = sill; 202 203 if (!p) return true; 204 if (sill.size() < 12) return false; 205 if (be::read<uint32>(p) != 0x00010000UL) return false; 206 m_numLanguages = be::read<uint16>(p); 207 m_langFeats = new LangFeaturePair[m_numLanguages]; 208 if (!m_langFeats || !m_FeatureMap.m_numFeats) { m_numLanguages = 0; return true; } //defensive 209 210 p += 6; // skip the fast search 211 if (sill.size() < m_numLanguages * 8U + 12) return false; 212 213 for (int i = 0; i < m_numLanguages; i++) 214 { 215 uint32 langid = be::read<uint32>(p); 216 uint16 numSettings = be::read<uint16>(p); 217 uint16 offset = be::read<uint16>(p); 218 if (offset + 8U * numSettings > sill.size() && numSettings > 0) return false; 219 Features* feats = new Features(m_FeatureMap.m_defaultFeatures); 220 if (!feats) return false; 221 const byte *pLSet = sill + offset; 222 223 // Apply langauge specific settings 224 for (int j = 0; j < numSettings; j++) 225 { 226 uint32 name = be::read<uint32>(pLSet); 227 uint16 val = be::read<uint16>(pLSet); 228 pLSet += 2; 229 const FeatureRef* pRef = m_FeatureMap.findFeatureRef(name); 230 if (pRef) pRef->applyValToFeature(val, *feats); 231 } 232 // Add the language id feature which is always feature id 1 233 const FeatureRef* pRef = m_FeatureMap.findFeatureRef(1); 234 if (pRef) pRef->applyValToFeature(langid, *feats); 235 236 m_langFeats[i].m_lang = langid; 237 m_langFeats[i].m_pFeatures = feats; 238 } 239 return true; 240 } 241 242 243 Features* SillMap::cloneFeatures(uint32 langname/*0 means default*/) const 244 { 245 if (langname) 246 { 247 // the number of languages in a font is usually small e.g. 8 in Doulos 248 // so this loop is not very expensive 249 for (uint16 i = 0; i < m_numLanguages; i++) 250 { 251 if (m_langFeats[i].m_lang == langname) 252 return new Features(*m_langFeats[i].m_pFeatures); 253 } 254 } 255 return new Features (m_FeatureMap.m_defaultFeatures); 256 } 257 258 259 260 const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const 261 { 262 NameAndFeatureRef *it; 263 264 for (it = m_pNamedFeats; it < m_pNamedFeats + m_numFeats; ++it) 265 if (it->m_name == name) 266 return it->m_pFRef; 267 return NULL; 268 } 269 270 bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const 271 { 272 if (val>maxVal() || !m_face) 273 return false; 274 if (pDest.m_pMap==NULL) 275 pDest.m_pMap = &m_face->theSill().theFeatureMap(); 276 else 277 if (pDest.m_pMap!=&m_face->theSill().theFeatureMap()) 278 return false; //incompatible 279 if (m_index >= pDest.size()) 280 pDest.resize(m_index+1); 281 pDest[m_index] &= ~m_mask; 282 pDest[m_index] |= (uint32(val) << m_bits); 283 return true; 284 } 285 286 uint32 FeatureRef::getFeatureVal(const Features& feats) const 287 { 288 if (m_index < feats.size() && m_face 289 && &m_face->theSill().theFeatureMap()==feats.m_pMap) 290 return (feats[m_index] & m_mask) >> m_bits; 291 else 292 return 0; 293 }