[subset] Implement subsetting of SingleSubst
This commit is contained in:
parent
3f00d0b0df
commit
0d160d5ff5
|
@ -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)
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue