Coverage Report

Created: 2023-12-14 14:03

/src/harfbuzz/src/hb-ot-cff-common.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2018 Adobe Inc.
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 *
24
 * Adobe Author(s): Michiharu Ariza
25
 */
26
#ifndef HB_OT_CFF_COMMON_HH
27
#define HB_OT_CFF_COMMON_HH
28
29
#include "hb-open-type.hh"
30
#include "hb-bimap.hh"
31
#include "hb-ot-layout-common.hh"
32
#include "hb-cff-interp-dict-common.hh"
33
#include "hb-subset-plan.hh"
34
35
namespace CFF {
36
37
using namespace OT;
38
39
5.40M
#define CFF_UNDEF_CODE  0xFFFFFFFF
40
41
using objidx_t = hb_serialize_context_t::objidx_t;
42
using whence_t = hb_serialize_context_t::whence_t;
43
44
/* utility macro */
45
template<typename Type>
46
static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset)
47
2.25M
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
Unexecuted instantiation: hb-ot-face.cc:CFF::Charset const& CFF::StructAtOffsetOrNull<CFF::Charset>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFF1FDArray const& CFF::StructAtOffsetOrNull<CFF::CFF1FDArray>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFF1FDSelect const& CFF::StructAtOffsetOrNull<CFF::CFF1FDSelect>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::Encoding const& CFF::StructAtOffsetOrNull<CFF::Encoding>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFFIndex<OT::IntType<unsigned short, 2u> > const& CFF::StructAtOffsetOrNull<CFF::CFFIndex<OT::IntType<unsigned short, 2u> > >(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::Subrs<OT::IntType<unsigned short, 2u> > const& CFF::StructAtOffsetOrNull<CFF::Subrs<OT::IntType<unsigned short, 2u> > >(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFF2VariationStore const& CFF::StructAtOffsetOrNull<CFF::CFF2VariationStore>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFFIndex<OT::IntType<unsigned int, 4u> > const& CFF::StructAtOffsetOrNull<CFF::CFFIndex<OT::IntType<unsigned int, 4u> > >(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFF2FDArray const& CFF::StructAtOffsetOrNull<CFF::CFF2FDArray>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::CFF2FDSelect const& CFF::StructAtOffsetOrNull<CFF::CFF2FDSelect>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::UnsizedByteStr const& CFF::StructAtOffsetOrNull<CFF::UnsizedByteStr>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-face.cc:CFF::Subrs<OT::IntType<unsigned int, 4u> > const& CFF::StructAtOffsetOrNull<CFF::Subrs<OT::IntType<unsigned int, 4u> > >(void const*, unsigned int)
hb-ot-font.cc:CFF::Charset const& CFF::StructAtOffsetOrNull<CFF::Charset>(void const*, unsigned int)
Line
Count
Source
47
32.5k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFF1FDArray const& CFF::StructAtOffsetOrNull<CFF::CFF1FDArray>(void const*, unsigned int)
Line
Count
Source
47
4.63k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFF1FDSelect const& CFF::StructAtOffsetOrNull<CFF::CFF1FDSelect>(void const*, unsigned int)
Line
Count
Source
47
4.63k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::Encoding const& CFF::StructAtOffsetOrNull<CFF::Encoding>(void const*, unsigned int)
Line
Count
Source
47
444
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFFIndex<OT::IntType<unsigned short, 2u> > const& CFF::StructAtOffsetOrNull<CFF::CFFIndex<OT::IntType<unsigned short, 2u> > >(void const*, unsigned int)
Line
Count
Source
47
31.5k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::Subrs<OT::IntType<unsigned short, 2u> > const& CFF::StructAtOffsetOrNull<CFF::Subrs<OT::IntType<unsigned short, 2u> > >(void const*, unsigned int)
Line
Count
Source
47
329k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFF2VariationStore const& CFF::StructAtOffsetOrNull<CFF::CFF2VariationStore>(void const*, unsigned int)
Line
Count
Source
47
34.2k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFFIndex<OT::IntType<unsigned int, 4u> > const& CFF::StructAtOffsetOrNull<CFF::CFFIndex<OT::IntType<unsigned int, 4u> > >(void const*, unsigned int)
Line
Count
Source
47
34.2k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFF2FDArray const& CFF::StructAtOffsetOrNull<CFF::CFF2FDArray>(void const*, unsigned int)
Line
Count
Source
47
34.2k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::CFF2FDSelect const& CFF::StructAtOffsetOrNull<CFF::CFF2FDSelect>(void const*, unsigned int)
Line
Count
Source
47
34.2k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::UnsizedByteStr const& CFF::StructAtOffsetOrNull<CFF::UnsizedByteStr>(void const*, unsigned int)
Line
Count
Source
47
857k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
hb-ot-font.cc:CFF::Subrs<OT::IntType<unsigned int, 4u> > const& CFF::StructAtOffsetOrNull<CFF::Subrs<OT::IntType<unsigned int, 4u> > >(void const*, unsigned int)
Line
Count
Source
47
856k
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
Unexecuted instantiation: hb-ot-cff1-table.cc:CFF::Charset const& CFF::StructAtOffsetOrNull<CFF::Charset>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff1-table.cc:CFF::CFF1FDArray const& CFF::StructAtOffsetOrNull<CFF::CFF1FDArray>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff1-table.cc:CFF::CFF1FDSelect const& CFF::StructAtOffsetOrNull<CFF::CFF1FDSelect>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff1-table.cc:CFF::Encoding const& CFF::StructAtOffsetOrNull<CFF::Encoding>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff1-table.cc:CFF::CFFIndex<OT::IntType<unsigned short, 2u> > const& CFF::StructAtOffsetOrNull<CFF::CFFIndex<OT::IntType<unsigned short, 2u> > >(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff1-table.cc:CFF::Subrs<OT::IntType<unsigned short, 2u> > const& CFF::StructAtOffsetOrNull<CFF::Subrs<OT::IntType<unsigned short, 2u> > >(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff2-table.cc:CFF::CFF2VariationStore const& CFF::StructAtOffsetOrNull<CFF::CFF2VariationStore>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff2-table.cc:CFF::CFFIndex<OT::IntType<unsigned int, 4u> > const& CFF::StructAtOffsetOrNull<CFF::CFFIndex<OT::IntType<unsigned int, 4u> > >(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff2-table.cc:CFF::CFF2FDArray const& CFF::StructAtOffsetOrNull<CFF::CFF2FDArray>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff2-table.cc:CFF::CFF2FDSelect const& CFF::StructAtOffsetOrNull<CFF::CFF2FDSelect>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff2-table.cc:CFF::UnsizedByteStr const& CFF::StructAtOffsetOrNull<CFF::UnsizedByteStr>(void const*, unsigned int)
Unexecuted instantiation: hb-ot-cff2-table.cc:CFF::Subrs<OT::IntType<unsigned int, 4u> > const& CFF::StructAtOffsetOrNull<CFF::Subrs<OT::IntType<unsigned int, 4u> > >(void const*, unsigned int)
48
49
struct code_pair_t
50
{
51
  hb_codepoint_t code;
52
  hb_codepoint_t glyph;
53
};
54
55
using str_buff_t = hb_vector_t<unsigned char>;
56
using str_buff_vec_t = hb_vector_t<str_buff_t>;
57
58
/* CFF INDEX */
59
template <typename COUNT>
60
struct CFFIndex
61
{
62
  unsigned int offset_array_size () const
63
6.57M
  { return offSize * (count + 1); }
CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::offset_array_size() const
Line
Count
Source
63
4.53M
  { return offSize * (count + 1); }
CFF::CFFIndex<OT::IntType<unsigned int, 4u> >::offset_array_size() const
Line
Count
Source
63
2.03M
  { return offSize * (count + 1); }
64
65
  CFFIndex *copy (hb_serialize_context_t *c) const
66
  {
67
    TRACE_SERIALIZE (this);
68
    unsigned int size = get_size ();
69
    CFFIndex *out = c->allocate_size<CFFIndex> (size, false);
70
    if (likely (out))
71
      hb_memcpy (out, this, size);
72
    return_trace (out);
73
  }
74
75
  template <typename Iterable,
76
      hb_requires (hb_is_iterable (Iterable))>
77
  bool serialize (hb_serialize_context_t *c,
78
      const Iterable &iterable)
79
0
  {
80
0
    TRACE_SERIALIZE (this);
81
0
    auto it = hb_iter (iterable);
82
0
    serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len));
83
0
    for (const auto &_ : +it)
84
0
      hb_iter (_).copy (c);
85
0
    return_trace (true);
86
0
  }
87
88
  template <typename Iterator,
89
      hb_requires (hb_is_iterator (Iterator))>
90
  bool serialize_header (hb_serialize_context_t *c,
91
      Iterator it)
92
0
  {
93
0
    TRACE_SERIALIZE (this);
94
0
95
0
    unsigned total = + it | hb_reduce (hb_add, 0);
96
0
    unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
97
0
98
0
    /* serialize CFFIndex header */
99
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
100
0
    this->count = it.len ();
101
0
    if (!this->count) return_trace (true);
102
0
    if (unlikely (!c->extend (this->offSize))) return_trace (false);
103
0
    this->offSize = off_size;
104
0
    if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1), false)))
105
0
      return_trace (false);
106
0
107
0
    /* serialize indices */
108
0
    unsigned int offset = 1;
109
0
    unsigned int i = 0;
110
0
    for (unsigned _ : +it)
111
0
    {
112
0
      set_offset_at (i++, offset);
113
0
      offset += _;
114
0
    }
115
0
    set_offset_at (i, offset);
116
0
117
0
    return_trace (true);
118
0
  }
Unexecuted instantiation: hb-ot-face.cc:bool CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::serialize_header<hb_map_iter_t<hb_map_iter_t<hb_array_t<hb_array_t<unsigned char const> const>, $_9 const&, (hb_function_sortedness_t)0, (void*)0>, $_33 const&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_array_t<hb_array_t<unsigned char const> const>, $_9 const&, (hb_function_sortedness_t)0, (void*)0>, $_33 const&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-font.cc:bool CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::serialize_header<hb_map_iter_t<hb_map_iter_t<hb_array_t<hb_array_t<unsigned char const> const>, $_8 const&, (hb_function_sortedness_t)0, (void*)0>, $_33 const&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_array_t<hb_array_t<unsigned char const> const>, $_8 const&, (hb_function_sortedness_t)0, (void*)0>, $_33 const&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-cff1-table.cc:bool CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::serialize_header<hb_map_iter_t<hb_map_iter_t<hb_array_t<hb_array_t<unsigned char const> const>, $_8 const&, (hb_function_sortedness_t)0, (void*)0>, $_34 const&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_array_t<hb_array_t<unsigned char const> const>, $_8 const&, (hb_function_sortedness_t)0, (void*)0>, $_34 const&, (hb_function_sortedness_t)0, (void*)0>)
119
120
  template <typename Iterable,
