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)
/* 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. */
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
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
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
} 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
{
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)
{