Merge pull request #2701 from googlefonts/Mark-To-Ligature_grieger

[subset] GPOS 5 MarkToLigature subsetting support
This commit is contained in:
Behdad Esfahbod 2021-02-10 18:13:38 -07:00 committed by GitHub
commit c7d232ce4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 126 additions and 6 deletions

View File

@ -566,6 +566,26 @@ 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);
auto indexes =
+ hb_range (rows * cols)
| hb_filter ([=] (unsigned index) { return klass_mapping->has (index % cols); })
;
out->serialize (c->serializer,
(unsigned) rows,
this,
c->plan->layout_variation_idx_map,
indexes);
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,40 @@ 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,
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);
unsigned ligature_count = 0;
for (hb_codepoint_t gid : coverage)
{
ligature_count++;
if (!glyphset.has (gid)) continue;
auto *matrix = out->serialize_append (c->serializer);
if (unlikely (!matrix)) return_trace (false);
matrix->serialize_subset (c,
this->arrayZ[ligature_count - 1],
this,
class_count,
klass_mapping);
}
return_trace (this->len);
}
};
struct MarkLigPosFormat1 struct MarkLigPosFormat1
{ {
@ -2130,8 +2180,56 @@ 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_gsub ();
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)
;
auto new_mark_coverage =
+ mark_iter
| hb_map_retains_sorting (hb_first)
| hb_map_retains_sorting (glyph_map)
;
if (!out->markCoverage.serialize (c->serializer, out)
.serialize (c->serializer, new_mark_coverage))
return_trace (false); return_trace (false);
out->markArray.serialize (c->serializer, out)
.serialize (c->serializer,
&klass_mapping,
c->plan->layout_variation_idx_map,
&(this+markArray),
+ mark_iter
| hb_map (hb_second));
auto new_ligature_coverage =
+ hb_iter (this + ligatureCoverage)
| hb_filter (glyphset)
| hb_map_retains_sorting (glyph_map)
;
if (!out->ligatureCoverage.serialize (c->serializer, out)
.serialize (c->serializer, new_ligature_coverage))
return_trace (false);
out->ligatureArray.serialize_subset (c, ligatureArray, this,
hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
return_trace (true);
} }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
@ -2164,6 +2262,7 @@ struct MarkLigPosFormat1
DEFINE_SIZE_STATIC (12); DEFINE_SIZE_STATIC (12);
}; };
struct MarkLigPos struct MarkLigPos
{ {
template <typename context_t, typename ...Ts> template <typename context_t, typename ...Ts>

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.gpos8.amiri \ expected/layout.gpos8.amiri \

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.gpos8.amiri.tests \ tests/layout.gpos8.amiri.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
*

View File

@ -9,6 +9,7 @@ tests = [
'layout.gpos2', 'layout.gpos2',
'layout.gpos3', 'layout.gpos3',
'layout.gpos4', 'layout.gpos4',
'layout.gpos5',
'layout.gpos6', 'layout.gpos6',
'layout.gpos8', 'layout.gpos8',
'layout.gpos8.amiri', 'layout.gpos8.amiri',