121
      hb_requires (hb_is_iterable (Iterable))>
122
  static unsigned total_size (const Iterable &iterable)
123
  {
124
    auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len);
125
    if (!it) return 0;
126
127
    unsigned total = + it | hb_reduce (hb_add, 0);
128
    unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
129
130
    return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total;
131
  }
132
133
  void set_offset_at (unsigned int index, unsigned int offset)
134
0
  {
135
0
    assert (index <= count);
136
0
    HBUINT8 *p = offsets + offSize * index + offSize;
137
0
    unsigned int size = offSize;
138
0
    for (; size; size--)
139
0
    {
140
0
      --p;
141
0
      *p = offset & 0xFF;
142
0
      offset >>= 8;
143
0
    }
144
0
  }
145
146
  private:
147
  unsigned int offset_at (unsigned int index) const
148
28.4M
  {
149
28.4M
    assert (index <= count);
150
151
0
    unsigned int size = offSize;
152
28.4M
    const HBUINT8 *p = offsets + size * index;
153
28.4M
    switch (size)
154
28.4M
    {
155
7.43M
      case 1: return * (HBUINT8  *) p;
156
17.8M
      case 2: return * (HBUINT16 *) p;
157
313k
      case 3: return * (HBUINT24 *) p;
158
2.88M
      case 4: return * (HBUINT32 *) p;
159
0
      default: return 0;
160
28.4M
    }
161
28.4M
  }
CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::offset_at(unsigned int) const
Line
Count
Source
148
18.1M
  {
149
18.1M
    assert (index <= count);
150
151
0
    unsigned int size = offSize;
152
18.1M
    const HBUINT8 *p = offsets + size * index;
153
18.1M
    switch (size)
154
18.1M
    {
155
1.42M
      case 1: return * (HBUINT8  *) p;
156
13.6M
      case 2: return * (HBUINT16 *) p;
157
198k
      case 3: return * (HBUINT24 *) p;
158
2.86M
      case 4: return * (HBUINT32 *) p;
159
0
      default: return 0;
160
18.1M
    }
161
18.1M
  }
CFF::CFFIndex<OT::IntType<unsigned int, 4u> >::offset_at(unsigned int) const
Line
Count
Source
148
10.3M
  {
149
10.3M
    assert (index <= count);
150
151
0
    unsigned int size = offSize;
152
10.3M
    const HBUINT8 *p = offsets + size * index;
153
10.3M
    switch (size)
154
10.3M
    {
155
6.00M
      case 1: return * (HBUINT8  *) p;
156
4.19M
      case 2: return * (HBUINT16 *) p;
157
115k
      case 3: return * (HBUINT24 *) p;
158
15.1k
      case 4: return * (HBUINT32 *) p;
159
0
      default: return 0;
160
10.3M
    }
161
10.3M
  }
