summaryrefslogtreecommitdiff
path: root/thirdparty/harfbuzz/src/OT/Layout/GPOS
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/harfbuzz/src/OT/Layout/GPOS')
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh22
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh171
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh56
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh23
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh10
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh14
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh10
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh56
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh10
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh15
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh14
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh253
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh24
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh189
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh99
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh3
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh28
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh14
18 files changed, 682 insertions, 329 deletions
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
index e212fab976..7f58fac8b8 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -140,7 +140,14 @@ struct CursivePosFormat1
unsigned int i = skippy_iter.idx;
unsigned int j = buffer->idx;
- buffer->unsafe_to_break (i, j);
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "cursive attaching glyph at %d to glyph at %d",
+ i, j);
+ }
+
+ buffer->unsafe_to_break (i, j + 1);
float entry_x, entry_y, exit_x, exit_y;
(this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
(this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
@@ -223,7 +230,20 @@ struct CursivePosFormat1
* https://github.com/harfbuzz/harfbuzz/issues/2469
*/
if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
+ {
pos[parent].attach_chain() = 0;
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+ pos[parent].y_offset = 0;
+ else
+ pos[parent].x_offset = 0;
+ }
+
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "cursive attached glyph at %d to glyph at %d",
+ i, j);
+ }
buffer->idx++;
return_trace (true);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh
new file mode 100644
index 0000000000..72829377a6
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh
@@ -0,0 +1,171 @@
+#ifndef OT_LAYOUT_GPOS_GPOS_HH
+#define OT_LAYOUT_GPOS_GPOS_HH
+
+#include "../../../hb-ot-layout-common.hh"
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+#include "PosLookup.hh"
+
+namespace OT {
+
+using Layout::GPOS_impl::PosLookup;
+
+namespace Layout {
+
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+ unsigned int len,
+ unsigned int i,
+ hb_direction_t direction,
+ unsigned nesting_level = HB_MAX_NESTING_LEVEL);
+
+/*
+ * GPOS -- Glyph Positioning
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
+ */
+
+struct GPOS : GSUBGPOS
+{
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
+
+ using Lookup = PosLookup;
+
+ const PosLookup& get_lookup (unsigned int i) const
+ { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
+
+ static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
+ return GSUBGPOS::subset<PosLookup> (&l);
+ }
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (GSUBGPOS::sanitize<PosLookup> (c));
+ }
+
+ HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
+ hb_face_t *face) const;
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
+ {
+ if (!c->gpos_lookups->has (i)) continue;
+ const PosLookup &l = get_lookup (i);
+ l.dispatch (c);
+ }
+ }
+
+ void closure_lookups (hb_face_t *face,
+ const hb_set_t *glyphs,
+ hb_set_t *lookup_indexes /* IN/OUT */) const
+ { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); }
+
+ typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
+};
+
+
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+ unsigned int len,
+ unsigned int i,
+ hb_direction_t direction,
+ unsigned nesting_level)
+{
+ /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
+ * offset of glyph they are attached to. */
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+ if (likely (!chain))
+ return;
+
+ pos[i].attach_chain() = 0;
+
+ unsigned int j = (int) i + chain;
+
+ if (unlikely (j >= len))
+ return;
+
+ if (unlikely (!nesting_level))
+ return;
+
+ propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
+
+ assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE));
+
+ if (type & GPOS_impl::ATTACH_TYPE_CURSIVE)
+ {
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[i].y_offset += pos[j].y_offset;
+ else
+ pos[i].x_offset += pos[j].x_offset;
+ }
+ else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/
+ {
+ pos[i].x_offset += pos[j].x_offset;
+ pos[i].y_offset += pos[j].y_offset;
+
+ assert (j < i);
+ if (HB_DIRECTION_IS_FORWARD (direction))
+ for (unsigned int k = j; k < i; k++) {
+ pos[i].x_offset -= pos[k].x_advance;
+ pos[i].y_offset -= pos[k].y_advance;
+ }
+ else
+ for (unsigned int k = j + 1; k < i + 1; k++) {
+ pos[i].x_offset += pos[k].x_advance;
+ pos[i].y_offset += pos[k].y_advance;
+ }
+ }
+}
+
+void
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
+}
+
+void
+GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
+{
+ //_hb_buffer_assert_gsubgpos_vars (buffer);
+}
+
+void
+GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
+{
+ _hb_buffer_assert_gsubgpos_vars (buffer);
+
+ unsigned int len;
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
+ hb_direction_t direction = buffer->props.direction;
+
+ /* Handle attachments */
+ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
+ for (unsigned i = 0; i < len; i++)
+ propagate_attachment_offsets (pos, len, i, direction);
+
+ if (unlikely (font->slant))
+ {
+ for (unsigned i = 0; i < len; i++)
+ if (unlikely (pos[i].y_offset))
+ pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
+ }
+}
+
+}
+
+struct GPOS_accelerator_t : Layout::GPOS::accelerator_t {
+ GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {}
+};
+
+}
+
+#endif /* OT_LAYOUT_GPOS_GPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh
new file mode 100644
index 0000000000..a2d807cc32
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh
@@ -0,0 +1,56 @@
+#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH
+#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+typedef AnchorMatrix LigatureAttach; /* component-major--
+ * in order of writing direction--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
+struct LigatureArray : List16OfOffset16To<LigatureAttach>
+{
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool subset (hb_subset_context_t *c,
+ Iterator coverage,
+ unsigned class_count,
+ const hb_map_t *klass_mapping) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+
+ auto *out = c->serializer->start_embed (this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ for (const auto _ : + hb_zip (coverage, *this)
+ | hb_filter (glyphset, hb_first))
+ {
+ auto *matrix = out->serialize_append (c->serializer);
+ if (unlikely (!matrix)) return_trace (false);
+
+ const LigatureAttach& src = (this + _.second);
+ auto indexes =
+ + hb_range (src.rows * class_count)
+ | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
+ ;
+ matrix->serialize_subset (c,
+ _.second,
+ this,
+ src.rows,
+ indexes);
+ }
+ return_trace (this->len);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh
index f8cddd1991..cb5e8b2689 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh
@@ -39,6 +39,13 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove
mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "attaching mark glyph at %d to glyph at %d",
+ c->buffer->idx, glyph_pos);
+ }
+
hb_glyph_position_t &o = buffer->cur_pos();
o.x_offset = roundf (base_x - mark_x);
o.y_offset = roundf (base_y - mark_y);
@@ -46,6 +53,13 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove
o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "attached mark glyph at %d to glyph at %d",
+ c->buffer->idx, glyph_pos);
+ }
+
buffer->idx++;
return_trace (true);
}
@@ -83,10 +97,11 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove
}
};
-static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
- const MarkArray &mark_array,
- const hb_set_t &glyphset,
- hb_map_t* klass_mapping /* INOUT */)
+HB_INTERNAL inline
+void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
+ const MarkArray &mark_array,
+ const hb_set_t &glyphset,
+ hb_map_t* klass_mapping /* INOUT */)
{
hb_set_t orig_classes;
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
index e99e13ff84..c99b6b2e4b 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
@@ -11,8 +11,11 @@ struct MarkBasePos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MarkBasePosFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MarkBasePosFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MarkBasePosFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -23,6 +26,9 @@ struct MarkBasePos
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
index a10b806fe5..ebb8c31c67 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
@@ -12,26 +12,27 @@ typedef AnchorMatrix BaseArray; /* base-major--
* mark-minor--
* ordered by class--zero-based. */
-struct MarkBasePosFormat1
+template <typename Types>
+struct MarkBasePosFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
markCoverage; /* Offset to MarkCoverage table--from
* beginning of MarkBasePos subtable */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
baseCoverage; /* Offset to BaseCoverage table--from
* beginning of MarkBasePos subtable */
HBUINT16 classCount; /* Number of classes defined for marks */
- Offset16To<MarkArray>
+ typename Types::template OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkBasePos subtable */
- Offset16To<BaseArray>
+ typename Types::template OffsetTo<BaseArray>
baseArray; /* Offset to BaseArray table--from
* beginning of MarkBasePos subtable */
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (4 + 4 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -117,6 +118,7 @@ struct MarkBasePosFormat1
0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
(skippy_iter.idx == 0 ||
_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) ||
+ !_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx - 1]) ||
_hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
_hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
_hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
index 7e74aa73e0..8a4de9ffaa 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
@@ -11,8 +11,11 @@ struct MarkLigPos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MarkLigPosFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MarkLigPosFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MarkLigPosFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -23,6 +26,9 @@ struct MarkLigPos
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
index 4382aa6c6c..1a8021237e 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
@@ -1,72 +1,34 @@
#ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
#define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
+#include "LigatureArray.hh"
+
namespace OT {
namespace Layout {
namespace GPOS_impl {
-typedef AnchorMatrix LigatureAttach; /* component-major--
- * in order of writing direction--,
- * mark-minor--
- * ordered by class--zero-based. */
-
-/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
-struct LigatureArray : List16OfOffset16To<LigatureAttach>
-{
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- Iterator coverage,
- unsigned class_count,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const auto _ : + hb_zip (coverage, *this)
- | hb_filter (glyphset, hb_first))
- {
- auto *matrix = out->serialize_append (c->serializer);
- if (unlikely (!matrix)) return_trace (false);
-
- const LigatureAttach& src = (this + _.second);
- auto indexes =
- + hb_range (src.rows * class_count)
- | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
- ;
- matrix->serialize_subset (c,
- _.second,
- this,
- src.rows,
- indexes);
- }
- return_trace (this->len);
- }
-};
-struct MarkLigPosFormat1
+template <typename Types>
+struct MarkLigPosFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
markCoverage; /* Offset to Mark Coverage table--from
* beginning of MarkLigPos subtable */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
ligatureCoverage; /* Offset to Ligature Coverage
* table--from beginning of MarkLigPos
* subtable */
HBUINT16 classCount; /* Number of defined mark classes */
- Offset16To<MarkArray>
+ typename Types::template OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkLigPos subtable */
- Offset16To<LigatureArray>
+ typename Types::template OffsetTo<LigatureArray>
ligatureArray; /* Offset to LigatureArray table--from
* beginning of MarkLigPos subtable */
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (4 + 4 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
index c0eee6d54c..74b5105c42 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
@@ -11,8 +11,11 @@ struct MarkMarkPos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MarkMarkPosFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MarkMarkPosFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MarkMarkPosFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -23,6 +26,9 @@ struct MarkMarkPos
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index c48a74f773..fbcebb8044 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -12,27 +12,28 @@ typedef AnchorMatrix Mark2Array; /* mark2-major--
* mark1-minor--
* ordered by class--zero-based. */
-struct MarkMarkPosFormat1
+template <typename Types>
+struct MarkMarkPosFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
mark1Coverage; /* Offset to Combining Mark1 Coverage
* table--from beginning of MarkMarkPos
* subtable */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
mark2Coverage; /* Offset to Combining Mark2 Coverage
* table--from beginning of MarkMarkPos
* subtable */
HBUINT16 classCount; /* Number of defined mark classes */
- Offset16To<MarkArray>
+ typename Types::template OffsetTo<MarkArray>
mark1Array; /* Offset to Mark1Array table--from
* beginning of MarkMarkPos subtable */
- Offset16To<Mark2Array>
+ typename Types::template OffsetTo<Mark2Array>
mark2Array; /* Offset to Mark2Array table--from
* beginning of MarkMarkPos subtable */
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (4 + 4 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -100,7 +101,7 @@ struct MarkMarkPosFormat1
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
- skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
+ skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from))
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
index 8479178d38..72bfc43dc4 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
@@ -12,9 +12,13 @@ struct PairPos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- PairPosFormat1 format1;
- PairPosFormat2 format2;
+ HBUINT16 format; /* Format identifier */
+ PairPosFormat1_3<SmallTypes> format1;
+ PairPosFormat2_4<SmallTypes> format2;
+#ifndef HB_NO_BORING_EXPANSION
+ PairPosFormat1_3<MediumTypes> format3;
+ PairPosFormat2_4<MediumTypes> format4;
+#endif
} u;
public:
@@ -26,6 +30,10 @@ struct PairPos
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
+ case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
index 35a2db2d45..3cb207281d 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -1,248 +1,22 @@
#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
#define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
+#include "PairSet.hh"
+
namespace OT {
namespace Layout {
namespace GPOS_impl {
-struct PairValueRecord
-{
- friend struct PairSet;
-
- int cmp (hb_codepoint_t k) const
- { return secondGlyph.cmp (k); }
-
- struct context_t
- {
- const void *base;
- const ValueFormat *valueFormats;
- const ValueFormat *newFormats;
- unsigned len1; /* valueFormats[0].get_len() */
- const hb_map_t *glyph_map;
- const hb_map_t *layout_variation_idx_map;
- };
-
- bool subset (hb_subset_context_t *c,
- context_t *closure) const
- {
- TRACE_SERIALIZE (this);
- auto *s = c->serializer;
- auto *out = s->start_embed (*this);
- if (unlikely (!s->extend_min (out))) return_trace (false);
-
- out->secondGlyph = (*closure->glyph_map)[secondGlyph];
-
- closure->valueFormats[0].copy_values (s,
- closure->newFormats[0],
- closure->base, &values[0],
- closure->layout_variation_idx_map);
- closure->valueFormats[1].copy_values (s,
- closure->newFormats[1],
- closure->base,
- &values[closure->len1],
- closure->layout_variation_idx_map);
-
- return_trace (true);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats,
- const void *base) const
- {
- unsigned record1_len = valueFormats[0].get_len ();
- unsigned record2_len = valueFormats[1].get_len ();
- const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
-
- if (valueFormats[0].has_device ())
- valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
-
- if (valueFormats[1].has_device ())
- valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
- }
-
- bool intersects (const hb_set_t& glyphset) const
- {
- return glyphset.has(secondGlyph);
- }
-
- const Value* get_values_1 () const
- {
- return &values[0];
- }
-
- const Value* get_values_2 (ValueFormat format1) const
- {
- return &values[format1.get_len ()];
- }
- protected:
- HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the
- * pair--first glyph is listed in the
- * Coverage table */
- ValueRecord values; /* Positioning data for the first glyph
- * followed by for second glyph */
- public:
- DEFINE_SIZE_ARRAY (2, values);
-};
-
-struct PairSet
+template <typename Types>
+struct PairPosFormat1_3
{
- friend struct PairPosFormat1;
-
- bool intersects (const hb_set_t *glyphs,
- const ValueFormat *valueFormats) const
- {
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (glyphs->has (record->secondGlyph))
- return true;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- return false;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- c->input->add_array (&record->secondGlyph, len, record_size);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len;
- for (unsigned i = 0; i < count; i++)
- {
- if (c->glyph_set->has (record->secondGlyph))
- { record->collect_variation_indices (c, valueFormats, this); }
-
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- }
+ using PairSet = GPOS_impl::PairSet<Types>;
+ using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
- bool apply (hb_ot_apply_context_t *c,
- const ValueFormat *valueFormats,
- unsigned int pos) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
- &firstPairValueRecord,
- len,
- record_size);
- if (record)
- {
- bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
- bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
- if (applied_first || applied_second)
- buffer->unsafe_to_break (buffer->idx, pos + 1);
- if (len2)
- pos++;
- buffer->idx = pos;
- return_trace (true);
- }
- buffer->unsafe_to_concat (buffer->idx, pos + 1);
- return_trace (false);
- }
-
- bool subset (hb_subset_context_t *c,
- const ValueFormat valueFormats[2],
- const ValueFormat newFormats[2]) const
- {
- TRACE_SUBSET (this);
- auto snap = c->serializer->snapshot ();
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->len = 0;
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
-
- PairValueRecord::context_t context =
- {
- this,
- valueFormats,
- newFormats,
- len1,
- &glyph_map,
- c->plan->layout_variation_idx_map
- };
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len, num = 0;
- for (unsigned i = 0; i < count; i++)
- {
- if (glyphset.has (record->secondGlyph)
- && record->subset (c, &context)) num++;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
-
- out->len = num;
- if (!num) c->serializer->revert (snap);
- return_trace (num);
- }
-
- struct sanitize_closure_t
- {
- const ValueFormat *valueFormats;
- unsigned int len1; /* valueFormats[0].get_len() */
- unsigned int stride; /* 1 + len1 + len2 */
- };
-
- bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this)
- && c->check_range (&firstPairValueRecord,
- len,
- HBUINT16::static_size,
- closure->stride))) return_trace (false);
-
- unsigned int count = len;
- const PairValueRecord *record = &firstPairValueRecord;
- return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
- closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
- }
-
- protected:
- HBUINT16 len; /* Number of PairValueRecords */
- PairValueRecord firstPairValueRecord;
- /* Array of PairValueRecords--ordered
- * by GlyphID of the second glyph */
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct PairPosFormat1
-{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
ValueFormat valueFormat[2]; /* [0] Defines the types of data in
@@ -251,11 +25,11 @@ struct PairPosFormat1
/* [1] Defines the types of data in
* ValueRecord2--for the second glyph
* in the pair--may be zero (0) */
- Array16OfOffset16To<PairSet>
+ Array16Of<typename Types::template OffsetTo<PairSet>>
pairSet; /* Array of PairSet tables
* ordered by Coverage Index */
public:
- DEFINE_SIZE_ARRAY (10, pairSet);
+ DEFINE_SIZE_ARRAY (8 + Types::size, pairSet);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -265,7 +39,7 @@ struct PairPosFormat1
unsigned int len1 = valueFormat[0].get_len ();
unsigned int len2 = valueFormat[1].get_len ();
- PairSet::sanitize_closure_t closure =
+ typename PairSet::sanitize_closure_t closure =
{
valueFormat,
len1,
@@ -275,14 +49,13 @@ struct PairPosFormat1
return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
}
-
bool intersects (const hb_set_t *glyphs) const
{
return
+ hb_zip (this+coverage, pairSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
- | hb_map ([glyphs, this] (const Offset16To<PairSet> &_)
+ | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
{ return (this+_).intersects (glyphs, valueFormat); })
| hb_any
;
@@ -358,7 +131,7 @@ struct PairPosFormat1
+ hb_zip (this+coverage, pairSet)
| hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
+ | hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _)
{
auto snap = c->serializer->snapshot ();
auto *o = out->pairSet.serialize_append (c->serializer);
@@ -391,7 +164,7 @@ struct PairPosFormat1
unsigned format1 = 0;
unsigned format2 = 0;
- for (const Offset16To<PairSet>& _ :
+ for (const auto & _ :
+ hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
{
const PairSet& set = (this + _);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
index 3f5f9959c4..a80fe0c226 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -7,11 +7,12 @@ namespace OT {
namespace Layout {
namespace GPOS_impl {
-struct PairPosFormat2
+template <typename Types>
+struct PairPosFormat2_4
{
protected:
HBUINT16 format; /* Format identifier--format = 2 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
ValueFormat valueFormat1; /* ValueRecord definition--for the
@@ -20,11 +21,11 @@ struct PairPosFormat2
ValueFormat valueFormat2; /* ValueRecord definition--for the
* second glyph of the pair--may be
* zero (0) */
- Offset16To<ClassDef>
+ typename Types::template OffsetTo<ClassDef>
classDef1; /* Offset to ClassDef table--from
* beginning of PairPos subtable--for
* the first glyph of the pair */
- Offset16To<ClassDef>
+ typename Types::template OffsetTo<ClassDef>
classDef2; /* Offset to ClassDef table--from
* beginning of PairPos subtable--for
* the second glyph of the pair */
@@ -36,7 +37,7 @@ struct PairPosFormat2
* class1-major, class2-minor,
* Each entry has value1 and value2 */
public:
- DEFINE_SIZE_ARRAY (16, values);
+ DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -216,10 +217,23 @@ struct PairPosFormat2
}
bail:
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "kerning glyphs at %d,%d",
+ c->buffer->idx, skippy_iter.idx);
+ }
applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "kerned glyphs at %d,%d",
+ c->buffer->idx, skippy_iter.idx);
+ }
+
success:
if (applied_first || applied_second)
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh
new file mode 100644
index 0000000000..4578fbd1d6
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh
@@ -0,0 +1,189 @@
+#ifndef OT_LAYOUT_GPOS_PAIRSET_HH
+#define OT_LAYOUT_GPOS_PAIRSET_HH
+
+#include "PairValueRecord.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+template <typename Types>
+struct PairSet
+{
+ template <typename Types2>
+ friend struct PairPosFormat1_3;
+
+ using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
+
+ protected:
+ HBUINT16 len; /* Number of PairValueRecords */
+ PairValueRecord firstPairValueRecord;
+ /* Array of PairValueRecords--ordered
+ * by GlyphID of the second glyph */
+ public:
+ DEFINE_SIZE_MIN (2);
+
+ struct sanitize_closure_t
+ {
+ const ValueFormat *valueFormats;
+ unsigned int len1; /* valueFormats[0].get_len() */
+ unsigned int stride; /* 1 + len1 + len2 */
+ };
+
+ bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && c->check_range (&firstPairValueRecord,
+ len,
+ HBUINT16::static_size,
+ closure->stride))) return_trace (false);
+
+ unsigned int count = len;
+ const PairValueRecord *record = &firstPairValueRecord;
+ return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
+ closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
+ }
+
+ bool intersects (const hb_set_t *glyphs,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (glyphs->has (record->secondGlyph))
+ return true;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ return false;
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ c->input->add_array (&record->secondGlyph, len, record_size);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (c->glyph_set->has (record->secondGlyph))
+ { record->collect_variation_indices (c, valueFormats, this); }
+
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ }
+
+ bool apply (hb_ot_apply_context_t *c,
+ const ValueFormat *valueFormats,
+ unsigned int pos) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
+ &firstPairValueRecord,
+ len,
+ record_size);
+ if (record)
+ {
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "kerning glyphs at %d,%d",
+ c->buffer->idx, pos);
+ }
+
+ bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+ bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "kerned glyphs at %d,%d",
+ c->buffer->idx, pos);
+ }
+
+ if (applied_first || applied_second)
+ buffer->unsafe_to_break (buffer->idx, pos + 1);
+ if (len2)
+ pos++;
+
+ buffer->idx = pos;
+ return_trace (true);
+ }
+ buffer->unsafe_to_concat (buffer->idx, pos + 1);
+ return_trace (false);
+ }
+
+ bool subset (hb_subset_context_t *c,
+ const ValueFormat valueFormats[2],
+ const ValueFormat newFormats[2]) const
+ {
+ TRACE_SUBSET (this);
+ auto snap = c->serializer->snapshot ();
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->len = 0;
+
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+
+ typename PairValueRecord::context_t context =
+ {
+ this,
+ valueFormats,
+ newFormats,
+ len1,
+ &glyph_map,
+ c->plan->layout_variation_idx_map
+ };
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len, num = 0;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (glyphset.has (record->secondGlyph)
+ && record->subset (c, &context)) num++;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+
+ out->len = num;
+ if (!num) c->serializer->revert (snap);
+ return_trace (num);
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRSET_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
new file mode 100644
index 0000000000..bd95abde16
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
@@ -0,0 +1,99 @@
+#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
+#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
+
+#include "ValueFormat.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+template <typename Types>
+struct PairValueRecord
+{
+ template <typename Types2>
+ friend struct PairSet;
+
+ protected:
+ typename Types::HBGlyphID
+ secondGlyph; /* GlyphID of second glyph in the
+ * pair--first glyph is listed in the
+ * Coverage table */
+ ValueRecord values; /* Positioning data for the first glyph
+ * followed by for second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (Types::size, values);
+
+ int cmp (hb_codepoint_t k) const
+ { return secondGlyph.cmp (k); }
+
+ struct context_t
+ {
+ const void *base;
+ const ValueFormat *valueFormats;
+ const ValueFormat *newFormats;
+ unsigned len1; /* valueFormats[0].get_len() */
+ const hb_map_t *glyph_map;
+ const hb_map_t *layout_variation_idx_map;
+ };
+
+ bool subset (hb_subset_context_t *c,
+ context_t *closure) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *s = c->serializer;
+ auto *out = s->start_embed (*this);
+ if (unlikely (!s->extend_min (out))) return_trace (false);
+
+ out->secondGlyph = (*closure->glyph_map)[secondGlyph];
+
+ closure->valueFormats[0].copy_values (s,
+ closure->newFormats[0],
+ closure->base, &values[0],
+ closure->layout_variation_idx_map);
+ closure->valueFormats[1].copy_values (s,
+ closure->newFormats[1],
+ closure->base,
+ &values[closure->len1],
+ closure->layout_variation_idx_map);
+
+ return_trace (true);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const ValueFormat *valueFormats,
+ const void *base) const
+ {
+ unsigned record1_len = valueFormats[0].get_len ();
+ unsigned record2_len = valueFormats[1].get_len ();
+ const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
+
+ if (valueFormats[0].has_device ())
+ valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
+
+ if (valueFormats[1].has_device ())
+ valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
+ }
+
+ bool intersects (const hb_set_t& glyphset) const
+ {
+ return glyphset.has(secondGlyph);
+ }
+
+ const Value* get_values_1 () const
+ {
+ return &values[0];
+ }
+
+ const Value* get_values_2 (ValueFormat format1) const
+ {
+ return &values[format1.get_len ()];
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
index 57e146befd..702f578b3c 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
@@ -45,10 +45,7 @@ struct SinglePos
ValueFormat new_format = src->get_value_format ();
if (glyph_val_iter_pairs)
- {
format = get_format (glyph_val_iter_pairs);
- new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second));
- }
u.format = format;
switch (u.format) {
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
index 8b7840ed0e..7cbdf6dc6c 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
@@ -39,12 +39,10 @@ struct SinglePosFormat1
{
if (!valueFormat.has_device ()) return;
- auto it =
- + hb_iter (this+coverage)
- | hb_filter (c->glyph_set)
- ;
+ hb_set_t intersection;
+ (this+coverage).intersect_set (*c->glyph_set, intersection);
+ if (!intersection) return;
- if (!it) return;
valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ()));
}
@@ -62,8 +60,22 @@ struct SinglePosFormat1
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "positioning glyph at %d",
+ c->buffer->idx);
+ }
+
valueFormat.apply_value (c, this, values, buffer->cur_pos());
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "positioned glyph at %d",
+ c->buffer->idx);
+ }
+
buffer->idx++;
return_trace (true);
}
@@ -104,9 +116,11 @@ struct SinglePosFormat1
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
+ hb_set_t intersection;
+ (this+coverage).intersect_set (glyphset, intersection);
+
auto it =
- + hb_iter (this+coverage)
- | hb_filter (glyphset)
+ + hb_iter (intersection)
| hb_map_retains_sorting (glyph_map)
| hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
;
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh
index 0d038b4422..518fa9dcb0 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh
@@ -70,10 +70,24 @@ struct SinglePosFormat2
if (likely (index >= valueCount)) return_trace (false);
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "positioning glyph at %d",
+ c->buffer->idx);
+ }
+
valueFormat.apply_value (c, this,
&values[index * valueFormat.get_len ()],
buffer->cur_pos());
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "positioned glyph at %d",
+ c->buffer->idx);
+ }
+
buffer->idx++;
return_trace (true);
}