29 #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
30 #define HB_OT_LAYOUT_GPOS_TABLE_HH
38 static void Markclass_closure_and_remap_indexes (
const Coverage &mark_coverage,
39 const MarkArray &mark_array,
44 #define attach_chain() var.i16[0]
45 #define attach_type() var.u8[2]
108 unsigned int get_len ()
const {
return hb_popcount ((
unsigned int) *
this); }
117 unsigned int format = *
this;
122 #ifndef HB_NO_VERTICAL
143 bool use_x_device =
font->x_ppem ||
font->num_coords;
144 bool use_y_device =
font->y_ppem ||
font->num_coords;
146 if (!use_x_device && !use_y_device)
return ret;
173 unsigned int format = *
this;
181 template<
typename Iterator,
184 unsigned int new_format = 0;
193 unsigned int new_format,
196 const hb_map_t *layout_variation_idx_map)
const
198 unsigned int format = *
this;
213 unsigned int new_format,
218 if (!(new_format & flag))
return;
262 unsigned int format = *
this;
277 static inline Offset16To<Device>& get_device (
Value*
value)
279 return *
static_cast<Offset16To<Device> *
> (
value);
281 static inline const Offset16To<Device>& get_device (
const Value*
value,
bool *worked=
nullptr)
283 if (worked) *worked |= bool (*
value);
284 return *
static_cast<const Offset16To<Device> *
> (
value);
288 const Value *src_value,
const hb_map_t *layout_variation_idx_map)
const
290 Value *dst_value =
c->copy (*src_value);
292 if (!dst_value)
return false;
293 if (*dst_value == 0)
return true;
297 if ((
base + get_device (src_value)).copy (
c, layout_variation_idx_map))
299 c->add_link (*dst_value,
c->pop_pack ());
309 static inline const HBINT16& get_short (
const Value*
value,
bool *worked=
nullptr)
311 if (worked) *worked |= bool (*
value);
319 unsigned int format = *
this;
338 for (
unsigned int i = 0;
i <
count;
i++) {
354 for (
unsigned int i = 0;
i <
count;
i++) {
373 template<
typename Iterator,
typename SrcLookup>
375 const SrcLookup *
src,
377 const hb_map_t *layout_variation_idx_map);
383 float *
x,
float *
y)
const
416 float *
x,
float *
y)
const
426 unsigned int x_ppem =
font->x_ppem;
427 unsigned int y_ppem =
font->y_ppem;
431 ret = (x_ppem || y_ppem) &&
461 float *
x,
float *
y)
const
467 if (
font->x_ppem ||
font->num_coords)
469 if (
font->y_ppem ||
font->num_coords)
480 const hb_map_t *layout_variation_idx_map)
const
518 float *
x,
float *
y)
const
522 case 1:
u.format1.get_anchor (
c, glyph_id,
x,
y);
return;
523 case 2:
u.format2.get_anchor (
c, glyph_id,
x,
y);
return;
524 case 3:
u.format3.get_anchor (
c, glyph_id,
x,
y);
return;
555 c->plan->layout_variation_idx_map))));
566 u.format3.collect_variation_indices (
c);
587 unsigned int cols,
bool *found)
const
591 *found = !
matrixZ[
row * cols + col].is_null ();
595 template <
typename Iterator,
598 Iterator index_iter)
const
600 for (
unsigned i : index_iter)
604 template <
typename Iterator,
608 Iterator index_iter)
const
612 auto *
out =
c->serializer->start_embed (
this);
618 for (
const unsigned i : index_iter)
635 for (
unsigned int i = 0;
i <
count;
i++)
661 const void *src_base,
662 const hb_map_t *klass_mapping)
const
665 auto *
out =
c->serializer->embed (
this);
674 const void *src_base)
const
693 unsigned int glyph_pos)
const
698 unsigned int mark_class =
record.klass;
707 float mark_x, mark_y, base_x, base_y;
711 glyph_anchor.
get_anchor (
c,
buffer->info[glyph_pos].codepoint, &base_x, &base_y);
714 o.x_offset =
roundf (base_x - mark_x);
715 o.y_offset =
roundf (base_y - mark_y);
717 o.attach_chain() = (int) glyph_pos - (
int)
buffer->idx;
724 template <
typename Iterator,
728 const hb_map_t *klass_mapping)
const
731 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
733 auto*
out =
c->serializer->start_embed (
this);
737 + hb_zip (coverage, this->
iter ())
738 | hb_filter (glyphset, hb_first)
742 unsigned new_length = 0;
743 for (
const auto& mark_record : mark_iter) {
744 if (
unlikely (!mark_record.subset (
c,
this, klass_mapping)))
749 if (
unlikely (!
c->serializer->check_assign (
out->len, new_length,
769 {
return (
this+
coverage).intersects (glyphs); }
778 | hb_filter (
c->glyph_set)
805 template<
typename Iterator,
809 const SrcLookup *
src,
812 const hb_map_t *layout_variation_idx_map)
814 if (
unlikely (!
c->extend_min (
this)))
return;
821 src->get_value_format ().copy_values (
c, newFormat,
src, &
_, layout_variation_idx_map);
829 | hb_map_retains_sorting (hb_first)
832 coverage.serialize_serialize (
c, glyphs);
838 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
839 const hb_map_t &glyph_map = *
c->plan->glyph_map;
843 | hb_filter (glyphset)
844 | hb_map_retains_sorting (glyph_map)
848 bool ret = bool (
it);
849 SinglePos_serialize (
c->serializer,
this,
it,
c->plan->layout_variation_idx_map);
878 {
return (
this+
coverage).intersects (glyphs); }
887 | hb_filter (
c->glyph_set, hb_first)
895 for (
unsigned i : +
it
925 template<
typename Iterator,
929 const SrcLookup *
src,
932 const hb_map_t *layout_variation_idx_map)
934 auto out =
c->extend_min (
this);
942 {
src->get_value_format ().copy_values (
c, newFormat,
src, &
_, layout_variation_idx_map); })
947 | hb_map_retains_sorting (hb_first)
950 coverage.serialize_serialize (
c, glyphs);
956 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
957 const hb_map_t &glyph_map = *
c->plan->glyph_map;
964 | hb_filter (glyphset, hb_first)
967 return hb_pair (glyph_map[
_.first],
968 values_array.sub_array (
_.second * sub_length,
973 bool ret = bool (
it);
974 SinglePos_serialize (
c->serializer,
this,
it,
c->plan->layout_variation_idx_map);
1002 template<
typename Iterator,
1008 for (
const auto iter : glyph_val_iter_pairs)
1009 for (
const auto _ : hb_zip (
iter.second, first_val_iter))
1010 if (
_.first !=
_.second)
1017 template<
typename Iterator,
1021 const SrcLookup*
src,
1022 Iterator glyph_val_iter_pairs,
1023 const hb_map_t *layout_variation_idx_map)
1025 if (
unlikely (!
c->extend_min (
u.format)))
return;
1029 if (glyph_val_iter_pairs)
1037 case 1:
u.format1.serialize (
c,
1039 glyph_val_iter_pairs,
1041 layout_variation_idx_map);
1043 case 2:
u.format2.serialize (
c,
1045 glyph_val_iter_pairs,
1047 layout_variation_idx_map);
1053 template <
typename context_t,
typename ...Ts>
1054 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
1059 case 1:
return_trace (
c->dispatch (
u.format1, std::forward<Ts> (ds)...));
1060 case 2:
return_trace (
c->dispatch (
u.format2, std::forward<Ts> (ds)...));
1073 template<
typename Iterator,
typename SrcLookup>
1076 const SrcLookup *
src,
1078 const hb_map_t *layout_variation_idx_map)
1079 {
c->start_embed<SinglePos> ()->serialize (
c,
src,
it, layout_variation_idx_map); }
1103 auto *
s =
c->serializer;
1104 auto *
out =
s->start_embed (*
this);
1124 const void *
base)
const
1126 unsigned record1_len = valueFormats[0].
get_len ();
1127 unsigned record2_len = valueFormats[1].
get_len ();
1130 if (valueFormats[0].has_device ())
1133 if (valueFormats[1].has_device ())
1169 unsigned int len1 = valueFormats[0].
get_len ();
1170 unsigned int len2 = valueFormats[1].
get_len ();
1171 unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
1175 for (
unsigned int i = 0;
i <
count;
i++)
1179 record = &StructAtOffset<const PairValueRecord> (
record, record_size);
1187 unsigned int len1 = valueFormats[0].
get_len ();
1188 unsigned int len2 = valueFormats[1].
get_len ();
1189 unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
1192 c->input->add_array (&
record->secondGlyph,
len, record_size);
1198 unsigned len1 = valueFormats[0].
get_len ();
1199 unsigned len2 = valueFormats[1].
get_len ();
1200 unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
1204 for (
unsigned i = 0;
i <
count;
i++)
1206 if (
c->glyph_set->has (
record->secondGlyph))
1207 {
record->collect_variation_indices (
c, valueFormats,
this); }
1209 record = &StructAtOffset<const PairValueRecord> (
record, record_size);
1215 unsigned int pos)
const
1219 unsigned int len1 = valueFormats[0].
get_len ();
1220 unsigned int len2 = valueFormats[1].
get_len ();
1221 unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
1231 if (applied_first || applied_second)
1247 auto snap =
c->serializer->snapshot ();
1249 auto *
out =
c->serializer->start_embed (*
this);
1253 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
1254 const hb_map_t &glyph_map = *
c->plan->glyph_map;
1256 unsigned len1 = valueFormats[0].
get_len ();
1257 unsigned len2 = valueFormats[1].
get_len ();
1258 unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
1267 c->plan->layout_variation_idx_map
1272 for (
unsigned i = 0;
i <
count;
i++)
1276 record = &StructAtOffset<const PairValueRecord> (
record, record_size);
1280 if (!
num)
c->serializer->revert (snap);
1294 if (!(
c->check_struct (
this)
1297 HBUINT16::static_size,
1321 | hb_filter (*glyphs, hb_first)
1336 | hb_filter (
c->glyph_set, hb_first)
1351 for (
unsigned int i = 0;
i <
count;
i++)
1367 if (!skippy_iter.
next (&unsafe_to))
1380 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
1381 const hb_map_t &glyph_map = *
c->plan->glyph_map;
1383 auto *
out =
c->serializer->start_embed (*
this);
1391 out->valueFormat[0] = newFormats.
first;
1392 out->valueFormat[1] = newFormats.
second;
1398 | hb_filter (glyphset, hb_first)
1401 auto snap =
c->serializer->snapshot ();
1402 auto *
o =
out->pairSet.serialize_append (
c->serializer);
1407 out->pairSet.pop ();
1408 c->serializer->revert (snap);
1415 | hb_sink (new_coverage)
1418 out->coverage.serialize_serialize (
c->serializer, new_coverage.
iter ());
1428 unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
1430 unsigned format1 = 0;
1431 unsigned format2 = 0;
1438 for (
unsigned i = 0;
i <
set.len;
i++)
1440 if (
record->intersects (glyphset))
1445 record = &StructAtOffset<const PairValueRecord> (
record, record_size);
1449 return hb_pair (format1, format2);
1493 return (
this+
coverage).intersects (glyphs) &&
1503 hb_set_t klass1_glyphs, klass2_glyphs;
1504 if (!(
this+
classDef1).collect_coverage (&klass1_glyphs))
return;
1505 if (!(
this+
classDef2).collect_coverage (&klass2_glyphs))
return;
1508 for (
const unsigned cp : +
c->glyph_set->iter () | hb_filter (
this +
coverage))
1510 if (!klass1_glyphs.
has (cp)) class1_set.
add (0);
1514 class1_set.
add (klass1);
1519 for (
const unsigned cp : +
c->glyph_set->iter () | hb_filter (klass2_glyphs))
1522 class2_set.
add (klass2);
1533 for (
const unsigned class1_idx : class1_set.
iter ())
1535 for (
const unsigned class2_idx : class2_set.
iter ())
1565 if (!skippy_iter.
next (&unsafe_to))
1573 unsigned int record_len = len1 + len2;
1575 unsigned int klass1 = (
this+
classDef1).get_class (
buffer->cur().codepoint);
1576 unsigned int klass2 = (
this+
classDef2).get_class (
buffer->info[skippy_iter.
idx].codepoint);
1585 bool applied_first =
false, applied_second =
false;
1595 #ifndef HB_SPLIT_KERN
1622 unsigned i = horizontal ? 0 : 1;
1632 dst2[
i + 2] += kern2;
1637 dst1[
i + 2] +=
src[
i + 2] - kern2;
1641 applied_first = applied_second =
kern != 0;
1654 if (applied_first || applied_second)
1671 auto *
out =
c->serializer->start_embed (*
this);
1680 out->classDef2.serialize_subset (
c,
classDef2,
this, &klass2_map,
true,
false);
1690 out->valueFormat1 = newFormats.
first;
1693 for (
unsigned class1_idx : + hb_range ((
unsigned)
class1Count) | hb_filter (klass1_map))
1695 for (
unsigned class2_idx : + hb_range ((
unsigned)
class2Count) | hb_filter (klass2_map))
1697 unsigned idx = (class1_idx * (unsigned)
class2Count + class2_idx) * (len1 + len2);
1703 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
1704 const hb_map_t &glyph_map = *
c->plan->glyph_map;
1708 | hb_filter (glyphset)
1709 | hb_map_retains_sorting (glyph_map)
1712 out->coverage.serialize_serialize (
c->serializer,
it);
1723 unsigned format1 = 0;
1724 unsigned format2 = 0;
1726 for (
unsigned class1_idx : + hb_range ((
unsigned)
class1Count) | hb_filter (klass1_map))
1728 for (
unsigned class2_idx : + hb_range ((
unsigned)
class2Count) | hb_filter (klass2_map))
1730 unsigned idx = (class1_idx * (unsigned)
class2Count + class2_idx) * (len1 + len2);
1736 return hb_pair (format1, format2);
1743 if (!(
c->check_struct (
this)
1750 unsigned int stride = len1 + len2;
1792 template <
typename context_t,
typename ...Ts>
1793 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
1798 case 1:
return_trace (
c->dispatch (
u.format1, std::forward<Ts> (ds)...));
1799 case 2:
return_trace (
c->dispatch (
u.format2, std::forward<Ts> (ds)...));
1824 const void *src_base)
const
1831 const void *src_base)
const
1834 auto *
out =
c->serializer->embed (
this);
1861 {
return (
this+
coverage).intersects (glyphs); }
1868 | hb_filter (
c->glyph_set, hb_first)
1889 unsigned unsafe_from;
1890 if (!skippy_iter.
prev (&unsafe_from))
1892 buffer->unsafe_to_concat_from_outbuffer (unsafe_from,
buffer->idx + 1);
1899 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
1903 unsigned int i = skippy_iter.
idx;
1907 float entry_x, entry_y, exit_x, exit_y;
1908 (
this+prev_record.
exitAnchor).get_anchor (
c,
buffer->info[
i].codepoint, &exit_x, &exit_y);
1909 (
this+this_record.
entryAnchor).get_anchor (
c,
buffer->info[
j].codepoint, &entry_x, &entry_y);
1915 switch (
c->direction) {
1920 pos[
j].x_advance -=
d;
1921 pos[
j].x_offset -=
d;
1925 pos[
i].x_advance -=
d;
1926 pos[
i].x_offset -=
d;
1934 pos[
j].y_advance -=
d;
1935 pos[
j].y_offset -=
d;
1939 pos[
i].y_advance -=
d;
1940 pos[
i].y_offset -=
d;
1963 unsigned int k =
child;
1966 x_offset = -x_offset;
1967 y_offset = -y_offset;
1995 template <
typename Iterator,
1999 const void *src_base)
2001 if (
unlikely (!
c->serializer->extend_min ((*
this))))
return;
2007 entry_record.subset (
c, src_base);
2011 | hb_map_retains_sorting (hb_first)
2014 coverage.serialize_serialize (
c->serializer, glyphs);
2020 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
2021 const hb_map_t &glyph_map = *
c->plan->glyph_map;
2023 auto *
out =
c->serializer->start_embed (*
this);
2028 | hb_filter (glyphset, hb_first)
2030 {
return hb_pair (glyph_map[
p.first],
p.second);})
2033 bool ret = bool (
it);
2034 out->serialize (
c,
it,
this);
2058 template <
typename context_t,
typename ...Ts>
2059 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
2064 case 1:
return_trace (
c->dispatch (
u.format1, std::forward<Ts> (ds)...));
2082 static void Markclass_closure_and_remap_indexes (
const Coverage &mark_coverage,
2089 + hb_zip (mark_coverage, mark_array)
2090 | hb_filter (glyphset, hb_first)
2093 | hb_sink (orig_classes)
2097 for (
auto klass : orig_classes.
iter ())
2099 if (klass_mapping->
has (klass))
continue;
2100 klass_mapping->
set (klass,
idx);
2118 | hb_filter (
c->glyph_set, hb_first)
2126 unsigned basecount = (
this+
baseArray).rows;
2129 | hb_filter (
c->glyph_set, hb_first)
2134 for (
const unsigned row : base_iter)
2137 | hb_filter (klass_mapping)
2139 | hb_sink (base_indexes)
2165 unsigned unsafe_from;
2166 if (!skippy_iter.
prev (&unsafe_from))
2168 buffer->unsafe_to_concat_from_outbuffer (unsafe_from,
buffer->idx + 1);
2177 if (!_hb_glyph_info_multiplied (&
buffer->info[skippy_iter.
idx]) ||
2178 0 == _hb_glyph_info_get_lig_comp (&
buffer->info[skippy_iter.
idx]) ||
2179 (skippy_iter.
idx == 0 ||
2180 _hb_glyph_info_is_mark (&
buffer->info[skippy_iter.
idx - 1]) ||
2181 _hb_glyph_info_get_lig_id (&
buffer->info[skippy_iter.
idx]) !=
2182 _hb_glyph_info_get_lig_id (&
buffer->info[skippy_iter.
idx - 1]) ||
2183 _hb_glyph_info_get_lig_comp (&
buffer->info[skippy_iter.
idx]) !=
2184 _hb_glyph_info_get_lig_comp (&
buffer->info[skippy_iter.
idx - 1]) + 1
2196 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
2206 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
2207 const hb_map_t &glyph_map = *
c->plan->glyph_map;
2209 auto *
out =
c->serializer->start_embed (*
this);
2221 | hb_filter (glyphset, hb_first)
2228 | hb_sink (new_coverage)
2231 if (!
out->markCoverage.serialize_serialize (
c->serializer, new_coverage.
iter ()))
2238 unsigned basecount = (
this+
baseArray).rows;
2241 | hb_filter (glyphset, hb_first)
2244 new_coverage.
reset ();
2248 | hb_sink (new_coverage)
2251 if (!
out->baseCoverage.serialize_serialize (
c->serializer, new_coverage.
iter ()))
2255 for (
const unsigned row : + base_iter
2259 | hb_filter (klass_mapping)
2261 | hb_sink (base_indexes)
2267 base_indexes.
iter ());
2303 template <
typename context_t,
typename ...Ts>
2304 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
2309 case 1:
return_trace (
c->dispatch (
u.format1, std::forward<Ts> (ds)...));
2330 template <
typename Iterator,
2334 unsigned class_count,
2335 const hb_map_t *klass_mapping)
const
2338 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
2340 auto *
out =
c->serializer->start_embed (
this);
2343 for (
const auto _ : + hb_zip (coverage, *
this)
2344 | hb_filter (glyphset, hb_first))
2346 auto *
matrix =
out->serialize_append (
c->serializer);
2351 + hb_range (
src.rows * class_count)
2352 | hb_filter ([=] (
unsigned index) {
return klass_mapping->
has (
index % class_count); })
2377 | hb_filter (
c->glyph_set, hb_first)
2388 | hb_filter (
c->glyph_set, hb_first)
2393 for (
const unsigned i : lig_iter)
2396 unsigned row_count = lig_array[
i].rows;
2397 for (
unsigned row : + hb_range (row_count))
2400 | hb_filter (klass_mapping)
2402 | hb_sink (lig_indexes)
2406 lig_array[
i].collect_variation_indices (
c, lig_indexes.
iter ());
2429 unsigned unsafe_from;
2430 if (!skippy_iter.
prev (&unsafe_from))
2432 buffer->unsafe_to_concat_from_outbuffer (unsafe_from,
buffer->idx + 1);
2439 unsigned int j = skippy_iter.
idx;
2443 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
2451 unsigned int comp_count = lig_attach.
rows;
2454 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
2462 unsigned int comp_index;
2463 unsigned int lig_id = _hb_glyph_info_get_lig_id (&
buffer->info[
j]);
2464 unsigned int mark_id = _hb_glyph_info_get_lig_id (&
buffer->cur());
2465 unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&
buffer->cur());
2466 if (lig_id && lig_id == mark_id && mark_comp > 0)
2467 comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&
buffer->cur())) - 1;
2469 comp_index = comp_count - 1;
2477 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
2478 const hb_map_t &glyph_map = *
c->plan->glyph_map;
2480 auto *
out =
c->serializer->start_embed (*
this);
2492 | hb_filter (glyphset, hb_first)
2495 auto new_mark_coverage =
2497 | hb_map_retains_sorting (hb_first)
2498 | hb_map_retains_sorting (glyph_map)
2501 if (!
out->markCoverage.serialize_serialize (
c->serializer, new_mark_coverage))
2508 auto new_ligature_coverage =
2510 | hb_filter (glyphset)
2511 | hb_map_retains_sorting (glyph_map)
2514 if (!
out->ligatureCoverage.serialize_serialize (
c->serializer, new_ligature_coverage))
2556 template <
typename context_t,
typename ...Ts>
2557 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
2562 case 1:
return_trace (
c->dispatch (
u.format1, std::forward<Ts> (ds)...));
2593 | hb_filter (
c->glyph_set, hb_first)
2601 unsigned mark2_count = (
this+
mark2Array).rows;
2604 | hb_filter (
c->glyph_set, hb_first)
2609 for (
const unsigned row : mark2_iter)
2612 | hb_filter (klass_mapping)
2614 | hb_sink (mark2_indexes)
2639 unsigned unsafe_from;
2640 if (!skippy_iter.
prev (&unsafe_from))
2642 buffer->unsafe_to_concat_from_outbuffer (unsafe_from,
buffer->idx + 1);
2646 if (!_hb_glyph_info_is_mark (&
buffer->info[skippy_iter.
idx]))
2648 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
2652 unsigned int j = skippy_iter.
idx;
2654 unsigned int id1 = _hb_glyph_info_get_lig_id (&
buffer->cur());
2655 unsigned int id2 = _hb_glyph_info_get_lig_id (&
buffer->info[
j]);
2656 unsigned int comp1 = _hb_glyph_info_get_lig_comp (&
buffer->cur());
2657 unsigned int comp2 = _hb_glyph_info_get_lig_comp (&
buffer->info[
j]);
2663 else if (comp1 == comp2)
2670 if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
2675 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
2682 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.
idx,
buffer->idx + 1);
2692 const hb_set_t &glyphset = *
c->plan->glyphset_gsub ();
2693 const hb_map_t &glyph_map = *
c->plan->glyph_map;
2695 auto *
out =
c->serializer->start_embed (*
this);
2707 | hb_filter (glyphset, hb_first)
2714 | hb_sink (new_coverage)
2717 if (!
out->mark1Coverage.serialize_serialize (
c->serializer, new_coverage.
iter ()))
2724 unsigned mark2count = (
this+
mark2Array).rows;
2727 | hb_filter (glyphset, hb_first)
2730 new_coverage.
reset ();
2734 | hb_sink (new_coverage)
2737 if (!
out->mark2Coverage.serialize_serialize (
c->serializer, new_coverage.
iter ()))
2741 for (
const unsigned row : + mark2_iter
2745 | hb_filter (klass_mapping)
2747 | hb_sink (mark2_indexes)
2751 out->mark2Array.serialize_subset (
c,
mark2Array,
this, mark2_iter.len (), mark2_indexes.
iter ());
2789 template <
typename context_t,
typename ...Ts>
2790 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
2795 case 1:
return_trace (
c->dispatch (
u.format1, std::forward<Ts> (ds)...));
2841 template <
typename context_t,
typename ...Ts>
2842 typename context_t::return_t
dispatch (context_t *
c,
unsigned int lookup_type, Ts&&... ds)
const
2845 switch (lookup_type) {
2887 {
return Lookup::get_subtable<SubTable> (
i); }
2911 if (
c->is_lookup_visited (this_index))
2914 c->set_lookup_visited (this_index);
2917 c->set_lookup_inactive (this_index);
2926 template <
typename set_t>
2935 template <
typename context_t>
2940 template <
typename context_t,
typename ...Ts>
2941 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
2942 {
return Lookup::dispatch<SubTable> (
c, std::forward<Ts> (ds)...); }
2945 {
return Lookup::subset<SubTable> (
c); }
2948 {
return Lookup::sanitize<SubTable> (
c); }
2970 return GSUBGPOS::subset<PosLookup> (&
l);
2974 {
return GSUBGPOS::sanitize<PosLookup> (
c); }
2983 if (!
c->gpos_lookups->has (
i))
continue;
2992 { GSUBGPOS::closure_lookups<PosLookup> (
face, glyphs, lookup_indexes); }
3001 int chain =
pos[
i].attach_chain(),
type =
pos[
i].attach_type();
3005 pos[
i].attach_chain() = 0;
3007 unsigned int j = (int)
i + chain;
3010 if (
j == new_parent)
3013 reverse_cursive_minor_offset (
pos,
j,
direction, new_parent);
3016 pos[
j].y_offset = -
pos[
i].y_offset;
3018 pos[
j].x_offset = -
pos[
i].x_offset;
3020 pos[
j].attach_chain() = -chain;
3031 int chain =
pos[
i].attach_chain(),
type =
pos[
i].attach_type();
3035 pos[
i].attach_chain() = 0;
3037 unsigned int j = (int)
i + chain;
3049 pos[
i].y_offset +=
pos[
j].y_offset;
3051 pos[
i].x_offset +=
pos[
j].x_offset;
3055 pos[
i].x_offset +=
pos[
j].x_offset;
3056 pos[
i].y_offset +=
pos[
j].y_offset;
3060 for (
unsigned int k =
j; k <
i; k++) {
3061 pos[
i].x_offset -=
pos[k].x_advance;
3062 pos[
i].y_offset -=
pos[k].y_advance;
3065 for (
unsigned int k =
j + 1; k <
i + 1; k++) {
3066 pos[
i].x_offset +=
pos[k].x_advance;
3067 pos[
i].y_offset +=
pos[k].y_advance;
3076 for (
unsigned int i = 0;
i <
count;
i++)
3077 buffer->pos[
i].attach_chain() =
buffer->pos[
i].attach_type() = 0;
3089 _hb_buffer_assert_gsubgpos_vars (
buffer);
3097 for (
unsigned i = 0;
i <
len;
i++)
3102 for (
unsigned i = 0;
i <
len;
i++)
3104 pos[
i].x_offset += _hb_roundf (
font->slant_xy *
pos[
i].y_offset);
3116 #ifndef HB_NO_OT_LAYOUT
3117 template <
typename context_t>
3120 const PosLookup &
l =
c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
3121 return l.dispatch (
c);
3126 const PosLookup &
l =
c->face->table.GPOS.get_relaxed ()->table->get_lookup (this_index);
3127 return l.closure_lookups (
c, this_index);
3132 const PosLookup &
l =
c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
3133 unsigned int saved_lookup_props =
c->lookup_props;
3134 unsigned int saved_lookup_index =
c->lookup_index;
3135 c->set_lookup_index (lookup_index);
3136 c->set_lookup_props (
l.get_props ());
3137 bool ret =
l.dispatch (
c);
3138 c->set_lookup_index (saved_lookup_index);
3139 c->set_lookup_props (saved_lookup_props);
small capitals from c petite p scientific i
[1]
hb_glyph_position_t * hb_buffer_get_glyph_positions(hb_buffer_t *buffer, unsigned int *length)
@ HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT
#define TRACE_SERIALIZE(this)
#define TRACE_SANITIZE(this)
#define TRACE_DISPATCH(this, format)
#define TRACE_APPLY(this)
#define return_trace(RET)
#define TRACE_SUBSET(this)
void const void *obj HB_UNUSED
#define hb_is_iterator(Iter)
auto it hb_map(hb_second)) template< typename Type > inline hb_array_t< Type > operator()(hb_array_t< Type > array
static auto hb_requires(hb_is_iterable(Iterable))> static inline auto end(Iterable &&iterable) HB_AUTO_RETURN(hb_iter(iterable).end()) namespace OT
HB_EXTERN unsigned int start_offset
@ HB_SERIALIZE_ERROR_ARRAY_OVERFLOW
@ HB_SERIALIZE_ERROR_INT_OVERFLOW
@ HB_SUBSET_FLAGS_NO_HINTING
int JSAMPARRAY int int num_rows
AnchorMatrix LigatureAttach
IntType< int16_t > HBINT16
UnsizedArrayOf< Value > ValueRecord
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
[3]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
EGLOutputLayerEXT EGLint EGLAttrib value
GLenum GLsizei GLsizei GLint * values
[16]
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum GLenum GLsizei count
const void GLsizei GLsizei stride
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLenum GLenum GLsizei void * row
#define HB_DIRECTION_IS_FORWARD(dir)
#define HB_DIRECTION_IS_BACKWARD(dir)
#define HB_DIRECTION_IS_HORIZONTAL(dir)
QFuture< QSet< QChar > > set
[10]
QTextStream out(stdout)
[7]
http get(QUrl::toPercentEncoding("/index.html"))
void get_anchor(hb_ot_apply_context_t *c, hb_codepoint_t glyph_id, float *x, float *y) const
void collect_variation_indices(hb_collect_variation_indices_context_t *c) const
bool subset(hb_subset_context_t *c) const
DEFINE_SIZE_UNION(2, format)
bool sanitize(hb_sanitize_context_t *c) const
void collect_variation_indices(hb_collect_variation_indices_context_t *c, Iterator index_iter) const
DEFINE_SIZE_ARRAY(2, matrixZ)
const Anchor & get_anchor(unsigned int row, unsigned int col, unsigned int cols, bool *found) const
bool subset(hb_subset_context_t *c, unsigned num_rows, Iterator index_iter) const
UnsizedArrayOf< Offset16To< Anchor > > matrixZ
bool sanitize(hb_sanitize_context_t *c, unsigned int cols) const
const Type & operator[](int i_) const
union OT::CursivePos::@174 u
CursivePosFormat1 format1
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
bool sanitize(hb_sanitize_context_t *c, const void *base) const
EntryExitRecord * subset(hb_subset_context_t *c, const void *src_base) const
void collect_variation_indices(hb_collect_variation_indices_context_t *c, const void *src_base) const
Offset16To< Anchor > entryAnchor
Offset16To< Anchor > exitAnchor
GPOS_accelerator_t(hb_face_t *face)
void closure_lookups(hb_face_t *face, const hb_set_t *glyphs, hb_set_t *lookup_indexes) const
bool sanitize(hb_sanitize_context_t *c) const
const PosLookup & get_lookup(unsigned int i) const
static void position_finish_offsets(hb_font_t *font, hb_buffer_t *buffer)
void collect_variation_indices(hb_collect_variation_indices_context_t *c) const
static void position_finish_advances(hb_font_t *font, hb_buffer_t *buffer)
GSUBGPOS::accelerator_t< GPOS > accelerator_t
bool subset(hb_subset_context_t *c) const
static constexpr hb_tag_t tableTag
static void position_start(hb_font_t *font, hb_buffer_t *buffer)
HB_INTERNAL bool is_blocklisted(hb_blob_t *blob, hb_face_t *face) const
accelerator_t(hb_face_t *face)
unsigned int get_lookup_count() const
const Lookup & get_lookup(unsigned int i) const
static HB_INTERNAL int cmp(const IntType *a, const IntType *b)
bool sanitize(hb_sanitize_context_t *c) const
bool subset(hb_subset_context_t *c, Iterator coverage, unsigned class_count, const hb_map_t *klass_mapping) const
bool sanitize(hb_sanitize_context_t *c) const
bool apply(hb_ot_apply_context_t *c, unsigned int mark_index, unsigned int glyph_index, const AnchorMatrix &anchors, unsigned int class_count, unsigned int glyph_pos) const
bool subset(hb_subset_context_t *c, Iterator coverage, const hb_map_t *klass_mapping) const
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
union OT::MarkBasePos::@175 u
MarkBasePosFormat1 format1
MarkLigPosFormat1 format1
union OT::MarkLigPos::@176 u
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
MarkMarkPosFormat1 format1
union OT::MarkMarkPos::@177 u
MarkRecord * subset(hb_subset_context_t *c, const void *src_base, const hb_map_t *klass_mapping) const
void collect_variation_indices(hb_collect_variation_indices_context_t *c, const void *src_base) const
Offset16To< Anchor > markAnchor
unsigned get_class() const
bool sanitize(hb_sanitize_context_t *c, const void *base) const
union OT::PairPos::@173 u
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
const ValueFormat * valueFormats
PairValueRecord firstPairValueRecord
bool intersects(const hb_set_t *glyphs, const ValueFormat *valueFormats) const
bool subset(hb_subset_context_t *c, const ValueFormat valueFormats[2], const ValueFormat newFormats[2]) const
void collect_glyphs(hb_collect_glyphs_context_t *c, const ValueFormat *valueFormats) const
bool sanitize(hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
void collect_variation_indices(hb_collect_variation_indices_context_t *c, const ValueFormat *valueFormats) const
bool apply(hb_ot_apply_context_t *c, const ValueFormat *valueFormats, unsigned int pos) const
const hb_map_t * glyph_map
const ValueFormat * newFormats
const hb_map_t * layout_variation_idx_map
const ValueFormat * valueFormats
void collect_variation_indices(hb_collect_variation_indices_context_t *c, const ValueFormat *valueFormats, const void *base) const
bool intersects(const hb_set_t &glyphset) const
const Value * get_values_2(ValueFormat format1) const
const Value * get_values_1() const
DEFINE_SIZE_ARRAY(2, values)
int cmp(hb_codepoint_t k) const
bool subset(hb_subset_context_t *c, context_t *closure) const
bool subset(hb_subset_context_t *c) const
bool sanitize(hb_sanitize_context_t *c) const
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
static bool apply_recurse_func(hb_ot_apply_context_t *c, unsigned int lookup_index)
static HB_INTERNAL hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func(hb_closure_lookups_context_t *c, unsigned this_index)
bool apply(hb_ot_apply_context_t *c) const
const SubTable & get_subtable(unsigned int i) const
static context_t::return_t dispatch_recurse_func(context_t *c, unsigned int lookup_index)
bool intersects(const hb_set_t *glyphs) const
void collect_coverage(set_t *glyphs) const
hb_collect_glyphs_context_t::return_t collect_glyphs(hb_collect_glyphs_context_t *c) const
hb_closure_lookups_context_t::return_t closure_lookups(hb_closure_lookups_context_t *c, unsigned this_index) const
union OT::PosLookupSubTable::@178 u
ChainContextPos chainContext
bool intersects(const hb_set_t *glyphs, unsigned int lookup_type) const
context_t::return_t dispatch(context_t *c, unsigned int lookup_type, Ts &&... ds) const
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
unsigned get_format(Iterator glyph_val_iter_pairs)
void serialize(hb_serialize_context_t *c, const SrcLookup *src, Iterator glyph_val_iter_pairs, const hb_map_t *layout_variation_idx_map)
union OT::SinglePos::@172 u
static return_t default_return_value()
void set_lookup_props(unsigned int lookup_props)
bool next(unsigned *unsafe_to=nullptr)
void reset(unsigned int start_index_, unsigned int num_items_)
bool prev(unsigned *unsafe_from=nullptr)
hb_array_t sub_array(unsigned int start_offset=0, unsigned int *seg_count=nullptr) const
unsigned int get_population() const
bool set(K key, const V &value)
bool has(K k, V *vp=nullptr) const
bool has(hb_codepoint_t k) const
unsigned int get_population() const
void add(hb_codepoint_t g)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent