[subset] subset MATH table
This commit is contained in:
parent
c2cc566c9d
commit
ca7b9daef0
|
@ -346,6 +346,43 @@ struct
|
|||
}
|
||||
HB_FUNCOBJ (subset_record_array);
|
||||
|
||||
|
||||
template<typename OutputArray>
|
||||
struct serialize_math_record_array_t
|
||||
{
|
||||
serialize_math_record_array_t (hb_serialize_context_t *serialize_context_,
|
||||
OutputArray& out_,
|
||||
const void *base_) : serialize_context (serialize_context_),
|
||||
out (out_), base (base_) {}
|
||||
|
||||
template <typename T>
|
||||
bool operator () (T&& record)
|
||||
{
|
||||
if (!serialize_context->copy (record, base)) return false;
|
||||
out.len++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_serialize_context_t *serialize_context;
|
||||
OutputArray &out;
|
||||
const void *base;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper to serialize an array of MATH records.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
template<typename OutputArray>
|
||||
serialize_math_record_array_t<OutputArray>
|
||||
operator () (hb_serialize_context_t *serialize_context, OutputArray& out,
|
||||
const void *base) const
|
||||
{ return serialize_math_record_array_t<OutputArray> (serialize_context, out, base); }
|
||||
|
||||
}
|
||||
HB_FUNCOBJ (serialize_math_record_array);
|
||||
|
||||
/*
|
||||
*
|
||||
* OpenType Layout Common Table Formats
|
||||
|
|
|
@ -41,6 +41,16 @@ struct MathValueRecord
|
|||
hb_position_t get_y_value (hb_font_t *font, const void *base) const
|
||||
{ return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); }
|
||||
|
||||
MathValueRecord* copy (hb_serialize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *out = c->embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
out->deviceTable.serialize_copy (c, deviceTable, base, 0, hb_serialize_context_t::Head);
|
||||
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -59,6 +69,29 @@ struct MathValueRecord
|
|||
|
||||
struct MathConstants
|
||||
{
|
||||
MathConstants* copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *out = c->start_embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
|
||||
HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
|
||||
if (unlikely (!p)) return_trace (nullptr);
|
||||
memcpy (p, percentScaleDown, HBINT16::static_size * 2);
|
||||
|
||||
HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2);
|
||||
if (unlikely (!m)) return_trace (nullptr);
|
||||
memcpy (m, minHeight, HBUINT16::static_size * 2);
|
||||
|
||||
unsigned count = ARRAY_LENGTH (mathValueRecords);
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
if (!c->copy (mathValueRecords[i], this))
|
||||
return_trace (nullptr);
|
||||
|
||||
if (!c->embed (radicalDegreeBottomRaisePercent)) return_trace (nullptr);
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
bool sanitize_math_value_records (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -165,6 +198,28 @@ struct MathConstants
|
|||
|
||||
struct MathItalicsCorrectionInfo
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
|
||||
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);
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ hb_zip (this+coverage, italicsCorrection)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_filter (serialize_math_record_array (c->serializer, out->italicsCorrection, this), hb_second)
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -196,6 +251,28 @@ struct MathItalicsCorrectionInfo
|
|||
|
||||
struct MathTopAccentAttachment
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
|
||||
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);
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ hb_zip (this+topAccentCoverage, topAccentAttachment)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_filter (serialize_math_record_array (c->serializer, out->topAccentAttachment, this), hb_second)
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
out->topAccentCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -229,6 +306,22 @@ struct MathTopAccentAttachment
|
|||
|
||||
struct MathKern
|
||||
{
|
||||
MathKern* copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *out = c->start_embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
|
||||
if (unlikely (!c->embed (heightCount))) return_trace (nullptr);
|
||||
|
||||
unsigned count = 2 * heightCount + 1;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
if (!c->copy (mathValueRecordsZ.arrayZ[i], this))
|
||||
return_trace (nullptr);
|
||||
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
bool sanitize_math_value_records (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -295,6 +388,19 @@ struct MathKern
|
|||
|
||||
struct MathKernInfoRecord
|
||||
{
|
||||
MathKernInfoRecord* copy (hb_serialize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *out = c->embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
|
||||
unsigned count = ARRAY_LENGTH (mathKern);
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
out->mathKern[i].serialize_copy (c, mathKern[i], base, 0, hb_serialize_context_t::Head);
|
||||
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -328,6 +434,28 @@ struct MathKernInfoRecord
|
|||
|
||||
struct MathKernInfo
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
|
||||
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);
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ hb_zip (this+mathKernCoverage, mathKernInfoRecords)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_filter (serialize_math_record_array (c->serializer, out->mathKernInfoRecords, this), hb_second)
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
out->mathKernCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -365,6 +493,30 @@ struct MathKernInfo
|
|||
|
||||
struct MathGlyphInfo
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
out->mathItalicsCorrectionInfo.serialize_subset (c, mathItalicsCorrectionInfo, this);
|
||||
out->mathTopAccentAttachment.serialize_subset (c, mathTopAccentAttachment, this);
|
||||
|
||||
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
auto it =
|
||||
+ hb_iter (this+extendedShapeCoverage)
|
||||
| hb_filter (glyphset)
|
||||
| hb_map_retains_sorting (glyph_map)
|
||||
;
|
||||
|
||||
out->extendedShapeCoverage.serialize_serialize (c->serializer, it);
|
||||
|
||||
out->mathKernInfo.serialize_subset (c, mathKernInfo, this);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -420,6 +572,16 @@ struct MathGlyphVariantRecord
|
|||
{
|
||||
friend struct MathGlyphConstruction;
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
const hb_map_t& glyph_map = *c->plan->glyph_map;
|
||||
return_trace (c->serializer->check_assign (out->variantGlyph, glyph_map.get (variantGlyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -453,6 +615,16 @@ struct PartFlags : HBUINT16
|
|||
|
||||
struct MathGlyphPartRecord
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
const hb_map_t& glyph_map = *c->plan->glyph_map;
|
||||
return_trace (c->serializer->check_assign (out->glyph, glyph_map.get (glyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -503,6 +675,20 @@ struct MathGlyphPartRecord
|
|||
|
||||
struct MathGlyphAssembly
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
if (!c->serializer->copy (italicsCorrection, this)) return_trace (false);
|
||||
if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false);
|
||||
|
||||
for (const auto& record : partRecords.iter ())
|
||||
if (!record.subset (c)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -555,6 +741,22 @@ struct MathGlyphAssembly
|
|||
|
||||
struct MathGlyphConstruction
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
out->glyphAssembly.serialize_subset (c, glyphAssembly, this);
|
||||
|
||||
if (!c->serializer->check_assign (out->mathGlyphVariantRecord.len, mathGlyphVariantRecord.len, HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
for (const auto& record : mathGlyphVariantRecord.iter ())
|
||||
if (!record.subset (c)) return_trace (false);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -630,6 +832,60 @@ struct MathVariants
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
void collect_coverage_and_indices (hb_sorted_vector_t<hb_codepoint_t>& new_coverage,
|
||||
const Offset16To<Coverage>& coverage,
|
||||
unsigned i,
|
||||
hb_set_t& indices,
|
||||
const hb_set_t& glyphset,
|
||||
const hb_map_t& glyph_map) const
|
||||
{
|
||||
for (const auto _ : (this+coverage).iter ())
|
||||
{
|
||||
if (glyphset.has (_))
|
||||
{
|
||||
unsigned new_gid = glyph_map.get (_);
|
||||
new_coverage.push (new_gid);
|
||||
indices.add (i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
|
||||
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);
|
||||
if (!c->serializer->check_assign (out->minConnectorOverlap, minConnectorOverlap, HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_vert_coverage;
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_hori_coverage;
|
||||
hb_set_t indices;
|
||||
collect_coverage_and_indices (new_vert_coverage, vertGlyphCoverage, 0, indices, glyphset, glyph_map);
|
||||
collect_coverage_and_indices (new_hori_coverage, horizGlyphCoverage, vertGlyphCount, indices, glyphset, glyph_map);
|
||||
|
||||
if (!c->serializer->check_assign (out->vertGlyphCount, new_vert_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
if (!c->serializer->check_assign (out->horizGlyphCount, new_hori_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
|
||||
for (unsigned i : indices.iter ())
|
||||
{
|
||||
auto *o = c->serializer->embed (glyphConstruction[i]);
|
||||
if (!o) return_trace (false);
|
||||
o->serialize_subset (c, glyphConstruction[i], this);
|
||||
}
|
||||
|
||||
out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ());
|
||||
out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ());
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize_offsets (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -747,6 +1003,18 @@ struct MATH
|
|||
}
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
out->mathConstants.serialize_copy (c->serializer, mathConstants, this, 0, hb_serialize_context_t::Head);
|
||||
out->mathGlyphInfo.serialize_subset (c, mathGlyphInfo, this);
|
||||
out->mathVariants.serialize_subset (c, mathVariants, this);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "hb-ot-color-colrv1-closure.hh"
|
||||
#include "hb-ot-var-fvar-table.hh"
|
||||
#include "hb-ot-stat-table.hh"
|
||||
#include "hb-ot-math-table.hh"
|
||||
|
||||
|
||||
typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
|
||||
|
@ -221,6 +222,17 @@ _cmap_closure (hb_face_t *face,
|
|||
cmap.fini ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
_math_closure (hb_face_t *face,
|
||||
hb_set_t *glyphset)
|
||||
{
|
||||
hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face);
|
||||
if (math->has_data ())
|
||||
math->closure_glyphs (glyphset);
|
||||
math.destroy ();
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
_remove_invalid_gids (hb_set_t *glyphs,
|
||||
unsigned int num_glyphs)
|
||||
|
@ -334,8 +346,12 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
|||
#endif
|
||||
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
|
||||
|
||||
hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub);
|
||||
_math_closure (plan->source, plan->_glyphset_mathed);
|
||||
_remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ());
|
||||
|
||||
// Collect all glyphs referenced by COLRv0
|
||||
hb_set_t* cur_glyphset = plan->_glyphset_gsub;
|
||||
hb_set_t* cur_glyphset = plan->_glyphset_mathed;
|
||||
hb_set_t glyphset_colrv0;
|
||||
if (colr.is_valid ())
|
||||
{
|
||||
|
@ -468,6 +484,7 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
|
||||
plan->_glyphset = hb_set_create ();
|
||||
plan->_glyphset_gsub = hb_set_create ();
|
||||
plan->_glyphset_mathed = hb_set_create ();
|
||||
plan->codepoint_to_glyph = hb_map_create ();
|
||||
plan->glyph_map = hb_map_create ();
|
||||
plan->reverse_glyph_map = hb_map_create ();
|
||||
|
@ -535,6 +552,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
|||
hb_map_destroy (plan->reverse_glyph_map);
|
||||
hb_set_destroy (plan->_glyphset);
|
||||
hb_set_destroy (plan->_glyphset_gsub);
|
||||
hb_set_destroy (plan->_glyphset_mathed);
|
||||
hb_map_destroy (plan->gsub_lookups);
|
||||
hb_map_destroy (plan->gpos_lookups);
|
||||
hb_map_destroy (plan->gsub_features);
|
||||
|
|
|
@ -77,6 +77,7 @@ struct hb_subset_plan_t
|
|||
unsigned int _num_output_glyphs;
|
||||
hb_set_t *_glyphset;
|
||||
hb_set_t *_glyphset_gsub;
|
||||
hb_set_t *_glyphset_mathed;
|
||||
|
||||
//active lookups we'd like to retain
|
||||
hb_map_t *gsub_lookups;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "hb-ot-layout-gpos-table.hh"
|
||||
#include "hb-ot-var-gvar-table.hh"
|
||||
#include "hb-ot-var-hvar-table.hh"
|
||||
#include "hb-ot-math-table.hh"
|
||||
#include "hb-repacker.hh"
|
||||
|
||||
/**
|
||||
|
@ -305,6 +306,7 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag)
|
|||
case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan);
|
||||
case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan);
|
||||
case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
|
||||
case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan);
|
||||
|
||||
#ifndef HB_NO_SUBSET_CFF
|
||||
case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan);
|
||||
|
|
|
@ -44,6 +44,7 @@ EXTRA_DIST += \
|
|||
expected/cbdt \
|
||||
expected/variable \
|
||||
expected/glyph_names \
|
||||
expected/math \
|
||||
fonts \
|
||||
profiles \
|
||||
$(NULL)
|
||||
|
|
|
@ -36,6 +36,7 @@ TESTS = \
|
|||
tests/sbix.tests \
|
||||
tests/variable.tests \
|
||||
tests/glyph_names.tests \
|
||||
tests/math.tests \
|
||||
$(NULL)
|
||||
|
||||
# TODO: re-enable once colrv1 subsetting is stabilized.
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,12 @@
|
|||
FONTS:
|
||||
STIXTwoMath-Regular.ttf
|
||||
|
||||
PROFILES:
|
||||
default.txt
|
||||
retain-gids.txt
|
||||
glyph-names.txt
|
||||
notdef-outline.txt
|
||||
|
||||
SUBSETS:
|
||||
U+2f,U+7c,U+305
|
||||
*
|
|
@ -32,6 +32,7 @@ tests = [
|
|||
'cmap14',
|
||||
'sbix',
|
||||
'colr',
|
||||
'math',
|
||||
# TODO: re-enable once colrv1 subsetting is stabilized.
|
||||
# 'colrv1.notoemoji',
|
||||
# 'colrv1',
|
||||
|
|
Loading…
Reference in New Issue