[subset] GPOS 5 MarkToLigature subsetting support

This commit is contained in:
Qunxin Liu 2020-02-06 15:08:26 -08:00 committed by Garret Rieger
parent a99e8721bf
commit 3a0b05faf1
25 changed files with 121 additions and 8 deletions

View File

@ -544,8 +544,7 @@ struct AnchorMatrix
hb_requires (hb_is_iterator (Iterator))> hb_requires (hb_is_iterator (Iterator))>
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
unsigned num_rows, unsigned num_rows,
AnchorMatrix const *offset_matrix, const AnchorMatrix *offset_matrix,
const hb_map_t *layout_variation_idx_map,
Iterator index_iter) Iterator index_iter)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
@ -566,6 +565,27 @@ struct AnchorMatrix
return_trace (true); return_trace (true);
} }
bool subset (hb_subset_context_t *c,
unsigned cols,
const hb_map_t *klass_mapping) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
hb_vector_t<unsigned> indexes;
for (unsigned row : + hb_range ((unsigned) rows))
{
+ hb_range (cols)
| hb_filter (klass_mapping)
| hb_map ([=] (const unsigned col) { return row * cols + col; })
| hb_sink (indexes)
;
}
out->serialize (c->serializer, (unsigned) rows, this, indexes.iter ());
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -2025,10 +2045,30 @@ typedef AnchorMatrix LigatureAttach; /* component-major--
* mark-minor-- * mark-minor--
* ordered by class--zero-based. */ * ordered by class--zero-based. */
typedef OffsetListOf<LigatureAttach> LigatureArray; /* Array of LigatureAttach tables ordered by LigatureCoverage Index */
/* Array of LigatureAttach struct LigatureArray : OffsetListOf<LigatureAttach>
* tables ordered by {
* LigatureCoverage Index */ template <typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
bool subset (hb_subset_context_t *c,
unsigned cols,
const hb_map_t *klass_mapping,
const LigatureArray &src_lig_array,
Iterator ligature_iter)
{
TRACE_SERIALIZE (this);
if (!ligature_iter.len ()) return_trace (false);
if (unlikely (!c->serializer->extend_min ((*this)))) return_trace (false);
for (unsigned i : ligature_iter)
{
auto *out = serialize_append (c->serializer);
if (unlikely (!out)) break;
out->serialize_subset (c, src_lig_array.arrayZ[i], &src_lig_array, this, cols, klass_mapping);
}
return_trace (this->len);
}
};
struct MarkLigPosFormat1 struct MarkLigPosFormat1
{ {
@ -2130,8 +2170,61 @@ struct MarkLigPosFormat1
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
// TODO(subset) const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
hb_map_t klass_mapping;
Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
if (!klass_mapping.get_population ()) return_trace (false);
out->classCount = klass_mapping.get_population ();
auto mark_iter =
+ hb_zip (this+markCoverage, this+markArray)
| hb_filter (glyphset, hb_first)
;
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ mark_iter
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
if (!out->markCoverage.serialize (c->serializer, out)
.serialize (c->serializer, new_coverage.iter ()))
return_trace (false); return_trace (false);
out->markArray.serialize (c->serializer, out)
.serialize (c->serializer, &klass_mapping, &(this+markArray), + mark_iter
| hb_map (hb_second));
unsigned ligcount = (this+ligatureArray).len;
auto ligature_iter =
+ hb_zip (this+ligatureCoverage, hb_range (ligcount))
| hb_filter (glyphset, hb_first)
;
new_coverage.reset ();
+ ligature_iter
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
if (!out->ligatureCoverage.serialize (c->serializer, out)
.serialize (c->serializer, new_coverage.iter ()))
return_trace (false);
out->ligatureArray.serialize (c->serializer, out)
.subset (c, (unsigned) classCount, &klass_mapping, this+ligatureArray, + ligature_iter
| hb_map (hb_second));
return_trace (true);
} }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const

View File

@ -17,6 +17,7 @@ EXTRA_DIST += \
expected/layout.gpos2 \ expected/layout.gpos2 \
expected/layout.gpos3 \ expected/layout.gpos3 \
expected/layout.gpos4 \ expected/layout.gpos4 \
expected/layout.gpos5 \
expected/layout.gpos6 \ expected/layout.gpos6 \
expected/layout.gpos8 \ expected/layout.gpos8 \
expected/layout.gsub3 \ expected/layout.gsub3 \

View File

@ -16,6 +16,7 @@ TESTS = \
tests/layout.gpos2.tests \ tests/layout.gpos2.tests \
tests/layout.gpos3.tests \ tests/layout.gpos3.tests \
tests/layout.gpos4.tests \ tests/layout.gpos4.tests \
tests/layout.gpos5.tests \
tests/layout.gpos6.tests \ tests/layout.gpos6.tests \
tests/layout.gpos8.tests \ tests/layout.gpos8.tests \
tests/layout.gsub3.tests \ tests/layout.gsub3.tests \

Binary file not shown.

View File

@ -0,0 +1,18 @@
FONTS:
gpos5_font1.otf
PROFILES:
keep-layout.txt
keep-layout-retain-gids.txt
SUBSETS:
A
B
AB
AC
ABC
ABE
ABCE
ABD
ABCD
*