• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 847c0d2d7901446c4c6df54c7361792d9b637ec8 Mon Sep 17 00:00:00 2001
2From: Zacoh <kouzhenrong@h-partners.com>
3Date: Wed, 14 May 2025 14:17:05 +0800
4Subject: [PATCH] harfbuzz update 11.0.0
5
6---
7 src/OT/Color/COLR/COLR.hh               | 506 ++++++++++++++++++++++++
8 src/OT/Layout/Common/CoverageFormat2.hh |   4 +
9 src/OT/glyf/Glyph.hh                    | 244 ++++++++++++
10 src/OT/glyf/GlyphHeader.hh              |  25 ++
11 src/hb-open-type.hh                     |   6 +
12 src/hb-ot-cmap-table.hh                 |  19 +
13 src/hb-ot-layout-common.hh              |  36 ++
14 src/hb-ot-layout-gpos-table.hh          |  20 +
15 src/hb-ot-layout-gsubgpos.hh            |   7 +
16 src/hb-static.cc                        |   5 +
17 10 files changed, 872 insertions(+)
18
19diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh
20index 16cd96e..46b96db 100644
21--- a/src/OT/Color/COLR/COLR.hh
22+++ b/src/OT/Color/COLR/COLR.hh
23@@ -915,6 +915,12 @@ struct PaintGlyph
24 {
25   void closurev1 (hb_colrv1_closure_context_t* c) const;
26
27+#ifdef ENABLE_ICCARM
28+  bool subset (hb_subset_context_t *c,
29+               const ItemVarStoreInstancer &instancer) const;
30+  bool sanitize (hb_sanitize_context_t *c) const;
31+  void paint_glyph (hb_paint_context_t *c) const;
32+#else
33   bool subset (hb_subset_context_t *c,
34                const ItemVarStoreInstancer &instancer) const
35   {
36@@ -946,6 +952,7 @@ struct PaintGlyph
37     c->funcs->pop_clip (c->data);
38     c->funcs->pop_transform (c->data);
39   }
40+#endif
41
42   HBUINT8		format; /* format = 10 */
43   Offset24To<Paint>	paint;  /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
44@@ -1027,6 +1034,13 @@ struct PaintTranslate
45 {
46   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
47
48+#ifdef ENABLE_ICCARM
49+  bool subset (hb_subset_context_t *c,
50+               const ItemVarStoreInstancer &instancer,
51+               uint32_t varIdxBase) const;
52+  bool sanitize (hb_sanitize_context_t *c) const;
53+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
54+#else
55   bool subset (hb_subset_context_t *c,
56                const ItemVarStoreInstancer &instancer,
57                uint32_t varIdxBase) const
58@@ -1063,6 +1077,7 @@ struct PaintTranslate
59     c->recurse (this+src);
60     if (p1) c->funcs->pop_transform (c->data);
61   }
62+#endif
63
64   HBUINT8		format; /* format = 14(noVar) or 15 (Var) */
65   Offset24To<Paint>	src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
66@@ -1076,6 +1091,13 @@ struct PaintScale
67 {
68   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
69
70+#ifdef ENABLE_ICCARM
71+  bool subset (hb_subset_context_t *c,
72+               const ItemVarStoreInstancer &instancer,
73+               uint32_t varIdxBase) const;
74+  bool sanitize (hb_sanitize_context_t *c) const;
75+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
76+#else
77   bool subset (hb_subset_context_t *c,
78                const ItemVarStoreInstancer &instancer,
79                uint32_t varIdxBase) const
80@@ -1112,6 +1134,7 @@ struct PaintScale
81     c->recurse (this+src);
82     if (p1) c->funcs->pop_transform (c->data);
83   }
84+#endif
85
86   HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
87   Offset24To<Paint>	src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
88@@ -1125,6 +1148,13 @@ struct PaintScaleAroundCenter
89 {
90   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
91
92+#ifdef ENABLE_ICCARM
93+  bool subset (hb_subset_context_t *c,
94+               const ItemVarStoreInstancer &instancer,
95+               uint32_t varIdxBase) const;
96+  bool sanitize (hb_sanitize_context_t *c) const;
97+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
98+#else
99   bool subset (hb_subset_context_t *c,
100                const ItemVarStoreInstancer &instancer,
101                uint32_t varIdxBase) const
102@@ -1169,6 +1199,7 @@ struct PaintScaleAroundCenter
103     if (p2) c->funcs->pop_transform (c->data);
104     if (p1) c->funcs->pop_transform (c->data);
105   }
106+#endif
107
108   HBUINT8		format; /* format = 18 (noVar) or 19(Var) */
109   Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
110@@ -1184,6 +1215,13 @@ struct PaintScaleUniform
111 {
112   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
113
114+#ifdef ENABLE_ICCARM
115+  bool subset (hb_subset_context_t *c,
116+               const ItemVarStoreInstancer &instancer,
117+               uint32_t varIdxBase) const;
118+  bool sanitize (hb_sanitize_context_t *c) const;
119+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
120+#else
121   bool subset (hb_subset_context_t *c,
122                const ItemVarStoreInstancer &instancer,
123                uint32_t varIdxBase) const
124@@ -1216,6 +1254,7 @@ struct PaintScaleUniform
125     c->recurse (this+src);
126     if (p1) c->funcs->pop_transform (c->data);
127   }
128+#endif
129
130   HBUINT8		format; /* format = 20 (noVar) or 21(Var) */
131   Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
132@@ -1228,6 +1267,13 @@ struct PaintScaleUniformAroundCenter
133 {
134   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
135
136+#ifdef ENABLE_ICCARM
137+  bool subset (hb_subset_context_t *c,
138+               const ItemVarStoreInstancer &instancer,
139+               uint32_t varIdxBase) const;
140+  bool sanitize (hb_sanitize_context_t *c) const;
141+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
142+#else
143   bool subset (hb_subset_context_t *c,
144                const ItemVarStoreInstancer &instancer,
145                uint32_t varIdxBase) const
146@@ -1270,6 +1316,7 @@ struct PaintScaleUniformAroundCenter
147     if (p2) c->funcs->pop_transform (c->data);
148     if (p1) c->funcs->pop_transform (c->data);
149   }
150+#endif
151
152   HBUINT8		format; /* format = 22 (noVar) or 23(Var) */
153   Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
154@@ -1284,6 +1331,13 @@ struct PaintRotate
155 {
156   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
157
158+#ifdef ENABLE_ICCARM
159+  bool subset (hb_subset_context_t *c,
160+               const ItemVarStoreInstancer &instancer,
161+               uint32_t varIdxBase) const;
162+  bool sanitize (hb_sanitize_context_t *c) const;
163+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
164+#else
165   bool subset (hb_subset_context_t *c,
166                const ItemVarStoreInstancer &instancer,
167                uint32_t varIdxBase) const
168@@ -1316,6 +1370,7 @@ struct PaintRotate
169     c->recurse (this+src);
170     if (p1) c->funcs->pop_transform (c->data);
171   }
172+#endif
173
174   HBUINT8		format; /* format = 24 (noVar) or 25(Var) */
175   Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
176@@ -1328,6 +1383,13 @@ struct PaintRotateAroundCenter
177 {
178   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
179
180+#ifdef ENABLE_ICCARM
181+  bool subset (hb_subset_context_t *c,
182+               const ItemVarStoreInstancer &instancer,
183+               uint32_t varIdxBase) const;
184+  bool sanitize (hb_sanitize_context_t *c) const;
185+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
186+#else
187   bool subset (hb_subset_context_t *c,
188                const ItemVarStoreInstancer &instancer,
189                uint32_t varIdxBase) const
190@@ -1370,6 +1432,7 @@ struct PaintRotateAroundCenter
191     if (p2) c->funcs->pop_transform (c->data);
192     if (p1) c->funcs->pop_transform (c->data);
193   }
194+#endif
195
196   HBUINT8		format; /* format = 26 (noVar) or 27(Var) */
197   Offset24To<Paint>	src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
198@@ -1384,6 +1447,13 @@ struct PaintSkew
199 {
200   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
201
202+#ifdef ENABLE_ICCARM
203+  bool subset (hb_subset_context_t *c,
204+               const ItemVarStoreInstancer &instancer,
205+               uint32_t varIdxBase) const;
206+  bool sanitize (hb_sanitize_context_t *c) const;
207+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
208+#else
209   bool subset (hb_subset_context_t *c,
210                const ItemVarStoreInstancer &instancer,
211                uint32_t varIdxBase) const
212@@ -1420,6 +1490,7 @@ struct PaintSkew
213     c->recurse (this+src);
214     if (p1) c->funcs->pop_transform (c->data);
215   }
216+#endif
217
218   HBUINT8		format; /* format = 28(noVar) or 29 (Var) */
219   Offset24To<Paint>	src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
220@@ -1433,6 +1504,13 @@ struct PaintSkewAroundCenter
221 {
222   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
223
224+#ifdef ENABLE_ICCARM
225+  bool subset (hb_subset_context_t *c,
226+               const ItemVarStoreInstancer &instancer,
227+               uint32_t varIdxBase) const;
228+  bool sanitize (hb_sanitize_context_t *c) const;
229+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
230+#else
231   bool subset (hb_subset_context_t *c,
232                const ItemVarStoreInstancer &instancer,
233                uint32_t varIdxBase) const
234@@ -1477,6 +1555,7 @@ struct PaintSkewAroundCenter
235     if (p2) c->funcs->pop_transform (c->data);
236     if (p1) c->funcs->pop_transform (c->data);
237   }
238+#endif
239
240   HBUINT8		format; /* format = 30(noVar) or 31 (Var) */
241   Offset24To<Paint>	src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
242@@ -1492,6 +1571,12 @@ struct PaintComposite
243 {
244   void closurev1 (hb_colrv1_closure_context_t* c) const;
245
246+#ifdef ENABLE_ICCARM
247+  bool subset (hb_subset_context_t *c,
248+               const ItemVarStoreInstancer &instancer) const;
249+  bool sanitize (hb_sanitize_context_t *c) const;
250+  void paint_glyph (hb_paint_context_t *c) const;
251+#else
252   bool subset (hb_subset_context_t *c,
253                const ItemVarStoreInstancer &instancer) const
254   {
255@@ -1524,6 +1609,7 @@ struct PaintComposite
256     c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
257     c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
258   }
259+#endif
260
261   HBUINT8		format; /* format = 32 */
262   Offset24To<Paint>	src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
263@@ -1920,6 +2006,426 @@ struct Paint
264   DEFINE_SIZE_MIN (2);
265 };
266
267+#ifdef ENABLE_ICCARM
268+inline bool PaintGlyph::subset (hb_subset_context_t *c,
269+              const ItemVarStoreInstancer &instancer) const
270+{
271+  TRACE_SUBSET (this);
272+  auto *out = c->serializer->embed (this);
273+  if (unlikely (!out)) return_trace (false);
274+
275+  if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
276+                                      HB_SERIALIZE_ERROR_INT_OVERFLOW))
277+    return_trace (false);
278+
279+  return_trace (out->paint.serialize_subset (c, paint, this, instancer));
280+}
281+
282+inline bool PaintGlyph::sanitize (hb_sanitize_context_t *c) const
283+{
284+  TRACE_SANITIZE (this);
285+  return_trace (c->check_struct (this) && paint.sanitize (c, this));
286+}
287+
288+inline void PaintGlyph::paint_glyph (hb_paint_context_t *c) const
289+{
290+  TRACE_PAINT (this);
291+  c->funcs->push_inverse_font_transform (c->data, c->font);
292+  c->funcs->push_clip_glyph (c->data, gid, c->font);
293+  c->funcs->push_font_transform (c->data, c->font);
294+  c->recurse (this+paint);
295+  c->funcs->pop_transform (c->data);
296+  c->funcs->pop_clip (c->data);
297+  c->funcs->pop_transform (c->data);
298+}
299+
300+inline bool PaintTranslate::subset (hb_subset_context_t *c,
301+              const ItemVarStoreInstancer &instancer,
302+              uint32_t varIdxBase) const
303+{
304+  TRACE_SUBSET (this);
305+  auto *out = c->serializer->embed (this);
306+  if (unlikely (!out)) return_trace (false);
307+
308+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
309+  {
310+    out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
311+    out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
312+  }
313+
314+  if (format == 15 && c->plan->all_axes_pinned)
315+      out->format = 14;
316+
317+  return_trace (out->src.serialize_subset (c, src, this, instancer));
318+}
319+
320+inline bool PaintTranslate::sanitize (hb_sanitize_context_t *c) const
321+{
322+  TRACE_SANITIZE (this);
323+  return_trace (c->check_struct (this) && src.sanitize (c, this));
324+}
325+
326+inline void PaintTranslate::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
327+{
328+  TRACE_PAINT (this);
329+  float ddx = dx + c->instancer (varIdxBase, 0);
330+  float ddy = dy + c->instancer (varIdxBase, 1);
331+
332+  bool p1 = c->funcs->push_translate (c->data, ddx, ddy);
333+  c->recurse (this+src);
334+  if (p1) c->funcs->pop_transform (c->data);
335+}
336+
337+inline bool PaintScale::subset (hb_subset_context_t *c,
338+              const ItemVarStoreInstancer &instancer,
339+              uint32_t varIdxBase) const
340+{
341+  TRACE_SUBSET (this);
342+  auto *out = c->serializer->embed (this);
343+  if (unlikely (!out)) return_trace (false);
344+
345+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
346+  {
347+    out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
348+    out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
349+  }
350+
351+  if (format == 17 && c->plan->all_axes_pinned)
352+      out->format = 16;
353+
354+  return_trace (out->src.serialize_subset (c, src, this, instancer));
355+}
356+
357+inline bool PaintScale::sanitize (hb_sanitize_context_t *c) const
358+{
359+  TRACE_SANITIZE (this);
360+  return_trace (c->check_struct (this) && src.sanitize (c, this));
361+}
362+
363+inline void PaintScale::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
364+{
365+  TRACE_PAINT (this);
366+  float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
367+  float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
368+
369+  bool p1 = c->funcs->push_scale (c->data, sx, sy);
370+  c->recurse (this+src);
371+  if (p1) c->funcs->pop_transform (c->data);
372+}
373+
374+inline bool PaintScaleAroundCenter::subset (hb_subset_context_t *c,
375+              const ItemVarStoreInstancer &instancer,
376+              uint32_t varIdxBase) const
377+{
378+  TRACE_SUBSET (this);
379+  auto *out = c->serializer->embed (this);
380+  if (unlikely (!out)) return_trace (false);
381+
382+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
383+  {
384+    out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
385+    out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
386+    out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
387+    out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
388+  }
389+
390+  if (format == 19 && c->plan->all_axes_pinned)
391+      out->format = 18;
392+
393+  return_trace (out->src.serialize_subset (c, src, this, instancer));
394+}
395+
396+inline bool PaintScaleAroundCenter::sanitize (hb_sanitize_context_t *c) const
397+{
398+  TRACE_SANITIZE (this);
399+  return_trace (c->check_struct (this) && src.sanitize (c, this));
400+}
401+
402+inline void PaintScaleAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
403+{
404+  TRACE_PAINT (this);
405+  float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
406+  float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
407+  float tCenterX = centerX + c->instancer (varIdxBase, 2);
408+  float tCenterY = centerY + c->instancer (varIdxBase, 3);
409+
410+  bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
411+  bool p2 = c->funcs->push_scale (c->data, sx, sy);
412+  bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
413+  c->recurse (this+src);
414+  if (p3) c->funcs->pop_transform (c->data);
415+  if (p2) c->funcs->pop_transform (c->data);
416+  if (p1) c->funcs->pop_transform (c->data);
417+}
418+
419+inline bool PaintScaleUniform::subset (hb_subset_context_t *c,
420+              const ItemVarStoreInstancer &instancer,
421+              uint32_t varIdxBase) const
422+{
423+  TRACE_SUBSET (this);
424+  auto *out = c->serializer->embed (this);
425+  if (unlikely (!out)) return_trace (false);
426+
427+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
428+    out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
429+
430+  if (format == 21 && c->plan->all_axes_pinned)
431+      out->format = 20;
432+
433+  return_trace (out->src.serialize_subset (c, src, this, instancer));
434+}
435+
436+inline bool PaintScaleUniform::sanitize (hb_sanitize_context_t *c) const
437+{
438+  TRACE_SANITIZE (this);
439+  return_trace (c->check_struct (this) && src.sanitize (c, this));
440+}
441+
442+inline void PaintScaleUniform::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
443+{
444+  TRACE_PAINT (this);
445+  float s = scale.to_float (c->instancer (varIdxBase, 0));
446+
447+  bool p1 = c->funcs->push_scale (c->data, s, s);
448+  c->recurse (this+src);
449+  if (p1) c->funcs->pop_transform (c->data);
450+}
451+
452+inline bool PaintScaleUniformAroundCenter::subset (hb_subset_context_t *c,
453+              const ItemVarStoreInstancer &instancer,
454+              uint32_t varIdxBase) const
455+{
456+  TRACE_SUBSET (this);
457+  auto *out = c->serializer->embed (this);
458+  if (unlikely (!out)) return_trace (false);
459+
460+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
461+  {
462+    out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
463+    out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
464+    out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
465+  }
466+
467+  if (format == 23 && c->plan->all_axes_pinned)
468+      out->format = 22;
469+
470+  return_trace (out->src.serialize_subset (c, src, this, instancer));
471+}
472+
473+inline bool PaintScaleUniformAroundCenter::sanitize (hb_sanitize_context_t *c) const
474+{
475+  TRACE_SANITIZE (this);
476+  return_trace (c->check_struct (this) && src.sanitize (c, this));
477+}
478+
479+inline void PaintScaleUniformAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
480+{
481+  TRACE_PAINT (this);
482+  float s = scale.to_float (c->instancer (varIdxBase, 0));
483+  float tCenterX = centerX + c->instancer (varIdxBase, 1);
484+  float tCenterY = centerY + c->instancer (varIdxBase, 2);
485+
486+  bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
487+  bool p2 = c->funcs->push_scale (c->data, s, s);
488+  bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
489+  c->recurse (this+src);
490+  if (p3) c->funcs->pop_transform (c->data);
491+  if (p2) c->funcs->pop_transform (c->data);
492+  if (p1) c->funcs->pop_transform (c->data);
493+}
494+
495+inline bool PaintRotate::subset (hb_subset_context_t *c,
496+              const ItemVarStoreInstancer &instancer,
497+              uint32_t varIdxBase) const
498+{
499+  TRACE_SUBSET (this);
500+  auto *out = c->serializer->embed (this);
501+  if (unlikely (!out)) return_trace (false);
502+
503+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
504+    out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
505+
506+  if (format == 25 && c->plan->all_axes_pinned)
507+    out->format = 24;
508+
509+  return_trace (out->src.serialize_subset (c, src, this, instancer));
510+}
511+
512+inline bool PaintRotate::sanitize (hb_sanitize_context_t *c) const
513+{
514+  TRACE_SANITIZE (this);
515+  return_trace (c->check_struct (this) && src.sanitize (c, this));
516+}
517+
518+inline void PaintRotate::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
519+{
520+  TRACE_PAINT (this);
521+  float a = angle.to_float (c->instancer (varIdxBase, 0));
522+
523+  bool p1 = c->funcs->push_rotate (c->data, a);
524+  c->recurse (this+src);
525+  if (p1) c->funcs->pop_transform (c->data);
526+}
527+
528+inline bool PaintRotateAroundCenter::subset (hb_subset_context_t *c,
529+              const ItemVarStoreInstancer &instancer,
530+              uint32_t varIdxBase) const
531+{
532+  TRACE_SUBSET (this);
533+  auto *out = c->serializer->embed (this);
534+  if (unlikely (!out)) return_trace (false);
535+
536+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
537+  {
538+    out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
539+    out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
540+    out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
541+  }
542+
543+  if (format ==27 && c->plan->all_axes_pinned)
544+      out->format = 26;
545+
546+  return_trace (out->src.serialize_subset (c, src, this, instancer));
547+}
548+
549+inline bool PaintRotateAroundCenter::sanitize (hb_sanitize_context_t *c) const
550+{
551+  TRACE_SANITIZE (this);
552+  return_trace (c->check_struct (this) && src.sanitize (c, this));
553+}
554+
555+inline void PaintRotateAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
556+{
557+  TRACE_PAINT (this);
558+  float a = angle.to_float (c->instancer (varIdxBase, 0));
559+  float tCenterX = centerX + c->instancer (varIdxBase, 1);
560+  float tCenterY = centerY + c->instancer (varIdxBase, 2);
561+
562+  bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
563+  bool p2 = c->funcs->push_rotate (c->data, a);
564+  bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
565+  c->recurse (this+src);
566+  if (p3) c->funcs->pop_transform (c->data);
567+  if (p2) c->funcs->pop_transform (c->data);
568+  if (p1) c->funcs->pop_transform (c->data);
569+}
570+
571+inline bool PaintSkew::subset (hb_subset_context_t *c,
572+              const ItemVarStoreInstancer &instancer,
573+              uint32_t varIdxBase) const
574+{
575+  TRACE_SUBSET (this);
576+  auto *out = c->serializer->embed (this);
577+  if (unlikely (!out)) return_trace (false);
578+
579+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
580+  {
581+    out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
582+    out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
583+  }
584+
585+  if (format == 29 && c->plan->all_axes_pinned)
586+      out->format = 28;
587+
588+  return_trace (out->src.serialize_subset (c, src, this, instancer));
589+}
590+
591+inline bool PaintSkew::sanitize (hb_sanitize_context_t *c) const
592+{
593+  TRACE_SANITIZE (this);
594+  return_trace (c->check_struct (this) && src.sanitize (c, this));
595+}
596+
597+inline void PaintSkew::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
598+{
599+  TRACE_PAINT (this);
600+  float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
601+  float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
602+
603+  bool p1 = c->funcs->push_skew (c->data, sx, sy);
604+  c->recurse (this+src);
605+  if (p1) c->funcs->pop_transform (c->data);
606+}
607+
608+inline bool PaintSkewAroundCenter::subset (hb_subset_context_t *c,
609+              const ItemVarStoreInstancer &instancer,
610+              uint32_t varIdxBase) const
611+{
612+  TRACE_SUBSET (this);
613+  auto *out = c->serializer->embed (this);
614+  if (unlikely (!out)) return_trace (false);
615+
616+  if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
617+  {
618+    out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
619+    out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
620+    out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
621+    out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
622+  }
623+
624+  if (format == 31 && c->plan->all_axes_pinned)
625+      out->format = 30;
626+
627+  return_trace (out->src.serialize_subset (c, src, this, instancer));
628+}
629+
630+inline bool PaintSkewAroundCenter::sanitize (hb_sanitize_context_t *c) const
631+{
632+  TRACE_SANITIZE (this);
633+  return_trace (c->check_struct (this) && src.sanitize (c, this));
634+}
635+
636+inline void PaintSkewAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
637+{
638+  TRACE_PAINT (this);
639+  float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
640+  float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
641+  float tCenterX = centerX + c->instancer (varIdxBase, 2);
642+  float tCenterY = centerY + c->instancer (varIdxBase, 3);
643+
644+  bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
645+  bool p2 = c->funcs->push_skew (c->data, sx, sy);
646+  bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
647+  c->recurse (this+src);
648+  if (p3) c->funcs->pop_transform (c->data);
649+  if (p2) c->funcs->pop_transform (c->data);
650+  if (p1) c->funcs->pop_transform (c->data);
651+}
652+
653+inline bool PaintComposite::subset (hb_subset_context_t *c,
654+              const ItemVarStoreInstancer &instancer) const
655+{
656+  TRACE_SUBSET (this);
657+  auto *out = c->serializer->embed (this);
658+  if (unlikely (!out)) return_trace (false);
659+
660+  bool ret = false;
661+  ret |= out->src.serialize_subset (c, src, this, instancer);
662+  ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer);
663+  return_trace (ret);
664+}
665+
666+inline bool PaintComposite::sanitize (hb_sanitize_context_t *c) const
667+{
668+  TRACE_SANITIZE (this);
669+  return_trace (c->check_struct (this) &&
670+    c->check_ops (this->min_size) && // PainComposite can get exponential
671+                src.sanitize (c, this) &&
672+                backdrop.sanitize (c, this));
673+}
674+
675+inline void PaintComposite::paint_glyph (hb_paint_context_t *c) const
676+{
677+  TRACE_PAINT (this);
678+  c->funcs->push_group (c->data);
679+  c->recurse (this+backdrop);
680+  c->funcs->push_group (c->data);
681+  c->recurse (this+src);
682+  c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
683+  c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
684+}
685+#endif
686+
687 struct BaseGlyphPaintRecord
688 {
689   int cmp (hb_codepoint_t g) const
690diff --git a/src/OT/Layout/Common/CoverageFormat2.hh b/src/OT/Layout/Common/CoverageFormat2.hh
691index dd577fd..18c93ac 100644
692--- a/src/OT/Layout/Common/CoverageFormat2.hh
693+++ b/src/OT/Layout/Common/CoverageFormat2.hh
694@@ -70,7 +70,11 @@ struct CoverageFormat2_4
695     typename Types::large_int ret = 0;
696     for (const auto &r : rangeRecord)
697       ret += r.get_population ();
698+#ifdef ENABLE_ICCARM
699+    return ret;
700+#else
701     return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
702+#endif
703   }
704
705   template <typename Iterator,
706diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh
707index 2c289d5..bb92986 100644
708--- a/src/OT/glyf/Glyph.hh
709+++ b/src/OT/glyf/Glyph.hh
710@@ -303,6 +303,21 @@ struct Glyph
711   /* Note: Recursively calls itself.
712    * all_points includes phantom points
713    */
714+#ifdef ENABLE_ICCARM
715+  template <typename accelerator_t>
716+  bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
717+		   contour_point_vector_t &all_points /* OUT */,
718+		   hb_glyf_scratch_t &scratch,
719+		   contour_point_vector_t *points_with_deltas = nullptr, /* OUT */
720+		   head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
721+		   unsigned *composite_contours = nullptr, /* OUT */
722+		   bool shift_points_hori = true,
723+		   bool use_my_metrics = true,
724+		   bool phantom_only = false,
725+		   hb_array_t<const int> coords = hb_array_t<const int> (),
726+		   unsigned int depth = 0,
727+		   unsigned *edge_count = nullptr) const;
728+#else
729   template <typename accelerator_t>
730   bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
731 		   contour_point_vector_t &all_points /* OUT */,
732@@ -529,6 +544,7 @@ struct Glyph
733
734     return !all_points.in_error ();
735   }
736+#endif
737
738   bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
739 				       hb_glyph_extents_t *extents) const
740@@ -566,6 +582,234 @@ struct Glyph
741   glyph_type_t type;
742 };
743
744+#ifdef ENABLE_ICCARM
745+template <typename accelerator_t>
746+inline bool Glyph::get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
747+      contour_point_vector_t &all_points /* OUT */,
748+      hb_glyf_scratch_t &scratch,
749+      contour_point_vector_t *points_with_deltas, /* OUT */
750+      head_maxp_info_t * head_maxp_info, /* OUT */
751+      unsigned *composite_contours, /* OUT */
752+      bool shift_points_hori,
753+      bool use_my_metrics,
754+      bool phantom_only,
755+      hb_array_t<const int> coords,
756+      unsigned int depth,
757+      unsigned *edge_count) const
758+{
759+  if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
760+  unsigned stack_edge_count = 0;
761+  if (!edge_count) edge_count = &stack_edge_count;
762+  if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false;
763+  (*edge_count)++;
764+
765+  if (head_maxp_info)
766+  {
767+    head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
768+  }
769+
770+  if (!coords)
771+    coords = hb_array (font->coords, font->num_coords);
772+
773+  contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points;
774+  unsigned old_length = points.length;
775+
776+  switch (type) {
777+  case SIMPLE:
778+    if (depth == 0 && head_maxp_info)
779+      head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
780+    if (depth > 0 && composite_contours)
781+      *composite_contours += (unsigned) header->numberOfContours;
782+    if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (all_points, phantom_only)))
783+return false;
784+    break;
785+  case COMPOSITE:
786+  {
787+    for (auto &item : get_composite_iterator ())
788+      if (unlikely (!item.get_points (points))) return false;
789+    break;
790+  }
791+  case EMPTY:
792+    break;
793+  }
794+
795+  /* Init phantom points */
796+  if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
797+  hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
798+  {
799+    int lsb = 0;
800+    int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
801+      (int) header->xMin - lsb : 0;
802+    HB_UNUSED int tsb = 0;
803+    int v_orig  = (int) header->yMax +
804+#ifndef HB_NO_VERTICAL
805+      ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
806+#else
807+      0
808+#endif
809+      ;
810+    unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid);
811+    unsigned v_adv =
812+#ifndef HB_NO_VERTICAL
813+          glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid)
814+#else
815+          - font->face->get_upem ()
816+#endif
817+          ;
818+    phantoms[PHANTOM_LEFT].x = h_delta;
819+    phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
820+    phantoms[PHANTOM_TOP].y = v_orig;
821+    phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
822+  }
823+
824+#ifndef HB_NO_VAR
825+  if (coords)
826+  {
827+#ifndef HB_NO_BEYOND_64K
828+    if (glyf_accelerator.GVAR->has_data ())
829+glyf_accelerator.GVAR->apply_deltas_to_points (gid,
830+                  coords,
831+                  points.as_array ().sub_array (old_length),
832+                  scratch,
833+                  phantom_only && type == SIMPLE);
834+    else
835+#endif
836+glyf_accelerator.gvar->apply_deltas_to_points (gid,
837+                  coords,
838+                  points.as_array ().sub_array (old_length),
839+                  scratch,
840+                  phantom_only && type == SIMPLE);
841+  }
842+#endif
843+
844+  // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
845+  // with child glyphs' points
846+  if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
847+  {
848+    assert (old_length == 0);
849+    *points_with_deltas = points;
850+  }
851+
852+  float shift = 0;
853+  switch (type) {
854+  case SIMPLE:
855+    if (depth == 0 && head_maxp_info)
856+      head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
857+    shift = phantoms[PHANTOM_LEFT].x;
858+    break;
859+  case COMPOSITE:
860+  {
861+    hb_decycler_node_t decycler_node (scratch.decycler);
862+
863+    unsigned int comp_index = 0;
864+    for (auto &item : get_composite_iterator ())
865+    {
866+hb_codepoint_t item_gid = item.get_gid ();
867+
868+      if (unlikely (!decycler_node.visit (item_gid)))
869+{
870+  comp_index++;
871+  continue;
872+}
873+
874+unsigned old_count = all_points.length;
875+
876+if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
877+        !glyf_accelerator.glyph_for_gid (item_gid)
878+              .get_points (font,
879+              glyf_accelerator,
880+              all_points,
881+              scratch,
882+              points_with_deltas,
883+              head_maxp_info,
884+              composite_contours,
885+              shift_points_hori,
886+              use_my_metrics,
887+              phantom_only,
888+              coords,
889+              depth + 1,
890+              edge_count)))
891+{
892+  points.resize (old_length);
893+  return false;
894+}
895+
896+// points might have been reallocated. Relocate phantoms.
897+phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
898+
899+auto comp_points = all_points.as_array ().sub_array (old_count);
900+
901+/* Copy phantom points from component if USE_MY_METRICS flag set */
902+if (use_my_metrics && item.is_use_my_metrics ())
903+  for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
904+    phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
905+
906+if (comp_points) // Empty in case of phantom_only
907+{
908+  float matrix[4];
909+  contour_point_t default_trans;
910+  item.get_transformation (matrix, default_trans);
911+
912+  /* Apply component transformation & translation (with deltas applied) */
913+  item.transform_points (comp_points, matrix, points[old_length + comp_index]);
914+}
915+
916+if (item.is_anchored () && !phantom_only)
917+{
918+  unsigned int p1, p2;
919+  item.get_anchor_points (p1, p2);
920+  if (likely (p1 < all_points.length && p2 < comp_points.length))
921+  {
922+    contour_point_t delta;
923+    delta.init (all_points[p1].x - comp_points[p2].x,
924+    all_points[p1].y - comp_points[p2].y);
925+
926+    item.translate (delta, comp_points);
927+  }
928+}
929+
930+all_points.resize (all_points.length - PHANTOM_COUNT);
931+
932+if (all_points.length > HB_GLYF_MAX_POINTS)
933+{
934+  points.resize (old_length);
935+  return false;
936+}
937+
938+comp_index++;
939+    }
940+
941+    if (head_maxp_info && depth == 0)
942+    {
943+      if (composite_contours)
944+        head_maxp_info->maxCompositeContours = hb_max (head_maxp_info->maxCompositeContours, *composite_contours);
945+      head_maxp_info->maxCompositePoints = hb_max (head_maxp_info->maxCompositePoints, all_points.length);
946+      head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index);
947+    }
948+    all_points.extend (phantoms);
949+    shift = phantoms[PHANTOM_LEFT].x;
950+    points.resize (old_length);
951+  } break;
952+  case EMPTY:
953+    all_points.extend (phantoms);
954+    shift = phantoms[PHANTOM_LEFT].x;
955+    points.resize (old_length);
956+    break;
957+  }
958+
959+  if (depth == 0 && shift_points_hori) /* Apply at top level */
960+  {
961+    /* Undocumented rasterizer behavior:
962+      * Shift points horizontally by the updated left side bearing
963+      */
964+    if (shift)
965+      for (auto &point : all_points)
966+  point.x -= shift;
967+  }
968+
969+  return !all_points.in_error ();
970+}
971+#endif
972
973 } /* namespace glyf_impl */
974 } /* namespace OT */
975diff --git a/src/OT/glyf/GlyphHeader.hh b/src/OT/glyf/GlyphHeader.hh
976index a43b669..14ab9d7 100644
977--- a/src/OT/glyf/GlyphHeader.hh
978+++ b/src/OT/glyf/GlyphHeader.hh
979@@ -13,6 +13,11 @@ struct GlyphHeader
980 {
981   bool has_data () const { return numberOfContours; }
982
983+#ifdef ENABLE_ICCARM
984+  template <typename accelerator_t>
985+  bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
986+				       hb_codepoint_t gid, hb_glyph_extents_t *extents) const;
987+#else
988   template <typename accelerator_t>
989   bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
990 				       hb_codepoint_t gid, hb_glyph_extents_t *extents) const
991@@ -30,6 +35,7 @@ struct GlyphHeader
992
993     return true;
994   }
995+#endif
996
997   HBINT16	numberOfContours;
998 		    /* If the number of contours is
999@@ -44,6 +50,25 @@ struct GlyphHeader
1000   DEFINE_SIZE_STATIC (10);
1001 };
1002
1003+#ifdef ENABLE_ICCARM
1004+template <typename accelerator_t>
1005+bool GlyphHeader::get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
1006+              hb_codepoint_t gid, hb_glyph_extents_t *extents) const
1007+{
1008+  /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
1009+  /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
1010+  int lsb = hb_min (xMin, xMax);
1011+  (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb);
1012+  extents->x_bearing = lsb;
1013+  extents->y_bearing = hb_max (yMin, yMax);
1014+  extents->width     = hb_max (xMin, xMax) - hb_min (xMin, xMax);
1015+  extents->height    = hb_min (yMin, yMax) - hb_max (yMin, yMax);
1016+
1017+  font->scale_glyph_extents (extents);
1018+
1019+  return true;
1020+}
1021+#endif
1022
1023 } /* namespace glyf_impl */
1024 } /* namespace OT */
1025diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
1026index f2040ea..844704a 100644
1027--- a/src/hb-open-type.hh
1028+++ b/src/hb-open-type.hh
1029@@ -669,8 +669,14 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf<Type>
1030   { return hb_sorted_array (this->arrayZ, len); }
1031   hb_sorted_array_t<const Type> as_array (unsigned int len) const
1032   { return hb_sorted_array (this->arrayZ, len); }
1033+
1034+#ifdef ENABLE_ICCARM
1035+  operator hb_sorted_array_t<Type> ()             { return as_array ( 0 ); }
1036+  operator hb_sorted_array_t<const Type> () const { return as_array ( 0 ); }
1037+#else
1038   operator hb_sorted_array_t<Type> ()             { return as_array (); }
1039   operator hb_sorted_array_t<const Type> () const { return as_array (); }
1040+#endif
1041
1042   template <typename T>
1043   Type &bsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))
1044diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
1045index 7a7a77a..eaba5d2 100644
1046--- a/src/hb-ot-cmap-table.hh
1047+++ b/src/hb-ot-cmap-table.hh
1048@@ -1695,6 +1695,10 @@ struct SubtableUnicodesCache {
1049     hb_free (cache);
1050   }
1051
1052+#ifdef ENABLE_ICCARM
1053+  SubtableUnicodesCache(const void* cmap_base);
1054+  SubtableUnicodesCache(hb_blob_ptr_t<cmap> base_blob_);
1055+#else
1056   SubtableUnicodesCache(const void* cmap_base)
1057       : base_blob(),
1058         base ((const char*) cmap_base),
1059@@ -1706,6 +1710,7 @@ struct SubtableUnicodesCache {
1060         base ((const char *) base_blob.get()),
1061         cached_unicodes ()
1062   {}
1063+#endif
1064
1065   ~SubtableUnicodesCache()
1066   {
1067@@ -2266,6 +2271,20 @@ struct cmap
1068   DEFINE_SIZE_ARRAY (4, encodingRecord);
1069 };
1070
1071+#ifdef ENABLE_ICCARM
1072+inline SubtableUnicodesCache::SubtableUnicodesCache(const void* cmap_base)
1073+    : base_blob(),
1074+      base ((const char*) cmap_base),
1075+      cached_unicodes ()
1076+{}
1077+
1078+inline SubtableUnicodesCache::SubtableUnicodesCache(hb_blob_ptr_t<cmap> base_blob_)
1079+    : base_blob(base_blob_),
1080+      base ((const char *) base_blob.get()),
1081+      cached_unicodes ()
1082+{}
1083+#endif
1084+
1085 struct cmap_accelerator_t : cmap::accelerator_t {
1086   cmap_accelerator_t (hb_face_t *face) : cmap::accelerator_t (face) {}
1087 };
1088diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
1089index ad54a1d..f8212a6 100644
1090--- a/src/hb-ot-layout-common.hh
1091+++ b/src/hb-ot-layout-common.hh
1092@@ -1768,7 +1768,11 @@ struct ClassDefFormat2_4
1093     typename Types::large_int ret = 0;
1094     for (const auto &r : rangeRecord)
1095       ret += r.get_population ();
1096+#ifdef ENABLE_ICCARM
1097+    return ret;
1098+#else
1099     return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
1100+#endif
1101   }
1102
1103   template<typename Iterator,
1104@@ -4014,11 +4018,15 @@ struct ConditionAnd
1105     return_trace (false);
1106   }
1107
1108+#ifdef ENABLE_ICCARM
1109+  bool sanitize (hb_sanitize_context_t *c) const;
1110+#else
1111   bool sanitize (hb_sanitize_context_t *c) const
1112   {
1113     TRACE_SANITIZE (this);
1114     return_trace (conditions.sanitize (c, this));
1115   }
1116+#endif
1117
1118   protected:
1119   HBUINT16	format;		/* Format identifier--format = 3 */
1120@@ -4061,11 +4069,15 @@ struct ConditionOr
1121     return_trace (false);
1122   }
1123
1124+#ifdef ENABLE_ICCARM
1125+  bool sanitize (hb_sanitize_context_t *c) const;
1126+#else
1127   bool sanitize (hb_sanitize_context_t *c) const
1128   {
1129     TRACE_SANITIZE (this);
1130     return_trace (conditions.sanitize (c, this));
1131   }
1132+#endif
1133
1134   protected:
1135   HBUINT16	format;		/* Format identifier--format = 4 */
1136@@ -4104,11 +4116,15 @@ struct ConditionNegate
1137     return_trace (false);
1138   }
1139
1140+#ifdef ENABLE_ICCARM
1141+  bool sanitize (hb_sanitize_context_t *c) const;
1142+#else
1143   bool sanitize (hb_sanitize_context_t *c) const
1144   {
1145     TRACE_SANITIZE (this);
1146     return_trace (condition.sanitize (c, this));
1147   }
1148+#endif
1149
1150   protected:
1151   HBUINT16	format;		/* Format identifier--format = 5 */
1152@@ -4186,6 +4202,26 @@ struct Condition
1153   DEFINE_SIZE_UNION (2, format);
1154 };
1155
1156+#ifdef ENABLE_ICCARM
1157+inline bool ConditionAnd::sanitize (hb_sanitize_context_t *c) const
1158+{
1159+  TRACE_SANITIZE (this);
1160+  return_trace (conditions.sanitize (c, this));
1161+}
1162+
1163+inline bool ConditionOr::sanitize (hb_sanitize_context_t *c) const
1164+{
1165+  TRACE_SANITIZE (this);
1166+  return_trace (conditions.sanitize (c, this));
1167+}
1168+
1169+inline bool ConditionNegate::sanitize (hb_sanitize_context_t *c) const
1170+{
1171+  TRACE_SANITIZE (this);
1172+  return_trace (condition.sanitize (c, this));
1173+}
1174+#endif
1175+
1176 template <typename Instancer>
1177 bool
1178 _hb_recurse_condition_evaluate (const struct Condition &condition,
1179diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
1180index 0cfa139..a2e87e8 100644
1181--- a/src/hb-ot-layout-gpos-table.hh
1182+++ b/src/hb-ot-layout-gpos-table.hh
1183@@ -75,6 +75,26 @@ inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply
1184
1185 } /* namespace GPOS_impl */
1186 } /* namespace Layout */
1187+
1188+#ifdef ENABLE_ICCARM
1189+template <typename TLookup>
1190+void GSUBGPOS::closure_lookups (hb_face_t      *face,
1191+    const hb_set_t *glyphs,
1192+    hb_set_t       *lookup_indexes /* IN/OUT */) const
1193+{
1194+  hb_set_t visited_lookups, inactive_lookups;
1195+  hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
1196+
1197+  c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>);
1198+
1199+  for (unsigned lookup_index : *lookup_indexes)
1200+    reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index);
1201+
1202+  hb_set_union (lookup_indexes, &visited_lookups);
1203+  hb_set_subtract (lookup_indexes, &inactive_lookups);
1204+}
1205+#endif
1206+
1207 } /* namespace OT */
1208
1209
1210diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
1211index 7d49710..66d69cb 100644
1212--- a/src/hb-ot-layout-gsubgpos.hh
1213+++ b/src/hb-ot-layout-gsubgpos.hh
1214@@ -4790,6 +4790,12 @@ struct GSUBGPOS
1215   { get_feature_variations ().collect_feature_substitutes_with_variations (c); }
1216 #endif
1217
1218+#ifdef ENABLE_ICCARM
1219+  template <typename TLookup>
1220+  void closure_lookups (hb_face_t      *face,
1221+			const hb_set_t *glyphs,
1222+			hb_set_t       *lookup_indexes /* IN/OUT */) const;
1223+#else
1224   template <typename TLookup>
1225   void closure_lookups (hb_face_t      *face,
1226 			const hb_set_t *glyphs,
1227@@ -4806,6 +4812,7 @@ struct GSUBGPOS
1228     hb_set_union (lookup_indexes, &visited_lookups);
1229     hb_set_subtract (lookup_indexes, &inactive_lookups);
1230   }
1231+#endif
1232
1233   void prune_langsys (const hb_map_t *duplicate_feature_map,
1234                       const hb_set_t *layout_scripts,
1235diff --git a/src/hb-static.cc b/src/hb-static.cc
1236index e328bc4..b4761a6 100644
1237--- a/src/hb-static.cc
1238+++ b/src/hb-static.cc
1239@@ -44,8 +44,13 @@
1240
1241 #include "hb-ot-name-language-static.hh"
1242
1243+#ifdef ENABLE_ICCARM
1244+uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = { 0 };
1245+/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = { 0 };
1246+#else
1247 uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
1248 /*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
1249+#endif
1250
1251 DEFINE_NULL_NAMESPACE_BYTES (OT, Index) =  {0xFF,0xFF};
1252 DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) =  {0xFF,0xFF,0xFF,0xFF};
1253--
12542.44.0.windows.1
1255
1256