Line data Source code
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 0 : static int cmpNameAndFeatures(const void *ap, const void *bp)
45 : {
46 0 : const NameAndFeatureRef & a = *static_cast<const NameAndFeatureRef *>(ap),
47 0 : & b = *static_cast<const NameAndFeatureRef *>(bp);
48 0 : 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 0 : uint16 readFeatureSettings(const byte * p, FeatureSetting * s, size_t num_settings)
59 : {
60 0 : uint16 max_val = 0;
61 0 : for (FeatureSetting * const end = s + num_settings; s != end; ++s)
62 : {
63 0 : const int16 value = be::read<int16>(p);
64 0 : ::new (s) FeatureSetting(value, be::read<uint16>(p));
65 0 : if (uint16(value) > max_val) max_val = value;
66 : }
67 :
68 0 : return max_val;
69 : }
70 : }
71 :
72 0 : FeatureRef::FeatureRef(const Face & face,
73 : unsigned short & bits_offset, uint32 max_val,
74 : uint32 name, uint16 uiName, uint16 flags,
75 0 : FeatureSetting *settings, uint16 num_set) throw()
76 : : m_pFace(&face),
77 : m_nameValues(settings),
78 0 : m_mask(mask_over_val(max_val)),
79 : m_max(max_val),
80 : m_id(name),
81 : m_nameid(uiName),
82 : m_flags(flags),
83 0 : m_numSet(num_set)
84 : {
85 0 : const uint8 need_bits = bit_set_count(m_mask);
86 0 : m_index = (bits_offset + need_bits) / SIZEOF_CHUNK;
87 0 : if (m_index > bits_offset / SIZEOF_CHUNK)
88 0 : bits_offset = m_index*SIZEOF_CHUNK;
89 0 : m_bits = bits_offset % SIZEOF_CHUNK;
90 0 : bits_offset += need_bits;
91 0 : m_mask <<= m_bits;
92 0 : }
93 :
94 0 : FeatureRef::~FeatureRef() throw()
95 : {
96 0 : free(m_nameValues);
97 0 : }
98 :
99 0 : bool FeatureMap::readFeats(const Face & face)
100 : {
101 0 : const Face::Table feat(face, TtfUtil::Tag::Feat);
102 0 : const byte * p = feat;
103 0 : if (!p) return true;
104 0 : if (feat.size() < FEAT_HEADER) return false;
105 :
106 0 : const byte *const feat_start = p,
107 0 : *const feat_end = p + feat.size();
108 :
109 0 : const uint32 version = be::read<uint32>(p);
110 0 : m_numFeats = be::read<uint16>(p);
111 0 : be::skip<uint16>(p);
112 0 : be::skip<uint32>(p);
113 :
114 : // Sanity checks
115 0 : if (m_numFeats == 0) return true;
116 0 : if (version < 0x00010000 ||
117 0 : p + m_numFeats*FEATURE_SIZE > feat_end)
118 : { //defensive
119 0 : m_numFeats = 0;
120 0 : return false;
121 : }
122 :
123 0 : m_feats = new FeatureRef [m_numFeats];
124 0 : uint16 * const defVals = gralloc<uint16>(m_numFeats);
125 0 : if (!defVals || !m_feats) return false;
126 0 : unsigned short bits = 0; //to cause overflow on first Feature
127 :
128 0 : for (int i = 0, ie = m_numFeats; i != ie; i++)
129 : {
130 0 : const uint32 label = version < 0x00020000 ? be::read<uint16>(p) : be::read<uint32>(p);
131 0 : const uint16 num_settings = be::read<uint16>(p);
132 0 : if (version >= 0x00020000)
133 0 : be::skip<uint16>(p);
134 0 : const uint32 settings_offset = be::read<uint32>(p);
135 0 : const uint16 flags = be::read<uint16>(p),
136 0 : uiName = be::read<uint16>(p);
137 :
138 0 : if (settings_offset > size_t(feat_end - feat_start)
139 0 : || settings_offset + num_settings * FEATURE_SETTING_SIZE > size_t(feat_end - feat_start))
140 : {
141 0 : free(defVals);
142 0 : return false;
143 : }
144 :
145 : FeatureSetting *uiSet;
146 : uint32 maxVal;
147 0 : if (num_settings != 0)
148 : {
149 0 : uiSet = gralloc<FeatureSetting>(num_settings);
150 0 : if (!uiSet)
151 : {
152 0 : free(defVals);
153 0 : return false;
154 : }
155 0 : maxVal = readFeatureSettings(feat_start + settings_offset, uiSet, num_settings);
156 0 : defVals[i] = uiSet[0].value();
157 : }
158 : else
159 : {
160 0 : uiSet = 0;
161 0 : maxVal = 0xffffffff;
162 0 : defVals[i] = 0;
163 : }
164 :
165 0 : ::new (m_feats + i) FeatureRef (face, bits, maxVal,
166 : label, uiName, flags,
167 0 : uiSet, num_settings);
168 : }
169 0 : new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this);
170 0 : m_pNamedFeats = new NameAndFeatureRef[m_numFeats];
171 0 : if (!m_pNamedFeats)
172 : {
173 0 : free(defVals);
174 0 : return false;
175 : }
176 0 : for (int i = 0; i < m_numFeats; ++i)
177 : {
178 0 : m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures);
179 0 : m_pNamedFeats[i] = m_feats+i;
180 : }
181 :
182 0 : free(defVals);
183 :
184 0 : qsort(m_pNamedFeats, m_numFeats, sizeof(NameAndFeatureRef), &cmpNameAndFeatures);
185 :
186 0 : return true;
187 : }
188 :
189 0 : bool SillMap::readFace(const Face & face)
190 : {
191 0 : if (!m_FeatureMap.readFeats(face)) return false;
192 0 : if (!readSill(face)) return false;
193 0 : return true;
194 : }
195 :
196 :
197 0 : bool SillMap::readSill(const Face & face)
198 : {
199 0 : const Face::Table sill(face, TtfUtil::Tag::Sill);
200 0 : const byte *p = sill;
201 :
202 0 : if (!p) return true;
203 0 : if (sill.size() < 12) return false;
204 0 : if (be::read<uint32>(p) != 0x00010000UL) return false;
205 0 : m_numLanguages = be::read<uint16>(p);
206 0 : m_langFeats = new LangFeaturePair[m_numLanguages];
207 0 : if (!m_langFeats || !m_FeatureMap.m_numFeats) { m_numLanguages = 0; return true; } //defensive
208 :
209 0 : p += 6; // skip the fast search
210 0 : if (sill.size() < m_numLanguages * 8U + 12) return false;
211 :
212 0 : for (int i = 0; i < m_numLanguages; i++)
213 : {
214 0 : uint32 langid = be::read<uint32>(p);
215 0 : uint16 numSettings = be::read<uint16>(p);
216 0 : uint16 offset = be::read<uint16>(p);
217 0 : if (offset + 8U * numSettings > sill.size() && numSettings > 0) return false;
218 0 : Features* feats = new Features(m_FeatureMap.m_defaultFeatures);
219 0 : if (!feats) return false;
220 0 : const byte *pLSet = sill + offset;
221 :
222 : // Apply langauge specific settings
223 0 : for (int j = 0; j < numSettings; j++)
224 : {
225 0 : uint32 name = be::read<uint32>(pLSet);
226 0 : uint16 val = be::read<uint16>(pLSet);
227 0 : pLSet += 2;
228 0 : const FeatureRef* pRef = m_FeatureMap.findFeatureRef(name);
229 0 : if (pRef) pRef->applyValToFeature(val, *feats);
230 : }
231 : // Add the language id feature which is always feature id 1
232 0 : const FeatureRef* pRef = m_FeatureMap.findFeatureRef(1);
233 0 : if (pRef) pRef->applyValToFeature(langid, *feats);
234 :
235 0 : m_langFeats[i].m_lang = langid;
236 0 : m_langFeats[i].m_pFeatures = feats;
237 : }
238 0 : return true;
239 : }
240 :
241 :
242 0 : Features* SillMap::cloneFeatures(uint32 langname/*0 means default*/) const
243 : {
244 0 : if (langname)
245 : {
246 : // the number of languages in a font is usually small e.g. 8 in Doulos
247 : // so this loop is not very expensive
248 0 : for (uint16 i = 0; i < m_numLanguages; i++)
249 : {
250 0 : if (m_langFeats[i].m_lang == langname)
251 0 : return new Features(*m_langFeats[i].m_pFeatures);
252 : }
253 : }
254 0 : return new Features (m_FeatureMap.m_defaultFeatures);
255 : }
256 :
257 :
258 :
259 0 : const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const
260 : {
261 : NameAndFeatureRef *it;
262 :
263 0 : for (it = m_pNamedFeats; it < m_pNamedFeats + m_numFeats; ++it)
264 0 : if (it->m_name == name)
265 0 : return it->m_pFRef;
266 0 : return NULL;
267 : }
268 :
269 0 : bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const
270 : {
271 0 : if (val>maxVal() || !m_pFace)
272 0 : return false;
273 0 : if (pDest.m_pMap==NULL)
274 0 : pDest.m_pMap = &m_pFace->theSill().theFeatureMap();
275 : else
276 0 : if (pDest.m_pMap!=&m_pFace->theSill().theFeatureMap())
277 0 : return false; //incompatible
278 0 : if (m_index >= pDest.size())
279 0 : pDest.resize(m_index+1);
280 0 : pDest[m_index] &= ~m_mask;
281 0 : pDest[m_index] |= (uint32(val) << m_bits);
282 0 : return true;
283 : }
284 :
285 0 : uint32 FeatureRef::getFeatureVal(const Features& feats) const
286 : {
287 0 : if (m_index < feats.size() && &m_pFace->theSill().theFeatureMap()==feats.m_pMap)
288 0 : return (feats[m_index] & m_mask) >> m_bits;
289 : else
290 0 : return 0;
291 : }
292 :
293 :
|