162
163
  unsigned int length_at (unsigned int index) const
164
7.48M
  {
165
7.48M
    unsigned offset0 = offset_at (index);
166
7.48M
    unsigned offset1 = offset_at (index + 1);
167
7.48M
    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
168
904k
      return 0;
169
6.57M
    return offset1 - offset0;
170
7.48M
  }
CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::length_at(unsigned int) const
Line
Count
Source
164
4.58M
  {
165
4.58M
    unsigned offset0 = offset_at (index);
166
4.58M
    unsigned offset1 = offset_at (index + 1);
167
4.58M
    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
168
281k
      return 0;
169
4.30M
    return offset1 - offset0;
170
4.58M
  }
CFF::CFFIndex<OT::IntType<unsigned int, 4u> >::length_at(unsigned int) const
Line
Count
Source
164
2.89M
  {
165
2.89M
    unsigned offset0 = offset_at (index);
166
2.89M
    unsigned offset1 = offset_at (index + 1);
167
2.89M
    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
168
622k
      return 0;
169
2.27M
    return offset1 - offset0;
170
2.89M
  }
171
172
  const unsigned char *data_base () const
173
6.46M
  { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); }
CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::data_base() const
Line
Count
Source
173
4.43M
  { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); }
CFF::CFFIndex<OT::IntType<unsigned int, 4u> >::data_base() const
Line
Count
Source
173
2.03M
  { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); }
174
  public:
175
176
  hb_ubytes_t operator [] (unsigned int index) const
177
7.88M
  {
178
7.88M
    if (unlikely (index >= count)) return hb_ubytes_t ();
179
7.48M
    _hb_compiler_memory_r_barrier ();
180
7.48M
    unsigned length = length_at (index);
181
7.48M
    if (unlikely (!length)) return hb_ubytes_t ();
182
6.19M
    return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
183
7.48M
  }
CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::operator[](unsigned int) const
Line
Count
Source
177
4.99M
  {
178
4.99M
    if (unlikely (index >= count)) return hb_ubytes_t ();
179
4.58M
    _hb_compiler_memory_r_barrier ();
180
4.58M
    unsigned length = length_at (index);
181
4.58M
    if (unlikely (!length)) return hb_ubytes_t ();
182
4.24M
    return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
183
4.58M
  }
CFF::CFFIndex<OT::IntType<unsigned int, 4u> >::operator[](unsigned int) const
Line
Count
Source
177
2.89M
  {
178
2.89M
    if (unlikely (index >= count)) return hb_ubytes_t ();
179
2.89M
    _hb_compiler_memory_r_barrier ();
180
2.89M
    unsigned length = length_at (index);
181
2.89M
    if (unlikely (!length)) return hb_ubytes_t ();
182
1.95M
    return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
183
2.89M
  }
184
185
  unsigned int get_size () const
186
101k
  {
187
101k
    if (count)
188
100k
      return min_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1);
189
398
    return min_size;  /* empty CFFIndex contains count only */
190
101k
  }
191
192
  bool sanitize (hb_sanitize_context_t *c) const
193
330k
  {
194
330k
    TRACE_SANITIZE (this);
195
330k
    return_trace (likely (c->check_struct (this) &&
196
330k
        (count == 0 || /* empty INDEX */
197
330k
         (count < count + 1u &&
198
330k
          c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 &&
199
330k
          c->check_array (offsets, offSize, count + 1u) &&
200
330k
          c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1)))));
