comparison mupdf-source/thirdparty/harfbuzz/src/hb-ot-var-common.hh @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 * Copyright © 2021 Google, 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 */
25
26 #ifndef HB_OT_VAR_COMMON_HH
27 #define HB_OT_VAR_COMMON_HH
28
29 #include "hb-ot-layout-common.hh"
30
31
32 namespace OT {
33
34 template <typename MapCountT>
35 struct DeltaSetIndexMapFormat01
36 {
37 friend struct DeltaSetIndexMap;
38
39 private:
40 DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const
41 {
42 TRACE_SERIALIZE (this);
43 auto *out = c->start_embed (this);
44 if (unlikely (!out)) return_trace (nullptr);
45
46 unsigned total_size = min_size + mapCount * get_width ();
47 HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
48 if (unlikely (!p)) return_trace (nullptr);
49
50 hb_memcpy (p, this, HBUINT8::static_size * total_size);
51 return_trace (out);
52 }
53
54 template <typename T>
55 bool serialize (hb_serialize_context_t *c, const T &plan)
56 {
57 unsigned int width = plan.get_width ();
58 unsigned int inner_bit_count = plan.get_inner_bit_count ();
59 const hb_array_t<const uint32_t> output_map = plan.get_output_map ();
60
61 TRACE_SERIALIZE (this);
62 if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
63 return_trace (false);
64 if (unlikely (!c->extend_min (this))) return_trace (false);
65
66 entryFormat = ((width-1)<<4)|(inner_bit_count-1);
67 mapCount = output_map.length;
68 HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
69 if (unlikely (!p)) return_trace (false);
70 for (unsigned int i = 0; i < output_map.length; i++)
71 {
72 unsigned int v = output_map[i];
73 unsigned int outer = v >> 16;
74 unsigned int inner = v & 0xFFFF;
75 unsigned int u = (outer << inner_bit_count) | inner;
76 for (unsigned int w = width; w > 0;)
77 {
78 p[--w] = u;
79 u >>= 8;
80 }
81 p += width;
82 }
83 return_trace (true);
84 }
85
86 uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */
87 {
88 /* If count is zero, pass value unchanged. This takes
89 * care of direct mapping for advance map. */
90 if (!mapCount)
91 return v;
92
93 if (v >= mapCount)
94 v = mapCount - 1;
95
96 unsigned int u = 0;
97 { /* Fetch it. */
98 unsigned int w = get_width ();
99 const HBUINT8 *p = mapDataZ.arrayZ + w * v;
100 for (; w; w--)
101 u = (u << 8) + *p++;
102 }
103
104 { /* Repack it. */
105 unsigned int n = get_inner_bit_count ();
106 unsigned int outer = u >> n;
107 unsigned int inner = u & ((1 << n) - 1);
108 u = (outer<<16) | inner;
109 }
110
111 return u;
112 }
113
114 unsigned get_map_count () const { return mapCount; }
115 unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; }
116 unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; }
117
118
119 bool sanitize (hb_sanitize_context_t *c) const
120 {
121 TRACE_SANITIZE (this);
122 return_trace (c->check_struct (this) &&
123 c->check_range (mapDataZ.arrayZ,
124 mapCount,
125 get_width ()));
126 }
127
128 protected:
129 HBUINT8 format; /* Format identifier--format = 0 */
130 HBUINT8 entryFormat; /* A packed field that describes the compressed
131 * representation of delta-set indices. */
132 MapCountT mapCount; /* The number of mapping entries. */
133 UnsizedArrayOf<HBUINT8>
134 mapDataZ; /* The delta-set index mapping data. */
135
136 public:
137 DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ);
138 };
139
140 struct DeltaSetIndexMap
141 {
142 template <typename T>
143 bool serialize (hb_serialize_context_t *c, const T &plan)
144 {
145 TRACE_SERIALIZE (this);
146 unsigned length = plan.get_output_map ().length;
147 u.format = length <= 0xFFFF ? 0 : 1;
148 switch (u.format) {
149 case 0: return_trace (u.format0.serialize (c, plan));
150 case 1: return_trace (u.format1.serialize (c, plan));
151 default:return_trace (false);
152 }
153 }
154
155 uint32_t map (unsigned v) const
156 {
157 switch (u.format) {
158 case 0: return (u.format0.map (v));
159 case 1: return (u.format1.map (v));
160 default:return v;
161 }
162 }
163
164 unsigned get_map_count () const
165 {
166 switch (u.format) {
167 case 0: return u.format0.get_map_count ();
168 case 1: return u.format1.get_map_count ();
169 default:return 0;
170 }
171 }
172
173 unsigned get_width () const
174 {
175 switch (u.format) {
176 case 0: return u.format0.get_width ();
177 case 1: return u.format1.get_width ();
178 default:return 0;
179 }
180 }
181
182 unsigned get_inner_bit_count () const
183 {
184 switch (u.format) {
185 case 0: return u.format0.get_inner_bit_count ();
186 case 1: return u.format1.get_inner_bit_count ();
187 default:return 0;
188 }
189 }
190
191 bool sanitize (hb_sanitize_context_t *c) const
192 {
193 TRACE_SANITIZE (this);
194 if (!u.format.sanitize (c)) return_trace (false);
195 switch (u.format) {
196 case 0: return_trace (u.format0.sanitize (c));
197 case 1: return_trace (u.format1.sanitize (c));
198 default:return_trace (true);
199 }
200 }
201
202 DeltaSetIndexMap* copy (hb_serialize_context_t *c) const
203 {
204 TRACE_SERIALIZE (this);
205 switch (u.format) {
206 case 0: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format0.copy (c)));
207 case 1: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format1.copy (c)));
208 default:return_trace (nullptr);
209 }
210 }
211
212 protected:
213 union {
214 HBUINT8 format; /* Format identifier */
215 DeltaSetIndexMapFormat01<HBUINT16> format0;
216 DeltaSetIndexMapFormat01<HBUINT32> format1;
217 } u;
218 public:
219 DEFINE_SIZE_UNION (1, format);
220 };
221
222
223 struct VarStoreInstancer
224 {
225 VarStoreInstancer (const VariationStore &varStore,
226 const DeltaSetIndexMap &varIdxMap,
227 hb_array_t<int> coords) :
228 varStore (varStore), varIdxMap (varIdxMap), coords (coords) {}
229
230 operator bool () const { return bool (coords); }
231
232 float operator() (uint32_t varIdx, unsigned short offset = 0) const
233 { return varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); }
234
235 const VariationStore &varStore;
236 const DeltaSetIndexMap &varIdxMap;
237 hb_array_t<int> coords;
238 };
239
240
241 } /* namespace OT */
242
243
244 #endif /* HB_OT_VAR_COMMON_HH */