summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh117
1 files changed, 81 insertions, 36 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
index 915b4c45287..81368ee4c54 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
@@ -282,30 +282,35 @@ struct flatten_param_t
bool drop_hints;
};
-template <typename ACC, typename ENV, typename OPSET>
+template <typename ACC, typename ENV, typename OPSET, op_code_t endchar_op=OpCode_Invalid>
struct subr_flattener_t
{
subr_flattener_t (const ACC &acc_,
- const hb_vector_t<hb_codepoint_t> &glyphs_,
- bool drop_hints_) : acc (acc_), glyphs (glyphs_),
- drop_hints (drop_hints_) {}
+ const hb_subset_plan_t *plan_)
+ : acc (acc_), plan (plan_) {}
bool flatten (str_buff_vec_t &flat_charstrings)
{
- if (!flat_charstrings.resize (glyphs.length))
+ if (!flat_charstrings.resize (plan->num_output_glyphs ()))
return false;
- for (unsigned int i = 0; i < glyphs.length; i++)
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
flat_charstrings[i].init ();
- for (unsigned int i = 0; i < glyphs.length; i++)
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
{
- hb_codepoint_t glyph = glyphs[i];
+ hb_codepoint_t glyph;
+ if (!plan->old_gid_for_new_gid (i, &glyph))
+ {
+ /* add an endchar only charstring for a missing glyph if CFF1 */
+ if (endchar_op != OpCode_Invalid) flat_charstrings[i].push (endchar_op);
+ continue;
+ }
const byte_str_t str = (*acc.charStrings)[glyph];
unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
return false;
cs_interpreter_t<ENV, OPSET, flatten_param_t> interp;
interp.env.init (str, acc, fd);
- flatten_param_t param = { flat_charstrings[i], drop_hints };
+ flatten_param_t param = { flat_charstrings[i], plan->drop_hints };
if (unlikely (!interp.interpret (param)))
return false;
}
@@ -313,8 +318,7 @@ struct subr_flattener_t
}
const ACC &acc;
- const hb_vector_t<hb_codepoint_t> &glyphs;
- bool drop_hints;
+ const hb_subset_plan_t *plan;
};
struct subr_closures_t
@@ -611,10 +615,11 @@ struct subr_remap_ts
hb_vector_t<subr_remap_t> local_remaps;
};
-template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typename OPSET>
+template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typename OPSET, op_code_t endchar_op=OpCode_Invalid>
struct subr_subsetter_t
{
- subr_subsetter_t ()
+ subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
+ : acc (acc_), plan (plan_)
{
parsed_charstrings.init ();
parsed_global_subrs.init ();
@@ -644,12 +649,12 @@ struct subr_subsetter_t
* Assumption: a callsubr/callgsubr operator must immediately follow a (biased) subroutine number
* within the same charstring/subroutine, e.g., not split across a charstring and a subroutine.
*/
- bool subset (ACC &acc, const hb_vector_t<hb_codepoint_t> &glyphs, bool drop_hints)
+ bool subset (void)
{
closures.init (acc.fdCount);
remaps.init (acc.fdCount);
- parsed_charstrings.init (glyphs.length);
+ parsed_charstrings.init (plan->num_output_glyphs ());
parsed_global_subrs.init (acc.globalSubrs->count);
parsed_local_subrs.resize (acc.fdCount);
for (unsigned int i = 0; i < acc.fdCount; i++)
@@ -660,9 +665,11 @@ struct subr_subsetter_t
return false;
/* phase 1 & 2 */
- for (unsigned int i = 0; i < glyphs.length; i++)
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
{
- hb_codepoint_t glyph = glyphs[i];
+ hb_codepoint_t glyph;
+ if (!plan->old_gid_for_new_gid (i, &glyph))
+ continue;
const byte_str_t str = (*acc.charStrings)[glyph];
unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
@@ -675,7 +682,7 @@ struct subr_subsetter_t
param.init (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_local_subrs[fd],
closures.global_closure, closures.local_closures[fd],
- drop_hints);
+ plan->drop_hints);
if (unlikely (!interp.interpret (param)))
return false;
@@ -684,19 +691,22 @@ struct subr_subsetter_t
SUBSETTER::finalize_parsed_str (interp.env, param, parsed_charstrings[i]);
}
- if (drop_hints)
+ if (plan->drop_hints)
{
/* mark hint ops and arguments for drop */
- for (unsigned int i = 0; i < glyphs.length; i++)
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
{
- unsigned int fd = acc.fdSelect->get_fd (glyphs[i]);
+ hb_codepoint_t glyph;
+ if (!plan->old_gid_for_new_gid (i, &glyph))
+ continue;
+ unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
return false;
subr_subset_param_t param;
param.init (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_local_subrs[fd],
closures.global_closure, closures.local_closures[fd],
- drop_hints);
+ plan->drop_hints);
drop_hints_param_t drop;
if (drop_hints_in_str (parsed_charstrings[i], param, drop))
@@ -709,16 +719,19 @@ struct subr_subsetter_t
/* after dropping hints recreate closures of actually used subrs */
closures.reset ();
- for (unsigned int i = 0; i < glyphs.length; i++)
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
{
- unsigned int fd = acc.fdSelect->get_fd (glyphs[i]);
+ hb_codepoint_t glyph;
+ if (!plan->old_gid_for_new_gid (i, &glyph))
+ continue;
+ unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
return false;
subr_subset_param_t param;
param.init (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_local_subrs[fd],
closures.global_closure, closures.local_closures[fd],
- drop_hints);
+ plan->drop_hints);
collect_subr_refs_in_str (parsed_charstrings[i], param);
}
}
@@ -728,13 +741,20 @@ struct subr_subsetter_t
return true;
}
- bool encode_charstrings (ACC &acc, const hb_vector_t<hb_codepoint_t> &glyphs, str_buff_vec_t &buffArray) const
+ bool encode_charstrings (str_buff_vec_t &buffArray) const
{
- if (unlikely (!buffArray.resize (glyphs.length)))
+ if (unlikely (!buffArray.resize (plan->num_output_glyphs ())))
return false;
- for (unsigned int i = 0; i < glyphs.length; i++)
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
{
- unsigned int fd = acc.fdSelect->get_fd (glyphs[i]);
+ hb_codepoint_t glyph;
+ if (!plan->old_gid_for_new_gid (i, &glyph))
+ {
+ /* add an endchar only charstring for a missing glyph if CFF1 */
+ if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op);
+ continue;
+ }
+ unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
return false;
if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i])))
@@ -777,10 +797,12 @@ struct subr_subsetter_t
drop_hints_param_t ()
: seen_moveto (false),
ends_in_hint (false),
+ all_dropped (false),
vsindex_dropped (false) {}
bool seen_moveto;
bool ends_in_hint;
+ bool all_dropped;
bool vsindex_dropped;
};
@@ -791,7 +813,7 @@ struct subr_subsetter_t
drop.ends_in_hint = false;
bool has_hint = drop_hints_in_str (subrs[subr_num], param, drop);
- /* if this subr ends with a stem hint (i.e., not a number a potential argument for moveto),
+ /* if this subr ends with a stem hint (i.e., not a number; potential argument for moveto),
* then this entire subroutine must be a hint. drop its call. */
if (drop.ends_in_hint)
{
@@ -801,6 +823,10 @@ struct subr_subsetter_t
if (!str.at_end (pos))
drop.ends_in_hint = false;
}
+ else if (drop.all_dropped)
+ {
+ str.values[pos].set_drop ();
+ }
return has_hint;
}
@@ -819,7 +845,6 @@ struct subr_subsetter_t
has_hint = drop_hints_in_subr (str, pos,
*param.parsed_local_subrs, str.values[pos].subr_num,
param, drop);
-
break;
case OpCode_callgsubr:
@@ -876,6 +901,23 @@ struct subr_subsetter_t
}
}
+ /* Raise all_dropped flag if all operators except return are dropped from a subr.
+ * It may happen even after seeing the first moveto if a subr contains
+ * only (usually one) hintmask operator, then calls to this subr can be dropped.
+ */
+ drop.all_dropped = true;
+ for (unsigned int pos = 0; pos < str.values.length; pos++)
+ {
+ parsed_cs_op_t &csop = str.values[pos];
+ if (csop.op == OpCode_return)
+ break;
+ if (!csop.for_drop ())
+ {
+ drop.all_dropped = false;
+ break;
+ }
+ }
+
return seen_hint;
}
@@ -954,13 +996,16 @@ struct subr_subsetter_t
}
protected:
- subr_closures_t closures;
+ const ACC &acc;
+ const hb_subset_plan_t *plan;
+
+ subr_closures_t closures;
- parsed_cs_str_vec_t parsed_charstrings;
- parsed_cs_str_vec_t parsed_global_subrs;
+ parsed_cs_str_vec_t parsed_charstrings;
+ parsed_cs_str_vec_t parsed_global_subrs;
hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
- subr_remap_ts remaps;
+ subr_remap_ts remaps;
private:
typedef typename SUBRS::count_type subr_count_type;
@@ -969,7 +1014,7 @@ struct subr_subsetter_t
} /* namespace CFF */
HB_INTERNAL bool
-hb_plan_subset_cff_fdselect (const hb_vector_t<hb_codepoint_t> &glyphs,
+hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
unsigned int fdCount,
const CFF::FDSelect &src, /* IN */
unsigned int &subset_fd_count /* OUT */,