201
330k
  }
CFF::CFFIndex<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
193
215k
  {
194
215k
    TRACE_SANITIZE (this);
195
215k
    return_trace (likely (c->check_struct (this) &&
196
215k
        (count == 0 || /* empty INDEX */
197
215k
         (count < count + 1u &&
198
215k
          c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 &&
199
215k
          c->check_array (offsets, offSize, count + 1u) &&
200
215k
          c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1)))));
201
215k
  }
CFF::CFFIndex<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
193
115k
  {
194
115k
    TRACE_SANITIZE (this);
195
115k
    return_trace (likely (c->check_struct (this) &&
196
115k
        (count == 0 || /* empty INDEX */
197
115k
         (count < count + 1u &&
198
115k
          c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 &&
199
115k
          c->check_array (offsets, offSize, count + 1u) &&
200
115k
          c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1)))));
201
115k
  }
202
203
  public:
204
  COUNT   count;    /* Number of object data. Note there are (count+1) offsets */
205
  private:
206
  HBUINT8 offSize;  /* The byte size of each offset in the offsets array. */
207
  HBUINT8 offsets[HB_VAR_ARRAY];
208
        /* The array of (count + 1) offsets into objects array (1-base). */
209
  /* HBUINT8 data[HB_VAR_ARRAY];  Object data */
210
  public:
211
  DEFINE_SIZE_MIN (COUNT::static_size);
212
};
213
214
template <typename COUNT, typename TYPE>
215
struct CFFIndexOf : CFFIndex<COUNT>
216
{
217
  template <typename DATA, typename PARAM1, typename PARAM2>
218
  bool serialize (hb_serialize_context_t *c,
219
      unsigned int offSize_,
220
      const DATA *dataArray,
221
      unsigned int dataArrayLen,
222
      const hb_vector_t<unsigned int> &dataSizeArray,
223
      const PARAM1 &param1,
224
      const PARAM2 &param2)
225
  {
226
    TRACE_SERIALIZE (this);
227
    /* serialize CFFIndex header */
228
    if (unlikely (!c->extend_min (this))) return_trace (false);
229
    this->count = dataArrayLen;
230
    this->offSize = offSize_;
231
    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false)))
232
      return_trace (false);
233
234
    /* serialize indices */
235
    unsigned int  offset = 1;
236
    unsigned int  i = 0;
237
    for (; i < dataArrayLen; i++)
238
    {
239
      this->set_offset_at (i, offset);
240
      offset += dataSizeArray[i];
241
    }
242
    this->set_offset_at (i, offset);
243
244
    /* serialize data */
245
    for (unsigned int i = 0; i < dataArrayLen; i++)
246
    {
247
      TYPE *dest = c->start_embed<TYPE> ();
248
      if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2)))
249
  return_trace (false);
250
    }
251
    return_trace (true);
252
  }
253
};
254
255
/* Top Dict, Font Dict, Private Dict */
256
struct Dict : UnsizedByteStr
257
{
258
  template <typename DICTVAL, typename OP_SERIALIZER, typename ...Ts>
259
  bool serialize (hb_serialize_context_t *c,
260
      const DICTVAL &dictval,
261
      OP_SERIALIZER& opszr,
262
      Ts&&... ds)
263
  {
264
    TRACE_SERIALIZE (this);
265
    for (unsigned int i = 0; i < dictval.get_count (); i++)
266
      if (unlikely (!opszr.serialize (c, dictval[i], std::forward<Ts> (ds)...)))
267
  return_trace (false);
268
269
    return_trace (true);
270
  }
271
272
  template <typename T, typename V>
273
  static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp)
274
0
  {
275
0
    if (unlikely ((!serialize_int<T, V> (c, intOp, value))))
276
0
      return false;
277
0
278
0
    TRACE_SERIALIZE (this);
279
0
    /* serialize the opcode */
280
0
    HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op), false);
281
0
    if (unlikely (!p)) return_trace (false);
282
0
    if (Is_OpCode_ESC (op))
283
0
    {
284
0
      *p = OpCode_escape;
285
0
      op = Unmake_OpCode_ESC (op);
286
0
      p++;
287
0
    }
