From 0d160d5ff5158fd4190201becd652c8f28ef4430 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 3 Sep 2018 20:50:11 -0700 Subject: [PATCH] [subset] Implement subsetting of SingleSubst --- src/hb-machinery.hh | 2 ++ src/hb-null.hh | 43 +++++++++++++++++++----------- src/hb-ot-layout-gsub-table.hh | 59 +++++++++++++++++++++++++++++++++++------- src/hb-vector.hh | 2 ++ 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 280a5a6..6899416 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -452,6 +452,8 @@ struct hb_serialize_context_t this->debug_depth = 0; } + inline bool err (bool e) { return this->ran_out_of_room = this->ran_out_of_room || e; } + /* To be called around main operation. */ template inline Type *start_serialize (void) diff --git a/src/hb-null.hh b/src/hb-null.hh index 19886a5..7128f0a 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -51,27 +51,40 @@ static inline Type const & Null (void) { /* Specializaitons for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ -} /* Close namespace. */ \ -extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ -template <> \ -/*static*/ inline const Namespace::Type& Null (void) { \ - return *reinterpret_cast (_hb_Null_##Namespace##_##Type); \ -} \ -namespace Namespace { \ -static_assert (true, "Just so we take semicolon after.") + } /* Close namespace. */ \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ + template <> \ + /*static*/ inline const Namespace::Type& Null (void) { \ + return *reinterpret_cast (_hb_Null_##Namespace##_##Type); \ + } \ + namespace Namespace { \ + static_assert (true, "Just so we take semicolon after.") #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ -const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] + const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] /* Specializaitons for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ -extern HB_INTERNAL const Type _hb_Null_##Type; \ -template <> \ -/*static*/ inline const Type& Null (void) { \ - return _hb_Null_##Type; \ -} \ + extern HB_INTERNAL const Type _hb_Null_##Type; \ + template <> \ + /*static*/ inline const Type& Null (void) { \ + return _hb_Null_##Type; \ + } \ static_assert (true, "Just so we take semicolon after.") #define DEFINE_NULL_INSTANCE(Type) \ -const Type _hb_Null_##Type + const Type _hb_Null_##Type + +/* Specializaiton to disallow Null objects. */ +#define DECLARE_NULL_DISALLOW(Type) \ + template <> inline const Type& Null (void) +#define DECLARE_NULL_NAMSPACE_DISALLOW(Namespace, Type) \ + } /* Close namespace. */ \ + template <> \ + /*static*/ inline const Namespace::Type& Null (void) { \ + extern void *_hb_undefined; \ + return *reinterpret_cast (_hb_undefined); \ + } \ + namespace Namespace { \ + static_assert (true, "Just so we take semicolon after.") /* Global writable pool. Enlarge as necessary. */ diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index c0f7081..5763361 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -35,6 +35,11 @@ namespace OT { +static inline void SingleSubst_serialize (hb_serialize_context_t *c, + Supplier &glyphs, + Supplier &substitutes, + unsigned int num_glyphs); + struct SingleSubstFormat1 { inline bool intersects (const hb_set_t *glyphs) const @@ -104,19 +109,26 @@ struct SingleSubstFormat1 inline bool subset (hb_subset_context_t *c) const { - return false; TRACE_SUBSET (this); - hb_auto_t> from; - hb_auto_t> to; + hb_auto_t> from; + hb_auto_t> to; hb_codepoint_t delta = deltaGlyphID; for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) { - //if (!c->plan->glyphs->has (iter.get_glyph ())) - // continue; - from.push (iter.get_glyph ()); - to.push ((iter.get_glyph () + delta) & 0xFFFF); + if (!c->plan->glyphset->has (iter.get_glyph ())) + continue; + from.push ()->set (iter.get_glyph ()); + to.push ()->set ((iter.get_glyph () + delta) & 0xFFFF); } - return_trace (false); + c->serializer->err (from.in_error () || to.in_error ()); + + Supplier from_supplier (&from); + Supplier to_supplier (&to); + SingleSubst_serialize (c->serializer, + from_supplier, + to_supplier, + from.len); + return_trace (from.len); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -204,8 +216,24 @@ struct SingleSubstFormat2 inline bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + hb_auto_t> from; + hb_auto_t> to; + for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + { + if (!c->plan->glyphset->has (iter.get_glyph ())) + continue; + from.push ()->set (iter.get_glyph ()); + to.push ()->set (substitute[iter.get_coverage ()]); + } + c->serializer->err (from.in_error () || to.in_error ()); + + Supplier from_supplier (&from); + Supplier to_supplier (&to); + SingleSubst_serialize (c->serializer, + from_supplier, + to_supplier, + from.len); + return_trace (from.len); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -275,6 +303,17 @@ struct SingleSubst } u; }; +static inline void +SingleSubst_serialize (hb_serialize_context_t *c, + Supplier &glyphs, + Supplier &substitutes, + unsigned int num_glyphs) +{ + c->start_embed ()->serialize (c, + glyphs, + substitutes, + num_glyphs); +} struct Sequence { diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 3134174..da548cb 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -72,6 +72,8 @@ struct hb_vector_t return p; } + inline bool in_error (void) const { return allocated == 0; } + /* Allocate for size but don't adjust len. */ inline bool alloc (unsigned int size) { -- 2.7.4