w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

FeatureMap.cpp
Go to the documentation of this file.
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 {
97 }
98 
100 {
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,
168  uiSet, num_settings);
169  }
170  new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this);
172  if (!m_pNamedFeats)
173  {
174  free(defVals);
175  return false;
176  }
177  for (int i = 0; i < m_numFeats; ++i)
178  {
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 
191 {
192  if (!m_FeatureMap.readFeats(face)) return false;
193  if (!readSill(face)) return false;
194  return true;
195 }
196 
197 
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);
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;
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;
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  }
256 }
257 
258 
259 
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 
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 
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 }
bp
Definition: action.c:1035
#define name
const SillMap & theSill() const
Definition: Face.h:126
FeatureVal m_defaultFeatures
Definition: FeatureMap.h:152
bool readFeats(const Face &face)
Definition: FeatureMap.cpp:99
NameAndFeatureRef * m_pNamedFeats
Definition: FeatureMap.h:151
const FeatureRef * findFeatureRef(uint32 name) const
Definition: FeatureMap.cpp:260
FeatureRef * m_feats
Definition: FeatureMap.h:150
FeatureSetting * m_nameValues
Definition: FeatureMap.h:91
uint32 maxVal() const
Definition: FeatureMap.h:82
bool applyValToFeature(uint32 val, Features &pDest) const
Definition: FeatureMap.cpp:270
const Face * m_face
Definition: FeatureMap.h:90
uint32 getFeatureVal(const Features &feats) const
Definition: FeatureMap.cpp:286
const FeatureMap * m_pMap
Definition: FeatureVal.h:60
CLASS_NEW_DELETE uint32 m_name
Definition: FeatureMap.h:128
const FeatureRef * m_pFRef
Definition: FeatureMap.h:129
FeatureMap m_FeatureMap
Definition: FeatureMap.h:185
bool readSill(const Face &face)
Definition: FeatureMap.cpp:198
FeatureVal * cloneFeatures(uint32 langname) const
Definition: FeatureMap.cpp:243
const FeatureMap & theFeatureMap() const
Definition: FeatureMap.h:185
LangFeaturePair * m_langFeats
Definition: FeatureMap.h:188
bool readFace(const Face &face)
Definition: FeatureMap.cpp:190
void resize(size_t n, const T &v=T())
Definition: List.h:119
size_t size() const
Definition: List.h:70
#define b
Definition: jpegint.h:372
#define ap
static Tfeature feat[21]
Definition: control.c:55
#define free(a)
Definition: decNumber.cpp:310
#define s
Definition: afcover.h:80
#define a(n)
Definition: gpos-common.c:148
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
FT_Face face
Definition: cffdrivr.c:659
void * new(uint32_t size)
Definition: mem.c:34
unsigned short uint16
Definition: tiff.h:62
short int16
Definition: tiff.h:61
unsigned long uint32
Definition: tiff.h:68
#define qsort
Definition: includes.h:72
#define uint32
Definition: unibasics.h:49
#define uint16
Definition: unibasics.h:51
Definition: bits.h:30
unsigned int bit_set_count(T v)
Definition: bits.h:80
FeatureVal Features
Definition: FeatureVal.h:63
gr_uint8 uint8
Definition: Main.h:38
T mask_over_val(T v)
Definition: bits.h:112
gr_uint16 uint16
Definition: Main.h:40
gr_uint32 uint32
Definition: Main.h:41
#define version
Definition: nup.c:10
union value value
Definition: obx.h:44
static int offset
Definition: ppmtogif.c:642
#define flags
struct Table Table
Definition: namelist.c:170
Definition: strexpr.c:21
struct def_label label[1024]
Definition: t1part.c:286
int j
Definition: t4ht.c:1589
Definition: obx.h:51
#define langname
#define end(cp)
Definition: zic.c:71