288
0
    *p = op;
289
0
    return_trace (true);
290
0
  }
Unexecuted instantiation: bool CFF::Dict::serialize_int_op<OT::IntType<int, 4u>, int>(hb_serialize_context_t*, unsigned int, int, unsigned int)
Unexecuted instantiation: bool CFF::Dict::serialize_int_op<OT::IntType<short, 2u>, int>(hb_serialize_context_t*, unsigned int, int, unsigned int)
291
292
  template <typename V>
293
  static bool serialize_int4_op (hb_serialize_context_t *c, op_code_t op, V value)
294
  { return serialize_int_op<HBINT32> (c, op, value, OpCode_longintdict); }
295
296
  template <typename V>
297
  static bool serialize_int2_op (hb_serialize_context_t *c, op_code_t op, V value)
298
  { return serialize_int_op<HBINT16> (c, op, value, OpCode_shortint); }
299
300
  template <typename T, int int_op>
301
  static bool serialize_link_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence)
302
0
  {
303
0
    T &ofs = *(T *) (c->head + OpCode_Size (int_op));
304
0
    if (unlikely (!serialize_int_op<T> (c, op, 0, int_op))) return false;
305
0
    c->add_link (ofs, link, whence);
306
0
    return true;
307
0
  }
Unexecuted instantiation: bool CFF::Dict::serialize_link_op<OT::IntType<int, 4u>, 29>(hb_serialize_context_t*, unsigned int, unsigned int, hb_serialize_context_t::whence_t)
Unexecuted instantiation: bool CFF::Dict::serialize_link_op<OT::IntType<short, 2u>, 28>(hb_serialize_context_t*, unsigned int, unsigned int, hb_serialize_context_t::whence_t)
308
309
  static bool serialize_link4_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head)
310
0
  { return serialize_link_op<HBINT32, OpCode_longintdict> (c, op, link, whence); }
311
312
  static bool serialize_link2_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head)
313
0
  { return serialize_link_op<HBINT16, OpCode_shortint> (c, op, link, whence); }
314
};
315
316
struct TopDict : Dict {};
317
struct FontDict : Dict {};
318
struct PrivateDict : Dict {};
319
320
struct table_info_t
321
{
322
2.74M
  void init () { offset = size = 0; link = 0; }
323
324
  unsigned int    offset;
325
  unsigned int    size;
326
  objidx_t    link;
327
};
328
329
template <typename COUNT>
330
struct FDArray : CFFIndexOf<COUNT, FontDict>
331
{
332
  template <typename DICTVAL, typename INFO, typename Iterator, typename OP_SERIALIZER>
333
  bool serialize (hb_serialize_context_t *c,
334
      Iterator it,
335
      OP_SERIALIZER& opszr)
336
  {
337
    TRACE_SERIALIZE (this);
338
339
    /* serialize INDEX data */
340
    hb_vector_t<unsigned> sizes;
341
    c->push ();
342
    + it
343
    | hb_map ([&] (const hb_pair_t<const DICTVAL&, const INFO&> &_)
344
    {
345
      FontDict *dict = c->start_embed<FontDict> ();
346
    dict->serialize (c, _.first, opszr, _.second);
347
    return c->head - (const char*)dict;
348
        })
349
    | hb_sink (sizes)
350
    ;
351
    c->pop_pack (false);
352
353
    /* serialize INDEX header */
354
    return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes)));
355
  }
356
};
357
358
/* FDSelect */
359
struct FDSelect0 {
360
  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
361
1.28k
  {
362
1.28k
    TRACE_SANITIZE (this);
363
1.28k
    if (unlikely (!(c->check_struct (this))))
364
0
      return_trace (false);
365
1.28k
    if (unlikely (!c->check_array (fds, c->get_num_glyphs ())))
366
21
      return_trace (false);
367
368
1.28k
    return_trace (true);
369
1.28k
  }
370
371
  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
372
941
  { return (hb_codepoint_t) fds[glyph]; }
373
374
  unsigned int get_size (unsigned int num_glyphs) const
375
0
  { return HBUINT8::static_size * num_glyphs; }
376
377
  HBUINT8     fds[HB_VAR_ARRAY];
378
379
  DEFINE_SIZE_MIN (0);
380
};
381
382
template <typename GID_TYPE, typename FD_TYPE>
383
struct FDSelect3_4_Range
384
{
385
  bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
386
68.7k
  {
387
68.7k
    TRACE_SANITIZE (this);
388
68.7k
    return_trace (first < c->get_num_glyphs () && (fd < fdcount));
389
68.7k
  }
CFF::FDSelect3_4_Range<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::sanitize(hb_sanitize_context_t*, void const*, unsigned int) const
Line
Count
Source
386
68.7k
  {
387
68.7k
    TRACE_SANITIZE (this);
388
68.7k
    return_trace (first < c->get_num_glyphs () && (fd < fdcount));
389
68.7k
  }
CFF::FDSelect3_4_Range<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*, void const*, unsigned int) const
Line
Count
Source
386
8
  {
387
8
    TRACE_SANITIZE (this);
388
8
    return_trace (first < c->get_num_glyphs () && (fd < fdcount));
389
8
  }
