[OT] Port Arabic fallback shaping to synthetic GSUB
All of init/medi/fina/isol and rlig implemented.
Let there be dragons... ⻯
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index c273a97..7106a2e 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -342,38 +342,52 @@
struct hb_serialize_context_t
{
- inline void init (void *start, unsigned int size)
+ inline hb_serialize_context_t (void *start, unsigned int size)
{
this->start = (char *) start;
this->end = this->start + size;
- }
- inline void start_processing (void)
- {
this->ran_out_of_room = false;
this->head = this->start;
this->debug_depth = 0;
+ }
+ template <typename Type>
+ inline Type *start_serialize (void)
+ {
DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
"start [%p..%p] (%lu bytes)",
this->start, this->end,
(unsigned long) (this->end - this->start));
+
+ return start_embed<Type> ();
}
- inline void end_processing (void)
+ inline void end_serialize (void)
{
DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
- "end [%p..%p] %s",
+ "end [%p..%p] serialized %d bytes; %s",
this->start, this->end,
+ (int) (this->head - this->start),
this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
- this->start = this->end = this->head = NULL;
+ }
+
+ template <typename Type>
+ inline Type *copy (void)
+ {
+ assert (!this->ran_out_of_room);
+ unsigned int len = this->head - this->start;
+ void *p = malloc (len);
+ if (p)
+ memcpy (p, this->start, len);
+ return reinterpret_cast<Type *> (p);
}
template <typename Type>
inline Type *allocate_size (unsigned int size)
{
- if (unlikely (this->ran_out_of_room || this->end - this->head > size)) {
+ if (unlikely (this->ran_out_of_room || this->end - this->head < size)) {
this->ran_out_of_room = true;
return NULL;
}
@@ -390,6 +404,13 @@
}
template <typename Type>
+ inline Type *start_embed (void)
+ {
+ Type *ret = reinterpret_cast<Type *> (this->head);
+ return ret;
+ }
+
+ template <typename Type>
inline Type *embed (const Type &obj)
{
unsigned int size = obj.get_size ();
@@ -403,8 +424,8 @@
inline Type *extend_min (Type &obj)
{
unsigned int size = obj.min_size;
- assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
- this->allocate_size<Type> (((char *) &obj) + size - this->head);
+ assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
return reinterpret_cast<Type *> (&obj);
}
@@ -413,7 +434,7 @@
{
unsigned int size = obj.get_size ();
assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
- this->allocate_size<Type> (((char *) &obj) + size - this->head);
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return false;
return reinterpret_cast<Type *> (&obj);
}
@@ -431,13 +452,6 @@
template <typename Type>
struct Supplier
{
- /* For automatic wrapping of bare arrays */
- inline Supplier (const Type *array)
- {
- head = array;
- len = (unsigned int) -1;
- }
-
inline Supplier (const Type *array, unsigned int len_)
{
head = array;
@@ -449,7 +463,8 @@
return head[i];
}
- inline void advance (unsigned int count) {
+ inline void advance (unsigned int count)
+ {
if (unlikely (count > len))
count = len;
len -= count;
@@ -457,6 +472,9 @@
}
private:
+ inline Supplier (const Supplier<Type> &); /* Disallow copy */
+ inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
+
unsigned int len;
const Type *head;
};
@@ -509,6 +527,8 @@
inline operator Type(void) const { return v; }
inline bool operator == (const IntType<Type> &o) const { return v == o.v; }
inline bool operator != (const IntType<Type> &o) const { return v != o.v; }
+ static inline int cmp (const IntType<Type> *a, const IntType<Type> *b) { return b->cmp (*a); }
+ inline int cmp (IntType<Type> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE ();
@@ -634,7 +654,7 @@
inline Type& serialize (hb_serialize_context_t *c, void *base)
{
- Type *t = (Type *) c->head;
+ Type *t = c->start_embed<Type> ();
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
return *t;
}
@@ -727,7 +747,7 @@
TRACE_SERIALIZE ();
if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false);
for (unsigned int i = 0; i < items_len; i++)
- array[i].set (items[i]);
+ array[i] = items[i];
items.advance (items_len);
return TRACE_RETURN (true);
}
@@ -842,11 +862,10 @@
TRACE_SERIALIZE ();
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
len.set (items_len); /* TODO(serialize) Overflow? */
- if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
if (unlikely (!items_len)) return TRACE_RETURN (true);
- unsigned int count = items_len;
- for (unsigned int i = 1; i < count; i++)
- array[i-1].set (items[i]);
+ if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < items_len - 1; i++)
+ array[i] = items[i];
items.advance (items_len - 1);
return TRACE_RETURN (true);
}