[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;
}
inline bool err (bool e) { return this->ran_out_of_room = this->ran_out_of_room || e; }
/* To be called around main operation. */
template <typename Type>
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. */
#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<Namespace::Type> (void) { \
return *reinterpret_cast<const Namespace::Type *> (_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<Namespace::Type> (void) { \
return *reinterpret_cast<const Namespace::Type *> (_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<Type> (void) { \
return _hb_Null_##Type; \
} \
extern HB_INTERNAL const Type _hb_Null_##Type; \
template <> \
/*static*/ inline const Type& Null<Type> (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<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. */

View File

@ -35,6 +35,11 @@
namespace OT {
static inline void SingleSubst_serialize (hb_serialize_context_t *c,
Supplier<GlyphID> &glyphs,
Supplier<GlyphID> &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<hb_vector_t<hb_codepoint_t>> from;
hb_auto_t<hb_vector_t<hb_codepoint_t>> to;
hb_auto_t<hb_vector_t<GlyphID>> from;
hb_auto_t<hb_vector_t<GlyphID>> to;
hb_codepoint_t delta = deltaGlyphID;
for (hb_auto_t<Coverage::Iter> 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<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
@ -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<hb_vector_t<GlyphID>> from;
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
@ -275,6 +303,17 @@ struct SingleSubst
} 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
{

View File

@ -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)
{