/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 ¶m1, |
224 | | const PARAM2 ¶m2) |
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 */ |