390
391
  GID_TYPE    first;
392
  FD_TYPE     fd;
393
  public:
394
  DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size);
395
};
396
397
template <typename GID_TYPE, typename FD_TYPE>
398
struct FDSelect3_4
399
{
400
  unsigned int get_size () const
401
0
  { return GID_TYPE::static_size * 2 + ranges.get_size (); }
Unexecuted instantiation: CFF::FDSelect3_4<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::get_size() const
Unexecuted instantiation: CFF::FDSelect3_4<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::get_size() const
402
403
  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
404
2.99k
  {
405
2.99k
    TRACE_SANITIZE (this);
406
2.99k
    if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) ||
407
2.99k
      (nRanges () == 0) || ranges[0].first != 0))
408
190
      return_trace (false);
409
410
59.5k
    for (unsigned int i = 1; i < nRanges (); i++)
411
56.7k
      if (unlikely (ranges[i - 1].first >= ranges[i].first))
412
42
  return_trace (false);
413
414
2.76k
    if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
415
19
      return_trace (false);
416
417
2.76k
    return_trace (true);
418
2.76k
  }
CFF::FDSelect3_4<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::sanitize(hb_sanitize_context_t*, unsigned int) const
Line
Count
Source
404
2.95k
  {
405
2.95k
    TRACE_SANITIZE (this);
406
2.95k
    if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) ||
407
2.95k
      (nRanges () == 0) || ranges[0].first != 0))
408
150
      return_trace (false);
409
410
59.5k
    for (unsigned int i = 1; i < nRanges (); i++)
411
56.7k
      if (unlikely (ranges[i - 1].first >= ranges[i].first))
412
42
  return_trace (false);
413
414
2.76k
    if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
415
19
      return_trace (false);
416
417
2.74k
    return_trace (true);
418
2.76k
  }
CFF::FDSelect3_4<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*, unsigned int) const
Line
Count
Source
404
40
  {
405
40
    TRACE_SANITIZE (this);
406
40
    if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) ||
407
40
      (nRanges () == 0) || ranges[0].first != 0))
408
40
      return_trace (false);
409
410
0
    for (unsigned int i = 1; i < nRanges (); i++)
411
0
      if (unlikely (ranges[i - 1].first >= ranges[i].first))
412
0
  return_trace (false);
413
414
0
    if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
415
0
      return_trace (false);
416
417
0
    return_trace (true);
418
0
  }
419
420
  static int _cmp_range (const void *_key, const void *_item)
421
2.54k
  {
422
2.54k
    hb_codepoint_t glyph = * (hb_codepoint_t *) _key;
423
2.54k
    FDSelect3_4_Range<GID_TYPE, FD_TYPE> *range = (FDSelect3_4_Range<GID_TYPE, FD_TYPE> *) _item;
424
425
2.54k
    if (glyph < range[0].first) return -1;
426
2.29k
    if (glyph < range[1].first) return 0;
427
625
    return +1;
428
2.29k
  }
CFF::FDSelect3_4<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::_cmp_range(void const*, void const*)
Line
Count
Source
421
2.54k
  {
422
2.54k
    hb_codepoint_t glyph = * (hb_codepoint_t *) _key;
423
2.54k
    FDSelect3_4_Range<GID_TYPE, FD_TYPE> *range = (FDSelect3_4_Range<GID_TYPE, FD_TYPE> *) _item;
424
425
2.54k
    if (glyph < range[0].first) return -1;
426
2.29k
    if (glyph < range[1].first) return 0;
427
625
    return +1;
428
2.29k
  }
