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     {
key() const49         unsigned short  key() const             { return uint16(be::peek<W>(_e) + _n); }
run() const50         unsigned int    run() const             { return be::peek<W>(_e+sizeof(W)); }
advance_entry()51         void            advance_entry()         { _n = 0; _e = _v; be::skip<W>(_v,2); }
52     public:
_glat_iterator(const void * glat=0)53         _glat_iterator(const void * glat=0) : _e(reinterpret_cast<const byte *>(glat)), _v(_e+2*sizeof(W)), _n(0) {}
54 
operator ++()55         _glat_iterator<W> & operator ++ () {
56             ++_n; be::skip<uint16>(_v);
57             if (_n == run()) advance_entry();
58             return *this;
59         }
operator ++(int)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.
operator ==(const _glat_iterator<W> & rhs)65         bool operator == (const _glat_iterator<W> & rhs) { return _v >= rhs._e - 1; }
operator !=(const _glat_iterator<W> & rhs)66         bool operator != (const _glat_iterator<W> & rhs) { return !operator==(rhs); }
67 
operator *() const68         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 
84 class GlyphCache::Loader
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();
96     GlyphBox * read_box(uint16 gid, GlyphBox *curr, const GlyphFace & face) const throw();
97 
98     CLASS_NEW_DELETE;
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
111                     _num_glyphs_attributes,
112                     _num_attrs;                    // number of glyph attributes per glyph
113 };
114 
115 
116 
GlyphCache(const Face & face,const uint32 face_options)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 
~GlyphCache()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 
glyph(unsigned short glyphid) const216 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 
Loader(const Face & face)246 GlyphCache::Loader::Loader(const Face & face)
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),
254   _num_glyphs_graphics(0),
255   _num_glyphs_attributes(0),
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.
266     if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-2))
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
operator bool() const319 GlyphCache::Loader::operator bool () const throw()
320 {
321     return _head && _hhea && _hmtx && !(bool(_glyf) != bool(_loca));
322 }
323 
324 inline
units_per_em() const325 unsigned short int GlyphCache::Loader::units_per_em() const throw()
326 {
327     return _head ? TtfUtil::DesignUnits(_head) : 0;
328 }
329 
330 inline
num_glyphs() const331 unsigned short int GlyphCache::Loader::num_glyphs() const throw()
332 {
333     return max(_num_glyphs_graphics, _num_glyphs_attributes);
334 }
335 
336 inline
num_attrs() const337 unsigned short int GlyphCache::Loader::num_attrs() const throw()
338 {
339     return _num_attrs;
340 }
341 
342 inline
has_boxes() const343 bool GlyphCache::Loader::has_boxes () const throw()
344 {
345     return _has_boxes;
346 }
347 
read_glyph(unsigned short glyphid,GlyphFace & glyph,int * numsubs) const348 const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFace & glyph, int *numsubs) const throw()
349 {
350     Rect        bbox;
351     Position    advance;
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 
scale_to(uint8 t,float zmin,float zmax)436 inline float scale_to(uint8 t, float zmin, float zmax)
437 {
438     return (zmin + t * (zmax - zmin) / 255);
439 }
440 
readbox(Rect & b,uint8 zxmin,uint8 zymin,uint8 zxmax,uint8 zymax)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 
read_box(uint16 gid,GlyphBox * curr,const GlyphFace & glyph) const447 GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphFace & glyph) const throw()
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 }
493