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)  

GlyphCache.cpp
Go to the documentation of this file.
1 /* GRAPHITE2 LICENSING
2 
3  Copyright 2012, 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 "graphite2/Font.h"
28 
29 #include "inc/Main.h"
30 #include "inc/Face.h" //for the tags
31 #include "inc/GlyphCache.h"
32 #include "inc/GlyphFace.h"
33 #include "inc/Endian.h"
34 #include "inc/bits.h"
35 
36 using namespace graphite2;
37 
38 namespace
39 {
40  // Iterator over version 1 or 2 glat entries which consist of a series of
41  // +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+
42  // v1 |k|n|v1 |v2 |...|vN | or v2 | k | n |v1 |v2 |...|vN |
43  // +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+
44  // variable length structures.
45 
46  template<typename W>
47  class _glat_iterator : public std::iterator<std::input_iterator_tag, std::pair<sparse::key_type, sparse::mapped_type> >
48  {
49  unsigned short key() const { return uint16(be::peek<W>(_e) + _n); }
50  unsigned int run() const { return be::peek<W>(_e+sizeof(W)); }
51  void advance_entry() { _n = 0; _e = _v; be::skip<W>(_v,2); }
52  public:
53  _glat_iterator(const void * glat=0) : _e(reinterpret_cast<const byte *>(glat)), _v(_e+2*sizeof(W)), _n(0) {}
54 
55  _glat_iterator<W> & operator ++ () {
56  ++_n; be::skip<uint16>(_v);
57  if (_n == run()) advance_entry();
58  return *this;
59  }
60  _glat_iterator<W> operator ++ (int) { _glat_iterator<W> tmp(*this); operator++(); return tmp; }
61 
62  // This is strictly a >= operator. A true == operator could be
63  // implemented that test for overlap but it would be more expensive a
64  // test.
65  bool operator == (const _glat_iterator<W> & rhs) { return _v >= rhs._e - 1; }
66  bool operator != (const _glat_iterator<W> & rhs) { return !operator==(rhs); }
67 
68  value_type operator * () const {
69  return value_type(key(), be::peek<uint16>(_v));
70  }
71 
72  protected:
73  const byte * _e, * _v;
74  size_t _n;
75  };
76 
77  typedef _glat_iterator<uint8> glat_iterator;
78  typedef _glat_iterator<uint16> glat2_iterator;
79 }
80 
81 const SlantBox SlantBox::empty = {0,0,0,0};
82 
83 
85 {
86 public:
87  Loader(const Face & face); //return result indicates success. Do not use if failed.
88 
89  operator bool () const throw();
90  unsigned short int units_per_em() const throw();
91  unsigned short int num_glyphs() const throw();
92  unsigned short int num_attrs() const throw();
93  bool has_boxes() const throw();
94 
95  const GlyphFace * read_glyph(unsigned short gid, GlyphFace &, int *numsubs) const throw();
97 
99 private:
100  Face::Table _head,
101  _hhea,
102  _hmtx,
103  _glyf,
104  _loca,
105  m_pGlat,
106  m_pGloc;
107 
108  bool _long_fmt;
109  bool _has_boxes;
110  unsigned short _num_glyphs_graphics, //i.e. boundary box and advance
112  _num_attrs; // number of glyph attributes per glyph
113 };
114 
115 
116 
117 GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
118 : _glyph_loader(new Loader(face)),
119  _glyphs(_glyph_loader && *_glyph_loader && _glyph_loader->num_glyphs()
120  ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
121  _boxes(_glyph_loader && _glyph_loader->has_boxes() && _glyph_loader->num_glyphs()
122  ? grzeroalloc<GlyphBox *>(_glyph_loader->num_glyphs()) : 0),
123  _num_glyphs(_glyphs ? _glyph_loader->num_glyphs() : 0),
124  _num_attrs(_glyphs ? _glyph_loader->num_attrs() : 0),
125  _upem(_glyphs ? _glyph_loader->units_per_em() : 0)
126 {
127  if ((face_options & gr_face_preloadGlyphs) && _glyph_loader && _glyphs)
128  {
129  int numsubs = 0;
130  GlyphFace * const glyphs = new GlyphFace [_num_glyphs];
131  if (!glyphs)
132  return;
133 
134  // The 0 glyph is definately required.
135  _glyphs[0] = _glyph_loader->read_glyph(0, glyphs[0], &numsubs);
136 
137  // glyphs[0] has the same address as the glyphs array just allocated,
138  // thus assigning the &glyphs[0] to _glyphs[0] means _glyphs[0] points
139  // to the entire array.
140  const GlyphFace * loaded = _glyphs[0];
141  for (uint16 gid = 1; loaded && gid != _num_glyphs; ++gid)
142  _glyphs[gid] = loaded = _glyph_loader->read_glyph(gid, glyphs[gid], &numsubs);
143 
144  if (!loaded)
145  {
146  _glyphs[0] = 0;
147  delete [] glyphs;
148  }
149  else if (numsubs > 0 && _boxes)
150  {
151  GlyphBox * boxes = (GlyphBox *)gralloc<char>(_num_glyphs * sizeof(GlyphBox) + numsubs * 8 * sizeof(float));
152  GlyphBox * currbox = boxes;
153 
154  for (uint16 gid = 0; currbox && gid != _num_glyphs; ++gid)
155  {
156  _boxes[gid] = currbox;
157  currbox = _glyph_loader->read_box(gid, currbox, *_glyphs[gid]);
158  }
159  if (!currbox)
160  {
161  free(boxes);
162  _boxes[0] = 0;
163  }
164  }
165  delete _glyph_loader;
166  _glyph_loader = 0;
167  // coverity[leaked_storage : FALSE] - calling read_glyph on index 0 saved
168  // glyphs as _glyphs[0]. Setting _glyph_loader to nullptr here flags that
169  // the dtor needs to call delete[] on _glyphs[0] to release what was allocated
170  // as glyphs
171  }
172 
173  if (_glyphs && glyph(0) == 0)
174  {
175  free(_glyphs);
176  _glyphs = 0;
177  if (_boxes)
178  {
179  free(_boxes);
180  _boxes = 0;
181  }
182  _num_glyphs = _num_attrs = _upem = 0;
183  }
184 }
185 
186 
187 GlyphCache::~GlyphCache()
188 {
189  if (_glyphs)
190  {
191  if (_glyph_loader)
192  {
193  const GlyphFace * * g = _glyphs;
194  for(unsigned short n = _num_glyphs; n; --n, ++g)
195  delete *g;
196  }
197  else
198  delete [] _glyphs[0];
199  free(_glyphs);
200  }
201  if (_boxes)
202  {
203  if (_glyph_loader)
204  {
205  GlyphBox * * g = _boxes;
206  for (uint16 n = _num_glyphs; n; --n, ++g)
207  free(*g);
208  }
209  else
210  free(_boxes[0]);
211  free(_boxes);
212  }
213  delete _glyph_loader;
214 }
215 
216 const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
217 {
218  if (glyphid >= numGlyphs())
219  return _glyphs[0];
220  const GlyphFace * & p = _glyphs[glyphid];
221  if (p == 0 && _glyph_loader)
222  {
223  int numsubs = 0;
224  GlyphFace * g = new GlyphFace();
225  if (g) p = _glyph_loader->read_glyph(glyphid, *g, &numsubs);
226  if (!p)
227  {
228  delete g;
229  return *_glyphs;
230  }
231  if (_boxes)
232  {
233  _boxes[glyphid] = (GlyphBox *)gralloc<char>(sizeof(GlyphBox) + 8 * numsubs * sizeof(float));
234  if (!_glyph_loader->read_box(glyphid, _boxes[glyphid], *_glyphs[glyphid]))
235  {
236  free(_boxes[glyphid]);
237  _boxes[glyphid] = 0;
238  }
239  }
240  }
241  return p;
242 }
243 
244 
245 
247 : _head(face, Tag::head),
248  _hhea(face, Tag::hhea),
249  _hmtx(face, Tag::hmtx),
250  _glyf(face, Tag::glyf),
251  _loca(face, Tag::loca),
252  _long_fmt(false),
253  _has_boxes(false),
256  _num_attrs(0)
257 {
258  if (!operator bool())
259  return;
260 
261  const Face::Table maxp = Face::Table(face, Tag::maxp);
262  if (!maxp) { _head = Face::Table(); return; }
263 
264  _num_glyphs_graphics = static_cast<unsigned short>(TtfUtil::GlyphCount(maxp));
265  // This will fail if the number of glyphs is wildly out of range.
267  {
268  _head = Face::Table();
269  return;
270  }
271 
272  if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL
273  || (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL
274  || m_pGloc.size() < 8)
275  {
276  _head = Face::Table();
277  return;
278  }
279  const byte * p = m_pGloc;
280  int version = be::read<uint32>(p);
281  const uint16 flags = be::read<uint16>(p);
282  _num_attrs = be::read<uint16>(p);
283  // We can accurately calculate the number of attributed glyphs by
284  // subtracting the length of the attribids array (numAttribs long if present)
285  // and dividing by either 2 or 4 depending on shor or lonf format
286  _long_fmt = flags & 1;
287  ptrdiff_t tmpnumgattrs = (m_pGloc.size()
288  - (p - m_pGloc)
289  - sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
290  / (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
291 
292  if (version >= 0x00020000 || tmpnumgattrs < 0 || tmpnumgattrs > 65535
293  || _num_attrs == 0 || _num_attrs > 0x3000 // is this hard limit appropriate?
294  || _num_glyphs_graphics > tmpnumgattrs
295  || m_pGlat.size() < 4)
296  {
297  _head = Face::Table();
298  return;
299  }
300 
301  _num_glyphs_attributes = static_cast<unsigned short>(tmpnumgattrs);
302  p = m_pGlat;
303  version = be::read<uint32>(p);
304  if (version >= 0x00040000 || (version >= 0x00030000 && m_pGlat.size() < 8)) // reject Glat tables that are too new
305  {
306  _head = Face::Table();
307  return;
308  }
309  else if (version >= 0x00030000)
310  {
311  unsigned int glatflags = be::read<uint32>(p);
312  _has_boxes = glatflags & 1;
313  // delete this once the compiler is fixed
314  _has_boxes = true;
315  }
316 }
317 
318 inline
319 GlyphCache::Loader::operator bool () const throw()
320 {
321  return _head && _hhea && _hmtx && !(bool(_glyf) != bool(_loca));
322 }
323 
324 inline
325 unsigned short int GlyphCache::Loader::units_per_em() const throw()
326 {
327  return _head ? TtfUtil::DesignUnits(_head) : 0;
328 }
329 
330 inline
331 unsigned short int GlyphCache::Loader::num_glyphs() const throw()
332 {
333  return max(_num_glyphs_graphics, _num_glyphs_attributes);
334 }
335 
336 inline
337 unsigned short int GlyphCache::Loader::num_attrs() const throw()
338 {
339  return _num_attrs;
340 }
341 
342 inline
343 bool GlyphCache::Loader::has_boxes () const throw()
344 {
345  return _has_boxes;
346 }
347 
348 const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFace & glyph, int *numsubs) const throw()
349 {
350  Rect bbox;
352 
353  if (glyphid < _num_glyphs_graphics)
354  {
355  int nLsb;
356  unsigned int nAdvWid;
357  if (_glyf)
358  {
359  int xMin, yMin, xMax, yMax;
360  size_t locidx = TtfUtil::LocaLookup(glyphid, _loca, _loca.size(), _head);
361  void *pGlyph = TtfUtil::GlyfLookup(_glyf, locidx, _glyf.size());
362 
363  if (pGlyph && TtfUtil::GlyfBox(pGlyph, xMin, yMin, xMax, yMax))
364  {
365  if ((xMin > xMax) || (yMin > yMax))
366  return 0;
367  bbox = Rect(Position(static_cast<float>(xMin), static_cast<float>(yMin)),
368  Position(static_cast<float>(xMax), static_cast<float>(yMax)));
369  }
370  }
371  if (TtfUtil::HorMetrics(glyphid, _hmtx, _hmtx.size(), _hhea, nLsb, nAdvWid))
372  advance = Position(static_cast<float>(nAdvWid), 0);
373  }
374 
375  if (glyphid < _num_glyphs_attributes)
376  {
377  const byte * gloc = m_pGloc;
378  size_t glocs = 0, gloce = 0;
379 
380  be::skip<uint32>(gloc);
381  be::skip<uint16>(gloc,2);
382  if (_long_fmt)
383  {
384  if (8 + glyphid * sizeof(uint32) > m_pGloc.size())
385  return 0;
386  be::skip<uint32>(gloc, glyphid);
387  glocs = be::read<uint32>(gloc);
388  gloce = be::peek<uint32>(gloc);
389  }
390  else
391  {
392  if (8 + glyphid * sizeof(uint16) > m_pGloc.size())
393  return 0;
394  be::skip<uint16>(gloc, glyphid);
395  glocs = be::read<uint16>(gloc);
396  gloce = be::peek<uint16>(gloc);
397  }
398 
399  if (glocs >= m_pGlat.size() - 1 || gloce > m_pGlat.size())
400  return 0;
401 
402  const uint32 glat_version = be::peek<uint32>(m_pGlat);
403  if (glat_version >= 0x00030000)
404  {
405  if (glocs >= gloce)
406  return 0;
407  const byte * p = m_pGlat + glocs;
408  uint16 bmap = be::read<uint16>(p);
409  int num = bit_set_count((uint32)bmap);
410  if (numsubs) *numsubs += num;
411  glocs += 6 + 8 * num;
412  if (glocs > gloce)
413  return 0;
414  }
415  if (glat_version < 0x00020000)
416  {
417  if (gloce - glocs < 2*sizeof(byte)+sizeof(uint16)
418  || gloce - glocs > _num_attrs*(2*sizeof(byte)+sizeof(uint16)))
419  return 0;
420  new (&glyph) GlyphFace(bbox, advance, glat_iterator(m_pGlat + glocs), glat_iterator(m_pGlat + gloce));
421  }
422  else
423  {
424  if (gloce - glocs < 3*sizeof(uint16) // can a glyph have no attributes? why not?
425  || gloce - glocs > _num_attrs*3*sizeof(uint16)
426  || glocs > m_pGlat.size() - 2*sizeof(uint16))
427  return 0;
428  new (&glyph) GlyphFace(bbox, advance, glat2_iterator(m_pGlat + glocs), glat2_iterator(m_pGlat + gloce));
429  }
430  if (!glyph.attrs() || glyph.attrs().capacity() > _num_attrs)
431  return 0;
432  }
433  return &glyph;
434 }
435 
436 inline float scale_to(uint8 t, float zmin, float zmax)
437 {
438  return (zmin + t * (zmax - zmin) / 255);
439 }
440 
441 Rect readbox(Rect &b, uint8 zxmin, uint8 zymin, uint8 zxmax, uint8 zymax)
442 {
443  return Rect(Position(scale_to(zxmin, b.bl.x, b.tr.x), scale_to(zymin, b.bl.y, b.tr.y)),
444  Position(scale_to(zxmax, b.bl.x, b.tr.x), scale_to(zymax, b.bl.y, b.tr.y)));
445 }
446 
448 {
449  if (gid >= _num_glyphs_attributes) return 0;
450 
451  const byte * gloc = m_pGloc;
452  size_t glocs = 0, gloce = 0;
453 
454  be::skip<uint32>(gloc);
455  be::skip<uint16>(gloc,2);
456  if (_long_fmt)
457  {
458  be::skip<uint32>(gloc, gid);
459  glocs = be::read<uint32>(gloc);
460  gloce = be::peek<uint32>(gloc);
461  }
462  else
463  {
464  be::skip<uint16>(gloc, gid);
465  glocs = be::read<uint16>(gloc);
466  gloce = be::peek<uint16>(gloc);
467  }
468 
469  if (gloce > m_pGlat.size() || glocs + 6 >= gloce)
470  return 0;
471 
472  const byte * p = m_pGlat + glocs;
473  uint16 bmap = be::read<uint16>(p);
474  int num = bit_set_count((uint32)bmap);
475 
476  Rect bbox = glyph.theBBox();
477  Rect diamax(Position(bbox.bl.x + bbox.bl.y, bbox.bl.x - bbox.tr.y),
478  Position(bbox.tr.x + bbox.tr.y, bbox.tr.x - bbox.bl.y));
479  Rect diabound = readbox(diamax, p[0], p[2], p[1], p[3]);
480  ::new (curr) GlyphBox(num, bmap, &diabound);
481  be::skip<uint8>(p, 4);
482  if (glocs + 6 + num * 8 >= gloce)
483  return 0;
484 
485  for (int i = 0; i < num * 2; ++i)
486  {
487  Rect box = readbox((i & 1) ? diamax : bbox, p[0], p[2], p[1], p[3]);
488  curr->addSubBox(i >> 1, i & 1, &box);
489  be::skip<uint8>(p, 4);
490  }
491  return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect));
492 }
int ptrdiff_t
Definition: CPAL.d:3845
#define empty
Definition: aptex-macros.h:52
#define advance
Definition: aptex-macros.h:464
mp_limb_t operator*(mp_limb_t lhs, const mp_limb_t &rhs)
Definition: asl.h:120
#define bool
Definition: autosp.c:101
unsigned short _num_glyphs_graphics
Definition: GlyphCache.cpp:110
const GlyphFace * read_glyph(unsigned short gid, GlyphFace &, int *numsubs) const
Definition: GlyphCache.cpp:348
unsigned short int num_attrs() const
Definition: GlyphCache.cpp:337
unsigned short int num_glyphs() const
Definition: GlyphCache.cpp:331
unsigned short _num_glyphs_attributes
Definition: GlyphCache.cpp:111
unsigned short int units_per_em() const
Definition: GlyphCache.cpp:325
GlyphBox * read_box(uint16 gid, GlyphBox *curr, const GlyphFace &face) const
Definition: GlyphCache.cpp:447
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
#define free(a)
Definition: decNumber.cpp:310
void glyphs(int opcode)
Definition: disdvi.c:775
#define W
Definition: dtl.h:141
static FIELD_PTR curr
Definition: genind.c:35
bool operator!=(const GenBuffer &s1, const GenBuffer &s2)
Definition: gensi.hpp:716
bool operator==(const GenBuffer &s1, const GenBuffer &s2)
Definition: gensi.hpp:671
#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
sizeof(AF_ModuleRec)
FT_BBox bbox
Definition: ftbbox.c:467
FT_Face face
Definition: cffdrivr.c:659
#define const
Definition: ftzconf.h:91
#define false
Definition: ftrandom.c:52
int num
Definition: disdvi.c:621
void * new(uint32_t size)
Definition: mem.c:34
unsigned char byte
Definition: tif_acorn.c:69
unsigned short uint16
Definition: tiff.h:62
unsigned long uint32
Definition: tiff.h:68
unsigned char uint8
Definition: tiff.h:60
#define uint32
Definition: unibasics.h:49
#define uint16
Definition: unibasics.h:51
#define size_t
Definition: glob.c:257
bool HorMetrics(gid16 nGlyphId, const void *pHmtx, size_t lHmtxSize, const void *pHhea, int &nLsb, unsigned int &nAdvWid)
Definition: TtfUtil.cpp:806
void * GlyfLookup(const void *pGlyf, size_t lGlyfOffset, size_t lTableLen)
Definition: TtfUtil.cpp:1252
size_t LocaLookup(gid16 nGlyphId, const void *pLoca, size_t lLocaSize, const void *pHead)
Definition: TtfUtil.cpp:1214
size_t GlyphCount(const void *pMaxp)
Definition: TtfUtil.cpp:361
int DesignUnits(const void *pHead)
Definition: TtfUtil.cpp:425
bool GlyfBox(const void *pSimpleGlyf, int &xMin, int &yMin, int &xMax, int &yMax)
Definition: TtfUtil.cpp:1264
Definition: bits.h:30
T * grzeroalloc(size_t n)
Definition: Main.h:137
unsigned int bit_set_count(T v)
Definition: bits.h:80
gr_uint16 uint16
Definition: Main.h:40
gr_uint32 uint32
Definition: Main.h:41
#define version
Definition: nup.c:10
#define max(a, b)
Definition: pbmto4425.c:11
int g
Definition: ppmqvga.c:68
@ gr_face_preloadGlyphs
Definition: Font.h:62
Rect readbox(Rect &b, uint8 zxmin, uint8 zymin, uint8 zxmax, uint8 zymax)
Definition: GlyphCache.cpp:441
float scale_to(uint8 t, float zmin, float zmax)
Definition: GlyphCache.cpp:436
#define flags
#define CLASS_NEW_DELETE
Definition: Main.h:159
struct Table Table
Definition: lobject.h:497
GLYF glyf
Definition: gcache.h:17
Definition: nsfix.c:44
Definition: jquant2.c:258
Definition: pbmfont.h:4
Definition: ttf.h:354
Definition: ttf.h:315
Definition: ttf.h:413
Definition: psfont.h:67
Definition: dvips.h:235
#define key
Definition: tex2xindy.c:753
int run(char *cmd)
Definition: texdocc.c:233
TT_Glyph glyph
Definition: ttf2pfb.c:162