[aat/morx] Implement NoncontextualSubtables

Also makes hb-ot-shape call morx for now instead of GSUB... Just for testing.
This commit is contained in:
Behdad Esfahbod 2018-01-09 17:55:17 +01:00
parent 4cf3ab1d81
commit 748b989a1f
5 changed files with 111 additions and 27 deletions

View File

@ -183,10 +183,10 @@ struct LookupFormat0
friend struct Lookup<T>;
private:
inline const T& get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
if (unlikely (glyph_id >= num_glyphs)) return Null(T);
return arrayZ[glyph_id];
if (unlikely (glyph_id >= num_glyphs)) return nullptr;
return &arrayZ[glyph_id];
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -230,10 +230,10 @@ struct LookupFormat2
friend struct Lookup<T>;
private:
inline const T& get_value (hb_codepoint_t glyph_id) const
inline const T* get_value (hb_codepoint_t glyph_id) const
{
const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
return v ? v->value : Null(T);
return v ? &v->value : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -255,9 +255,9 @@ struct LookupFormat2
template <typename T>
struct LookupSegmentArray
{
inline const T& get_value (hb_codepoint_t glyph_id, const void *base) const
inline const T* get_value (hb_codepoint_t glyph_id, const void *base) const
{
return first <= glyph_id && glyph_id <= last ? (base+valuesZ)[glyph_id - first] : Null(T);
return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
}
inline int cmp (hb_codepoint_t g) const {
@ -287,10 +287,10 @@ struct LookupFormat4
friend struct Lookup<T>;
private:
inline const T& get_value (hb_codepoint_t glyph_id) const
inline const T* get_value (hb_codepoint_t glyph_id) const
{
const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
return v ? v->get_value (glyph_id, this) : Null(T);
return v ? v->get_value (glyph_id, this) : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -332,10 +332,10 @@ struct LookupFormat6
friend struct Lookup<T>;
private:
inline const T& get_value (hb_codepoint_t glyph_id) const
inline const T* get_value (hb_codepoint_t glyph_id) const
{
const LookupSingle<T> *v = entries.bsearch (glyph_id);
return v ? v->value : Null(T);
return v ? &v->value : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -358,9 +358,9 @@ struct LookupFormat8
friend struct Lookup<T>;
private:
inline const T& get_value (hb_codepoint_t glyph_id) const
inline const T* get_value (hb_codepoint_t glyph_id) const
{
return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? valueArrayZ[glyph_id - firstGlyph] : Null(T);
return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? &valueArrayZ[glyph_id - firstGlyph] : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -384,7 +384,7 @@ struct LookupFormat8
template <typename T>
struct Lookup
{
inline const T& get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
switch (u.format) {
case 0: return u.format0.get_value (glyph_id, num_glyphs);
@ -392,7 +392,7 @@ struct Lookup
case 4: return u.format4.get_value (glyph_id);
case 6: return u.format6.get_value (glyph_id);
case 8: return u.format8.get_value (glyph_id);
default:return Null(T);
default:return nullptr;
}
}
@ -423,10 +423,6 @@ struct Lookup
DEFINE_SIZE_UNION (2, format);
};
// Instantiate, to catch compile errors.
Lookup<GlyphID> g;
Lookup<Tag> t;
} /* namespace AAT */

View File

@ -27,8 +27,8 @@
#ifndef HB_AAT_LAYOUT_MORX_TABLE_HH
#define HB_AAT_LAYOUT_MORX_TABLE_HH
#include <hb-open-type-private.hh>
#include <hb-aat-layout-common-private.hh>
#include "hb-open-type-private.hh"
#include "hb-aat-layout-common-private.hh"
#define HB_AAT_TAG_MORT HB_TAG('m','o','r','t')
#define HB_AAT_TAG_MORX HB_TAG('m','o','r','x')
@ -41,7 +41,13 @@ using namespace OT;
struct RearrangementSubtable
{
/* TODO */
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
/* TODO */
return_trace (false);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -52,7 +58,13 @@ struct RearrangementSubtable
struct ContextualSubtable
{
/* TODO */
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
/* TODO */
return_trace (false);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -63,7 +75,13 @@ struct ContextualSubtable
struct LigatureSubtable
{
/* TODO */
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
/* TODO */
return_trace (false);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -74,6 +92,26 @@ struct LigatureSubtable
struct NoncontextualSubtable
{
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
hb_glyph_info_t *info = buffer->info;
unsigned int num_glyphs = c->face->get_num_glyphs ();
bool ret = false;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
{
const GlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
if (replacement)
{
info[i].codepoint = *replacement;
ret = true;
}
}
return_trace (ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -88,7 +126,13 @@ struct NoncontextualSubtable
struct InsertionSubtable
{
/* TODO */
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
/* TODO */
return_trace (false);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -136,6 +180,11 @@ struct ChainSubtable
Insertion = 5
};
inline void apply (hb_apply_context_t *c) const
{
dispatch (c);
}
template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const
{
@ -180,6 +229,16 @@ struct ChainSubtable
template <typename UINT>
struct Chain
{
inline void apply (hb_apply_context_t *c) const
{
const ChainSubtable<UINT> *subtable = &StructAtOffset<ChainSubtable<UINT> > (featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
subtable->apply (c);
subtable = &StructAfter<ChainSubtable<UINT> > (*subtable);
}
}
inline unsigned int get_size (void) const { return length; }
@ -231,6 +290,17 @@ struct mortmorx
static const hb_tag_t mortTag = HB_AAT_TAG_MORT;
static const hb_tag_t morxTag = HB_AAT_TAG_MORX;
inline void apply (hb_apply_context_t *c) const
{
const Chain<UINT> *chain = chains;
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
chain->apply (c);
chain = &StructAfter<Chain<UINT> > (*chain);
}
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);

View File

@ -34,4 +34,7 @@
#include "hb-open-type-private.hh"
HB_INTERNAL void
hb_aat_layout_substitute (OT::hb_apply_context_t *c);
#endif /* HB_AAT_LAYOUT_PRIVATE_HH */

View File

@ -25,7 +25,9 @@
*/
#include "hb-open-type-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-ot-layout-gsubgpos-private.hh"
#include "hb-aat-layout-private.hh"
#include "hb-aat-layout-morx-table.hh"
@ -39,10 +41,10 @@ _get_morx (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(AAT::morx);
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
return *(layout->morx.get ());
return *(layout->morx.get ()); /* XXX this doesn't call set_num_glyphs on sanitizer. */
}
void
static inline void
_hb_aat_layout_create (hb_face_t *face)
{
OT::Sanitizer<AAT::morx> sanitizer;
@ -55,3 +57,10 @@ _hb_aat_layout_create (hb_face_t *face)
OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ());
}
}
void
hb_aat_layout_substitute (OT::hb_apply_context_t *c)
{
const AAT::morx& morx = _get_morx (c->face);
morx.apply (c);
}

View File

@ -40,6 +40,8 @@
#include "hb-unicode-private.hh"
#include "hb-set-private.hh"
#include "hb-ot-layout-gsubgpos-private.hh"
#include "hb-aat-layout-private.hh"
static hb_tag_t common_features[] = {
HB_TAG('c','c','m','p'),
@ -613,6 +615,10 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
hb_synthesize_glyph_classes (c);
c->plan->substitute (c->font, buffer);
/* XXX Call morx instead. */
OT::hb_apply_context_t ac (0, c->font, c->buffer);
hb_aat_layout_substitute (&ac);
}
static inline void