[subset] Implement subsetting of SingleSubst

This commit is contained in:
Behdad Esfahbod 2018-09-03 20:50:11 -07:00
parent 3f00d0b0df
commit 0d160d5ff5
4 changed files with 81 additions and 25 deletions

View File

@ -452,6 +452,8 @@ struct hb_serialize_context_t
this->debug_depth = 0; 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. */ /* To be called around main operation. */
template <typename Type> template <typename Type>
inline Type *start_serialize (void) inline Type *start_serialize (void)

View File

@ -51,27 +51,40 @@ static inline Type const & Null (void) {
/* Specializaitons for arbitrary-content Null objects expressed in bytes. */ /* Specializaitons for arbitrary-content Null objects expressed in bytes. */
#define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \
} /* Close namespace. */ \ } /* Close namespace. */ \
extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \
template <> \ template <> \
/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ /*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \ return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \
} \ } \
namespace Namespace { \ namespace Namespace { \
static_assert (true, "Just so we take semicolon after.") static_assert (true, "Just so we take semicolon after.")
#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ #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. */ /* Specializaitons for arbitrary-content Null objects expressed as struct initializer. */
#define DECLARE_NULL_INSTANCE(Type) \ #define DECLARE_NULL_INSTANCE(Type) \
extern HB_INTERNAL const Type _hb_Null_##Type; \ extern HB_INTERNAL const Type _hb_Null_##Type; \
template <> \ template <> \
/*static*/ inline const Type& Null<Type> (void) { \ /*static*/ inline const Type& Null<Type> (void) { \
return _hb_Null_##Type; \ return _hb_Null_##Type; \
} \ } \
static_assert (true, "Just so we take semicolon after.") static_assert (true, "Just so we take semicolon after.")
#define DEFINE_NULL_INSTANCE(Type) \ #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<Type> (void)
#define DECLARE_NULL_NAMSPACE_DISALLOW(Namespace, Type) \
} /* Close namespace. */ \
template <> \
/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
extern void *_hb_undefined; \
return *reinterpret_cast<const Namespace::Type *> (_hb_undefined); \
} \
namespace Namespace { \
static_assert (true, "Just so we take semicolon after.")
/* Global writable pool. Enlarge as necessary. */ /* Global writable pool. Enlarge as necessary. */

View File

@ -35,6 +35,11 @@
namespace OT { namespace OT {
static inline void SingleSubst_serialize (hb_serialize_context_t *c,
Supplier<GlyphID> &glyphs,
Supplier<GlyphID> &substitutes,
unsigned int num_glyphs);
struct SingleSubstFormat1 struct SingleSubstFormat1
{ {
inline bool intersects (const hb_set_t *glyphs) const inline bool intersects (const hb_set_t *glyphs) const
@ -104,19 +109,26 @@ struct SingleSubstFormat1
inline bool subset (hb_subset_context_t *c) const inline bool subset (hb_subset_context_t *c) const
{ {
return false;
TRACE_SUBSET (this); TRACE_SUBSET (this);
hb_auto_t<hb_vector_t<hb_codepoint_t>> from; hb_auto_t<hb_vector_t<GlyphID>> from;
hb_auto_t<hb_vector_t<hb_codepoint_t>> to; hb_auto_t<hb_vector_t<GlyphID>> to;
hb_codepoint_t delta = deltaGlyphID; hb_codepoint_t delta = deltaGlyphID;
for (hb_auto_t<Coverage::Iter> iter (this+coverage); iter.more (); iter.next ()) for (hb_auto_t<Coverage::Iter> iter (this+coverage); iter.more (); iter.next ())
{ {
//if (!c->plan->glyphs->has (iter.get_glyph ())) if (!c->plan->glyphset->has (iter.get_glyph ()))
// continue; continue;
from.push (iter.get_glyph ()); from.push ()->set (iter.get_glyph ());
to.push ((iter.get_glyph () + delta) & 0xFFFF); to.push ()->set ((iter.get_glyph () + delta) & 0xFFFF);
} }
return_trace (false); c->serializer->err (from.in_error () || to.in_error ());
Supplier<GlyphID> from_supplier (&from);
Supplier<GlyphID> 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 inline bool sanitize (hb_sanitize_context_t *c) const
@ -204,8 +216,24 @@ struct SingleSubstFormat2
inline bool subset (hb_subset_context_t *c) const inline bool subset (hb_subset_context_t *c) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
// TODO(subset) hb_auto_t<hb_vector_t<GlyphID>> from;
return_trace (false); hb_auto_t<hb_vector_t<GlyphID>> to;
for (hb_auto_t<Coverage::Iter> 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<GlyphID> from_supplier (&from);
Supplier<GlyphID> 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 inline bool sanitize (hb_sanitize_context_t *c) const
@ -275,6 +303,17 @@ struct SingleSubst
} u; } u;
}; };
static inline void
SingleSubst_serialize (hb_serialize_context_t *c,
Supplier<GlyphID> &glyphs,
Supplier<GlyphID> &substitutes,
unsigned int num_glyphs)
{
c->start_embed<SingleSubst> ()->serialize (c,
glyphs,
substitutes,
num_glyphs);
}
struct Sequence struct Sequence
{ {

View File

@ -72,6 +72,8 @@ struct hb_vector_t
return p; return p;
} }
inline bool in_error (void) const { return allocated == 0; }
/* Allocate for size but don't adjust len. */ /* Allocate for size but don't adjust len. */
inline bool alloc (unsigned int size) inline bool alloc (unsigned int size)
{ {