Unexecuted instantiation: CFF::FDSelect3_4<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::_cmp_range(void const*, void const*)
429
430
  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
431
1.93k
  {
432
1.93k
    auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
433
1.93k
    return range ? range->fd : ranges[nRanges () - 1].fd;
434
1.93k
  }
CFF::FDSelect3_4<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::get_fd(unsigned int) const
Line
Count
Source
431
1.93k
  {
432
1.93k
    auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
433
1.93k
    return range ? range->fd : ranges[nRanges () - 1].fd;
434
1.93k
  }
Unexecuted instantiation: CFF::FDSelect3_4<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::get_fd(unsigned int) const
435
436
  GID_TYPE        &nRanges ()       { return ranges.len; }
437
70.0k
  GID_TYPE         nRanges () const { return ranges.len; }
CFF::FDSelect3_4<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::nRanges() const
Line
Count
Source
437
70.0k
  GID_TYPE         nRanges () const { return ranges.len; }
CFF::FDSelect3_4<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::nRanges() const
Line
Count
Source
437
8
  GID_TYPE         nRanges () const { return ranges.len; }
438
  GID_TYPE       &sentinel ()       { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
439
5.52k
  const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
CFF::FDSelect3_4<OT::IntType<unsigned short, 2u>, OT::IntType<unsigned char, 1u> >::sentinel() const
Line
Count
Source
439
5.52k
  const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
Unexecuted instantiation: CFF::FDSelect3_4<OT::IntType<unsigned int, 4u>, OT::IntType<unsigned short, 2u> >::sentinel() const
440
441
  ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
442
  /* GID_TYPE sentinel */
443
444
  DEFINE_SIZE_ARRAY (GID_TYPE::static_size, ranges);
445
};
446
447
typedef FDSelect3_4<HBUINT16, HBUINT8> FDSelect3;
448
typedef FDSelect3_4_Range<HBUINT16, HBUINT8> FDSelect3_Range;
449
450
struct FDSelect
451
{
452
  bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs)
453
0
  {
454
0
    TRACE_SERIALIZE (this);
455
0
    unsigned int size = src.get_size (num_glyphs);
456
0
    FDSelect *dest = c->allocate_size<FDSelect> (size, false);
457
0
    if (unlikely (!dest)) return_trace (false);
458
0
    hb_memcpy (dest, &src, size);
459
0
    return_trace (true);
460
0
  }
461
462
  unsigned int get_size (unsigned int num_glyphs) const
463
0
  {
464
0
    switch (format)
465
0
    {
466
0
    case 0: return format.static_size + u.format0.get_size (num_glyphs);
467
0
    case 3: return format.static_size + u.format3.get_size ();
468
0
    default:return 0;
469
0
    }
470
0
  }
471
472
  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
473
88.9k
  {
474
88.9k
    if (this == &Null (FDSelect)) return 0;
475
476
2.87k
    switch (format)
477
2.87k
    {
478
941
    case 0: return u.format0.get_fd (glyph);
479
1.93k
    case 3: return u.format3.get_fd (glyph);
480
0
    default:return 0;
481
2.87k
    }
482
2.87k
  }
483
484
  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
485
4.29k
  {
486
4.29k
    TRACE_SANITIZE (this);
487
4.29k
    if (unlikely (!c->check_struct (this)))
488
32
      return_trace (false);
489
490
4.26k
    switch (format)
491
4.26k
    {
492
1.25k
    case 0: return_trace (u.format0.sanitize (c, fdcount));
493
2.93k
    case 3: return_trace (u.format3.sanitize (c, fdcount));
494
76
    default:return_trace (false);
495
4.26k
    }
496
4.26k
  }
497
498
  HBUINT8 format;
499
  union {
500
  FDSelect0 format0;
501
  FDSelect3 format3;
502
  } u;
503
  public:
504
  DEFINE_SIZE_MIN (1);
505
};
506
507
template <typename COUNT>
508
struct Subrs : CFFIndex<COUNT>
509
{
510
  typedef COUNT count_type;
511
  typedef CFFIndex<COUNT> SUPER;
512
};
513
514
} /* namespace CFF */
515
516
#endif /* HB_OT_CFF_COMMON_HH */