[aat] Start implementing Apple AAT morx table
This commit is contained in:
parent
3c7aeb5c64
commit
c71b55a223
|
@ -82,6 +82,8 @@ HB_FALLBACK_sources = \
|
|||
$(NULL)
|
||||
|
||||
HB_OT_sources = \
|
||||
hb-aat-layout.cc \
|
||||
hb-aat-layout-morx-table.hh \
|
||||
hb-ot-font.cc \
|
||||
hb-ot-layout.cc \
|
||||
hb-ot-layout-common-private.hh \
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Copyright © 2017 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_AAT_LAYOUT_MORX_TABLE_HH
|
||||
#define HB_AAT_LAYOUT_MORX_TABLE_HH
|
||||
|
||||
#include <hb-open-type-private.hh>
|
||||
|
||||
#define HB_AAT_TAG_MORT HB_TAG('m','o','r','t')
|
||||
#define HB_AAT_TAG_MORX HB_TAG('m','o','r','x')
|
||||
|
||||
|
||||
namespace AAT {
|
||||
|
||||
using namespace OT;
|
||||
|
||||
|
||||
struct RearrangementSubtable
|
||||
{
|
||||
/* TODO */
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
};
|
||||
|
||||
struct ContextualSubtable
|
||||
{
|
||||
/* TODO */
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
};
|
||||
|
||||
struct LigatureSubtable
|
||||
{
|
||||
/* TODO */
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
};
|
||||
|
||||
struct NoncontextualSubtable
|
||||
{
|
||||
/* TODO */
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
};
|
||||
|
||||
struct InsertionSubtable
|
||||
{
|
||||
/* TODO */
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Feature
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
public:
|
||||
USHORT featureType; /* The type of feature. */
|
||||
USHORT featureSetting; /* The feature's setting (aka selector). */
|
||||
ULONG enableFlags; /* Flags for the settings that this feature
|
||||
* and setting enables. */
|
||||
ULONG disableFlags; /* Complement of flags for the settings that this
|
||||
* feature and setting disable. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
|
||||
template <typename UINT>
|
||||
struct ChainSubtable
|
||||
{
|
||||
template <typename> struct Chain;
|
||||
friend struct Chain<UINT>;
|
||||
|
||||
inline unsigned int get_size (void) const { return length; }
|
||||
inline unsigned int get_type (void) const { return coverage & 0xFF; }
|
||||
|
||||
enum Type {
|
||||
Rearrangement = 0,
|
||||
Contextual = 1,
|
||||
Ligature = 2,
|
||||
Noncontextual = 4,
|
||||
Insertion = 5
|
||||
};
|
||||
|
||||
template <typename context_t>
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
unsigned int subtable_type = get_type ();
|
||||
TRACE_DISPATCH (this, subtable_type);
|
||||
switch (subtable_type) {
|
||||
case Rearrangement: return_trace (c->dispatch (u.rearrangement));
|
||||
case Contextual: return_trace (c->dispatch (u.contextual));
|
||||
case Ligature: return_trace (c->dispatch (u.ligature));
|
||||
case Noncontextual: return_trace (c->dispatch (u.noncontextual));
|
||||
case Insertion: return_trace (c->dispatch (u.insertion));
|
||||
default: return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!length.sanitize (c) ||
|
||||
length < min_size ||
|
||||
!c->check_range (this, length))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (dispatch (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
UINT length; /* Total subtable length, including this header. */
|
||||
UINT coverage; /* Coverage flags and subtable type. */
|
||||
ULONG subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */
|
||||
union {
|
||||
RearrangementSubtable rearrangement;
|
||||
ContextualSubtable contextual;
|
||||
LigatureSubtable ligature;
|
||||
NoncontextualSubtable noncontextual;
|
||||
InsertionSubtable insertion;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_MIN (2 * sizeof (UINT) + 4);
|
||||
};
|
||||
|
||||
template <typename UINT>
|
||||
struct Chain
|
||||
{
|
||||
|
||||
inline unsigned int get_size (void) const { return length; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!length.sanitize (c) ||
|
||||
length < min_size ||
|
||||
!c->check_range (this, length))
|
||||
return_trace (false);
|
||||
|
||||
if (!c->check_array (featureZ, featureZ[0].static_size, featureCount))
|
||||
return_trace (false);
|
||||
|
||||
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++)
|
||||
{
|
||||
if (!subtable->sanitize (c))
|
||||
return_trace (false);
|
||||
subtable = &StructAfter<ChainSubtable<UINT> > (*subtable);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
protected:
|
||||
ULONG defaultFlags; /* The default specification for subtables. */
|
||||
ULONG length; /* Total byte count, including this header. */
|
||||
UINT featureCount; /* Number of feature subtable entries. */
|
||||
UINT subtableCount; /* The number of subtables in the chain. */
|
||||
|
||||
Feature featureZ[VAR]; /* Features. */
|
||||
ChainSubtable<UINT> subtableX[VAR]; /* Subtables. */
|
||||
// subtableGlyphCoverageArray if major == 3
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8 + 2 * sizeof (UINT));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The 'mort'/'morx' Tables
|
||||
*/
|
||||
|
||||
template <typename UINT>
|
||||
struct mortmorx
|
||||
{
|
||||
static const hb_tag_t mortTag = HB_AAT_TAG_MORT;
|
||||
static const hb_tag_t morxTag = HB_AAT_TAG_MORX;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!version.sanitize (c) ||
|
||||
version.major >> (sizeof (UINT) == 4) != 1 ||
|
||||
!chainCount.sanitize (c))
|
||||
return_trace (false);
|
||||
|
||||
const Chain<UINT> *chain = chains;
|
||||
unsigned int count = chainCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (!chain->sanitize (c, version.major))
|
||||
return_trace (false);
|
||||
chain = &StructAfter<Chain<UINT> > (*chain);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version number of the glyph metamorphosis table.
|
||||
* 1 for mort, 2 or 3 for morx. */
|
||||
ULONG chainCount; /* Number of metamorphosis chains contained in this
|
||||
* table. */
|
||||
Chain<UINT> chains[VAR]; /* Chains. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8);
|
||||
};
|
||||
|
||||
struct mort : mortmorx<USHORT>
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_AAT_TAG_MORT;
|
||||
};
|
||||
|
||||
struct morx : mortmorx<ULONG>
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_AAT_TAG_MORX;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace AAT */
|
||||
|
||||
|
||||
#endif /* HB_AAT_LAYOUT_MORX_TABLE_HH */
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright © 2017 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
#include "hb-aat-layout-morx-table.hh"
|
||||
|
||||
/*
|
||||
* mort/morx
|
||||
*/
|
||||
|
||||
static inline const AAT::morx&
|
||||
_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 ());
|
||||
}
|
|
@ -160,6 +160,11 @@ static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small.
|
|||
* Dispatch
|
||||
*/
|
||||
|
||||
#define TRACE_DISPATCH(this, format) \
|
||||
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"format %d", (int) format);
|
||||
|
||||
template <typename Context, typename Return, unsigned int MaxDebugDepth>
|
||||
struct hb_dispatch_context_t
|
||||
{
|
||||
|
|
|
@ -130,6 +130,10 @@ namespace OT {
|
|||
struct avar;
|
||||
}
|
||||
|
||||
namespace AAT {
|
||||
struct morx;
|
||||
}
|
||||
|
||||
struct hb_ot_layout_lookup_accelerator_t
|
||||
{
|
||||
template <typename TLookup>
|
||||
|
@ -165,6 +169,7 @@ struct hb_ot_layout_t
|
|||
OT::hb_lazy_table_loader_t<struct OT::MATH> math;
|
||||
OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
|
||||
OT::hb_lazy_table_loader_t<struct OT::avar> avar;
|
||||
OT::hb_lazy_table_loader_t<struct AAT::morx> morx;
|
||||
|
||||
unsigned int gsub_lookup_count;
|
||||
unsigned int gpos_lookup_count;
|
||||
|
|
|
@ -62,6 +62,7 @@ _hb_ot_layout_create (hb_face_t *face)
|
|||
layout->math.init (face);
|
||||
layout->fvar.init (face);
|
||||
layout->avar.init (face);
|
||||
layout->morx.init (face);
|
||||
|
||||
{
|
||||
/*
|
||||
|
@ -209,6 +210,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
|||
layout->math.fini ();
|
||||
layout->fvar.fini ();
|
||||
layout->avar.fini ();
|
||||
layout->morx.fini ();
|
||||
|
||||
free (layout);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue