fixed inclusion of excluded Private & local Subrs
It was bloating a multi-FD subset font unnecessarily defined a wrapper struct FDMap for fdmap
This commit is contained in:
parent
64c5412264
commit
a97ed342d1
|
@ -700,6 +700,28 @@ struct TableInfo
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* font dict index remap table from fullset FDArray to subset FDArray.
|
||||||
|
* set to HB_SET_VALUE_INVALID if excluded from subset */
|
||||||
|
struct FDMap : hb_vector_t<hb_codepoint_t>
|
||||||
|
{
|
||||||
|
inline void init (void)
|
||||||
|
{ hb_vector_t<hb_codepoint_t>::init (); }
|
||||||
|
|
||||||
|
inline void fini (void)
|
||||||
|
{ hb_vector_t<hb_codepoint_t>::fini (); }
|
||||||
|
|
||||||
|
inline bool fullset (void) const
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < len; i++)
|
||||||
|
if ((*this)[i] == HB_SET_VALUE_INVALID)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool excludes (hb_codepoint_t fd) const
|
||||||
|
{ return (fd < len) && ((*this)[fd] == HB_SET_VALUE_INVALID); }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename COUNT>
|
template <typename COUNT>
|
||||||
struct FDArray : IndexOf<COUNT, FontDict>
|
struct FDArray : IndexOf<COUNT, FontDict>
|
||||||
{
|
{
|
||||||
|
@ -708,7 +730,7 @@ struct FDArray : IndexOf<COUNT, FontDict>
|
||||||
unsigned int offSize_,
|
unsigned int offSize_,
|
||||||
const hb_vector_t<DICTVAL> &fontDicts,
|
const hb_vector_t<DICTVAL> &fontDicts,
|
||||||
unsigned int fdCount,
|
unsigned int fdCount,
|
||||||
const hb_vector_t<hb_codepoint_t> &fdmap,
|
const FDMap &fdmap,
|
||||||
OP_SERIALIZER& opszr,
|
OP_SERIALIZER& opszr,
|
||||||
const hb_vector_t<TableInfo> &privateInfos)
|
const hb_vector_t<TableInfo> &privateInfos)
|
||||||
{
|
{
|
||||||
|
@ -723,7 +745,7 @@ struct FDArray : IndexOf<COUNT, FontDict>
|
||||||
unsigned int offset = 1;
|
unsigned int offset = 1;
|
||||||
unsigned int fid = 0;
|
unsigned int fid = 0;
|
||||||
for (unsigned i = 0; i < fontDicts.len; i++)
|
for (unsigned i = 0; i < fontDicts.len; i++)
|
||||||
if (!fdmap.len || fdmap[i] != HB_SET_VALUE_INVALID)
|
if (!fdmap.excludes (i))
|
||||||
{
|
{
|
||||||
IndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
|
IndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
|
||||||
offset += FontDict::calculate_serialized_size (fontDicts[i], opszr);
|
offset += FontDict::calculate_serialized_size (fontDicts[i], opszr);
|
||||||
|
@ -732,10 +754,10 @@ struct FDArray : IndexOf<COUNT, FontDict>
|
||||||
|
|
||||||
/* serialize font dicts */
|
/* serialize font dicts */
|
||||||
for (unsigned int i = 0; i < fontDicts.len; i++)
|
for (unsigned int i = 0; i < fontDicts.len; i++)
|
||||||
if (fdmap[i] != HB_SET_VALUE_INVALID)
|
if (!fdmap.excludes (i))
|
||||||
{
|
{
|
||||||
FontDict *dict = c->start_embed<FontDict> ();
|
FontDict *dict = c->start_embed<FontDict> ();
|
||||||
if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[i])))
|
if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap[i]])))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -746,12 +768,12 @@ struct FDArray : IndexOf<COUNT, FontDict>
|
||||||
inline static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
|
inline static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
|
||||||
const hb_vector_t<DICTVAL> &fontDicts,
|
const hb_vector_t<DICTVAL> &fontDicts,
|
||||||
unsigned int fdCount,
|
unsigned int fdCount,
|
||||||
const hb_vector_t<hb_codepoint_t> &fdmap,
|
const FDMap &fdmap,
|
||||||
OP_SERIALIZER& opszr)
|
OP_SERIALIZER& opszr)
|
||||||
{
|
{
|
||||||
unsigned int dictsSize = 0;
|
unsigned int dictsSize = 0;
|
||||||
for (unsigned int i = 0; i < fontDicts.len; i++)
|
for (unsigned int i = 0; i < fontDicts.len; i++)
|
||||||
if (!fdmap.len || fdmap[i] != HB_SET_VALUE_INVALID)
|
if (!fdmap.excludes (i))
|
||||||
dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
|
dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
|
||||||
|
|
||||||
offSize_ = calcOffSize (dictsSize + 1);
|
offSize_ = calcOffSize (dictsSize + 1);
|
||||||
|
|
|
@ -46,7 +46,7 @@ hb_plan_subset_cff_fdselect (const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||||
unsigned int &subst_fdselect_size /* OUT */,
|
unsigned int &subst_fdselect_size /* OUT */,
|
||||||
unsigned int &subst_fdselect_format /* OUT */,
|
unsigned int &subst_fdselect_format /* OUT */,
|
||||||
hb_vector_t<hb_codepoint_t> &subst_first_glyphs /* OUT */,
|
hb_vector_t<hb_codepoint_t> &subst_first_glyphs /* OUT */,
|
||||||
hb_vector_t<hb_codepoint_t> &fdmap /* OUT */)
|
FDMap &fdmap /* OUT */)
|
||||||
{
|
{
|
||||||
subset_fd_count = 0;
|
subset_fd_count = 0;
|
||||||
subst_fdselect_size = 0;
|
subst_fdselect_size = 0;
|
||||||
|
@ -131,7 +131,7 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c,
|
||||||
const FDSelect &src,
|
const FDSelect &src,
|
||||||
unsigned int size,
|
unsigned int size,
|
||||||
const hb_vector_t<hb_codepoint_t> &first_glyphs,
|
const hb_vector_t<hb_codepoint_t> &first_glyphs,
|
||||||
const hb_vector_t<hb_codepoint_t> &fdmap)
|
const FDMap &fdmap)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
|
FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
|
||||||
|
@ -159,7 +159,7 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c,
|
||||||
unsigned int fdselect_format,
|
unsigned int fdselect_format,
|
||||||
unsigned int size,
|
unsigned int size,
|
||||||
const hb_vector_t<hb_codepoint_t> &first_glyphs,
|
const hb_vector_t<hb_codepoint_t> &first_glyphs,
|
||||||
const hb_vector_t<hb_codepoint_t> &fdmap)
|
const FDMap &fdmap)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
FDSelect *p = c->allocate_min<FDSelect> ();
|
FDSelect *p = c->allocate_min<FDSelect> ();
|
||||||
|
|
|
@ -39,7 +39,7 @@ hb_plan_subset_cff_fdselect (const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||||
unsigned int &subst_fdselect_size /* OUT */,
|
unsigned int &subst_fdselect_size /* OUT */,
|
||||||
unsigned int &subst_fdselect_format /* OUT */,
|
unsigned int &subst_fdselect_format /* OUT */,
|
||||||
hb_vector_t<hb_codepoint_t> &subst_first_glyphs /* OUT */,
|
hb_vector_t<hb_codepoint_t> &subst_first_glyphs /* OUT */,
|
||||||
hb_vector_t<hb_codepoint_t> &fdmap /* OUT */);
|
CFF::FDMap &fdmap /* OUT */);
|
||||||
|
|
||||||
HB_INTERNAL bool
|
HB_INTERNAL bool
|
||||||
hb_serialize_cff_fdselect (hb_serialize_context_t *c,
|
hb_serialize_cff_fdselect (hb_serialize_context_t *c,
|
||||||
|
@ -49,6 +49,6 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c,
|
||||||
unsigned int fdselect_format,
|
unsigned int fdselect_format,
|
||||||
unsigned int size,
|
unsigned int size,
|
||||||
const hb_vector_t<hb_codepoint_t> &first_glyphs,
|
const hb_vector_t<hb_codepoint_t> &first_glyphs,
|
||||||
const hb_vector_t<hb_codepoint_t> &fdmap);
|
const CFF::FDMap &fdmap);
|
||||||
|
|
||||||
#endif /* HB_SUBSET_CFF_COMMON_PRIVATE_HH */
|
#endif /* HB_SUBSET_CFF_COMMON_PRIVATE_HH */
|
||||||
|
|
|
@ -291,10 +291,13 @@ struct cff_subset_plan {
|
||||||
offsets.privateDictInfo.offset = final_size;
|
offsets.privateDictInfo.offset = final_size;
|
||||||
for (unsigned int i = 0; i < orig_fdcount; i++)
|
for (unsigned int i = 0; i < orig_fdcount; i++)
|
||||||
{
|
{
|
||||||
CFFPrivateDict_OpSerializer privSzr;
|
if (!fdmap.excludes (i))
|
||||||
TableInfo privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr) };
|
{
|
||||||
privateDictInfos.push (privInfo);
|
CFFPrivateDict_OpSerializer privSzr;
|
||||||
final_size += privInfo.size + acc.privateDicts[i].localSubrs->get_size ();
|
TableInfo privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr) };
|
||||||
|
privateDictInfos.push (privInfo);
|
||||||
|
final_size += privInfo.size + acc.privateDicts[i].localSubrs->get_size ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!acc.is_CID ())
|
if (!acc.is_CID ())
|
||||||
|
@ -317,7 +320,7 @@ struct cff_subset_plan {
|
||||||
|
|
||||||
/* font dict index remap table from fullset FDArray to subset FDArray.
|
/* font dict index remap table from fullset FDArray to subset FDArray.
|
||||||
* set to HB_SET_VALUE_INVALID if excluded from subset */
|
* set to HB_SET_VALUE_INVALID if excluded from subset */
|
||||||
hb_vector_t<hb_codepoint_t> fdmap;
|
FDMap fdmap;
|
||||||
|
|
||||||
hb_vector_t<ByteStr> subset_charstrings;
|
hb_vector_t<ByteStr> subset_charstrings;
|
||||||
hb_vector_t<TableInfo> privateDictInfos;
|
hb_vector_t<TableInfo> privateDictInfos;
|
||||||
|
@ -474,27 +477,30 @@ static inline bool _write_cff (const cff_subset_plan &plan,
|
||||||
assert (plan.offsets.privateDictInfo.offset == c.head - c.start);
|
assert (plan.offsets.privateDictInfo.offset == c.head - c.start);
|
||||||
for (unsigned int i = 0; i < acc.privateDicts.len; i++)
|
for (unsigned int i = 0; i < acc.privateDicts.len; i++)
|
||||||
{
|
{
|
||||||
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
if (!plan.fdmap.excludes (i))
|
||||||
if (unlikely (pd == nullptr)) return false;
|
|
||||||
CFFPrivateDict_OpSerializer privSzr;
|
|
||||||
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
|
||||||
if (unlikely (!pd->serialize (&c, acc.privateDicts[i], privSzr, plan.privateDictInfos[i].size)))
|
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i);
|
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
||||||
return false;
|
if (unlikely (pd == nullptr)) return false;
|
||||||
}
|
CFFPrivateDict_OpSerializer privSzr;
|
||||||
if (acc.privateDicts[i].subrsOffset != 0)
|
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
||||||
{
|
if (unlikely (!pd->serialize (&c, acc.privateDicts[i], privSzr, plan.privateDictInfos[plan.fdmap[i]].size)))
|
||||||
CFFSubrs *subrs = c.start_embed<CFFSubrs> ();
|
|
||||||
if (unlikely (subrs == nullptr) || acc.privateDicts[i].localSubrs == &Null(CFFSubrs))
|
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "CFF subset: local subrs unexpectedly null [%d]", i);
|
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (unlikely (!subrs->serialize (&c, *acc.privateDicts[i].localSubrs)))
|
if (acc.privateDicts[i].subrsOffset != 0)
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF local subrs [%d]", i);
|
CFFSubrs *subrs = c.start_embed<CFFSubrs> ();
|
||||||
return false;
|
if (unlikely (subrs == nullptr) || acc.privateDicts[i].localSubrs == &Null(CFFSubrs))
|
||||||
|
{
|
||||||
|
DEBUG_MSG (SUBSET, nullptr, "CFF subset: local subrs unexpectedly null [%d]", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (unlikely (!subrs->serialize (&c, *acc.privateDicts[i].localSubrs)))
|
||||||
|
{
|
||||||
|
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF local subrs [%d]", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,10 +250,13 @@ struct cff2_subset_plan {
|
||||||
offsets.privateDictsOffset = final_size;
|
offsets.privateDictsOffset = final_size;
|
||||||
for (unsigned int i = 0; i < orig_fdcount; i++)
|
for (unsigned int i = 0; i < orig_fdcount; i++)
|
||||||
{
|
{
|
||||||
CFF2PrivateDict_OpSerializer privSzr;
|
if (!fdmap.excludes (i))
|
||||||
TableInfo privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr) };
|
{
|
||||||
privateDictInfos.push (privInfo);
|
CFF2PrivateDict_OpSerializer privSzr;
|
||||||
final_size += privInfo.size + acc.privateDicts[i].localSubrs->get_size ();
|
TableInfo privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr) };
|
||||||
|
privateDictInfos.push (privInfo);
|
||||||
|
final_size += privInfo.size + acc.privateDicts[i].localSubrs->get_size ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -270,9 +273,7 @@ struct cff2_subset_plan {
|
||||||
unsigned int subst_fdselect_format;
|
unsigned int subst_fdselect_format;
|
||||||
hb_vector_t<hb_codepoint_t> subst_fdselect_first_glyphs;
|
hb_vector_t<hb_codepoint_t> subst_fdselect_first_glyphs;
|
||||||
|
|
||||||
/* font dict index remap table from fullset FDArray to subset FDArray.
|
FDMap fdmap;
|
||||||
* set to HB_SET_VALUE_INVALID if excluded from subset */
|
|
||||||
hb_vector_t<hb_codepoint_t> fdmap;
|
|
||||||
|
|
||||||
hb_vector_t<ByteStr> subset_charstrings;
|
hb_vector_t<ByteStr> subset_charstrings;
|
||||||
hb_vector_t<TableInfo> privateDictInfos;
|
hb_vector_t<TableInfo> privateDictInfos;
|
||||||
|
@ -390,27 +391,30 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
|
||||||
assert (plan.offsets.privateDictsOffset == c.head - c.start);
|
assert (plan.offsets.privateDictsOffset == c.head - c.start);
|
||||||
for (unsigned int i = 0; i < acc.privateDicts.len; i++)
|
for (unsigned int i = 0; i < acc.privateDicts.len; i++)
|
||||||
{
|
{
|
||||||
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
if (!plan.fdmap.excludes (i))
|
||||||
if (unlikely (pd == nullptr)) return false;
|
|
||||||
CFF2PrivateDict_OpSerializer privSzr;
|
|
||||||
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
|
||||||
if (unlikely (!pd->serialize (&c, acc.privateDicts[i], privSzr, plan.privateDictInfos[i].size)))
|
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 Private Dict[%d]", i);
|
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
||||||
return false;
|
if (unlikely (pd == nullptr)) return false;
|
||||||
}
|
CFF2PrivateDict_OpSerializer privSzr;
|
||||||
if (acc.privateDicts[i].subrsOffset != 0)
|
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
||||||
{
|
if (unlikely (!pd->serialize (&c, acc.privateDicts[i], privSzr, plan.privateDictInfos[plan.fdmap[i]].size)))
|
||||||
CFF2Subrs *subrs = c.start_embed<CFF2Subrs> ();
|
|
||||||
if (unlikely (subrs == nullptr) || acc.privateDicts[i].localSubrs == &Null(CFF2Subrs))
|
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "CFF2 subset: local subrs unexpectedly null [%d]", i);
|
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 Private Dict[%d]", i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (unlikely (!subrs->serialize (&c, *acc.privateDicts[i].localSubrs)))
|
if (acc.privateDicts[i].subrsOffset != 0)
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 local subrs [%d]", i);
|
CFF2Subrs *subrs = c.start_embed<CFF2Subrs> ();
|
||||||
return false;
|
if (unlikely (subrs == nullptr) || acc.privateDicts[i].localSubrs == &Null(CFF2Subrs))
|
||||||
|
{
|
||||||
|
DEBUG_MSG (SUBSET, nullptr, "CFF2 subset: local subrs unexpectedly null [%d]", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (unlikely (!subrs->serialize (&c, *acc.privateDicts[i].localSubrs)))
|
||||||
|
{
|
||||||
|
DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 local subrs [%d]", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue