/*
 * 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_OT_KERN_TABLE_HH
#define HB_OT_KERN_TABLE_HH

#include "hb-aat-layout-kerx-table.hh"


/*
 * kern -- Kerning
 * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
 */
#define HB_OT_TAG_kern HB_TAG('k','e','r','n')


namespace OT {


template <typename KernSubTableHeader>
struct KernSubTableFormat3
{
  int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  {
    hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (kernValue).as_array (glyphCount);
    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (leftClass).as_array (glyphCount);
    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8> > (rightClass).as_array (leftClassCount * rightClassCount);

    unsigned int leftC = leftClass[left];
    unsigned int rightC = rightClass[right];
    if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))
      return 0;
    unsigned int i = leftC * rightClassCount + rightC;
    return kernValue[kernIndex[i]];
  }

  bool apply (AAT::hb_aat_apply_context_t *c) const
  {
    TRACE_APPLY (this);

    if (!c->plan->requested_kerning)
      return false;

    if (header.coverage & header.Backwards)
      return false;

    hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
    machine.kern (c->font, c->buffer, c->plan->kern_mask);

    return_trace (true);
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
		  c->check_range (kernValueZ,
				  kernValueCount * sizeof (FWORD) +
				  glyphCount * 2 +
				  leftClassCount * rightClassCount));
  }

  protected:
  KernSubTableHeader	header;
  HBUINT16		glyphCount;	/* The number of glyphs in this font. */
  HBUINT8		kernValueCount;	/* The number of kerning values. */
  HBUINT8		leftClassCount;	/* The number of left-hand classes. */
  HBUINT8		rightClassCount;/* The number of right-hand classes. */
  HBUINT8		flags;		/* Set to zero (reserved for future use). */
  UnsizedArrayOf<FWORD>	kernValueZ;	/* The kerning values.
					 * Length kernValueCount. */
#if 0
  UnsizedArrayOf<HBUINT8>leftClass;	/* The left-hand classes.
					 * Length glyphCount. */
  UnsizedArrayOf<HBUINT8>rightClass;	/* The right-hand classes.
					 * Length glyphCount. */
  UnsizedArrayOf<HBUINT8>kernIndex;	/* The indices into the kernValue array.
					 * Length leftClassCount * rightClassCount */
#endif
  public:
  DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
};

template <typename KernSubTableHeader>
struct KernSubTable
{
  unsigned int get_size () const { return u.header.length; }
  unsigned int get_type () const { return u.header.format; }

  int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  {
    switch (get_type ()) {
    /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
    case 0: return u.format0.get_kerning (left, right);
    default:return 0;
    }
  }

  template <typename context_t>
  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 0:	return_trace (c->dispatch (u.format0));
    case 1:	return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ());
    case 2:	return_trace (c->dispatch (u.format2));
    case 3:	return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ());
    default:	return_trace (c->default_return_value ());
    }
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (unlikely (!u.header.sanitize (c) ||
		  u.header.length < u.header.min_size ||
		  !c->check_range (this, u.header.length))) return_trace (false);

    return_trace (dispatch (c));
  }

  public:
  union {
  KernSubTableHeader				header;
  AAT::KerxSubTableFormat0<KernSubTableHeader>	format0;
  AAT::KerxSubTableFormat1<KernSubTableHeader>	format1;
  AAT::KerxSubTableFormat2<KernSubTableHeader>	format2;
  KernSubTableFormat3<KernSubTableHeader>	format3;
  } u;
  public:
  DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
};


struct KernOTSubTableHeader
{
  static constexpr bool apple = false;
  typedef AAT::ObsoleteTypes Types;

  unsigned int tuple_count () const { return 0; }
  bool is_horizontal () const { return (coverage & Horizontal); }

  enum Coverage
  {
    Horizontal	= 0x01u,
    Minimum	= 0x02u,
    CrossStream	= 0x04u,
    Override	= 0x08u,

    /* Not supported: */
    Backwards	= 0x00u,
    Variation	= 0x00u,
  };

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  public:
  HBUINT16	versionZ;	/* Unused. */
  HBUINT16	length;		/* Length of the subtable (including this header). */
  HBUINT8	format;		/* Subtable format. */
  HBUINT8	coverage;	/* Coverage bits. */
  public:
  DEFINE_SIZE_STATIC (6);
};

struct KernOT : AAT::KerxTable<KernOT>
{
  friend struct AAT::KerxTable<KernOT>;

  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
  static constexpr unsigned minVersion = 0u;

  typedef KernOTSubTableHeader SubTableHeader;
  typedef SubTableHeader::Types Types;
  typedef KernSubTable<SubTableHeader> SubTable;

  protected:
  HBUINT16	version;	/* Version--0x0000u */
  HBUINT16	tableCount;	/* Number of subtables in the kerning table. */
  SubTable	firstSubTable;	/* Subtables. */
  public:
  DEFINE_SIZE_MIN (4);
};


struct KernAATSubTableHeader
{
  static constexpr bool apple = true;
  typedef AAT::ObsoleteTypes Types;

  unsigned int tuple_count () const { return 0; }
  bool is_horizontal () const       { return !(coverage & Vertical); }

  enum Coverage
  {
    Vertical	= 0x80u,
    CrossStream	= 0x40u,
    Variation	= 0x20u,

    /* Not supported: */
    Backwards	= 0x00u,
  };

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  public:
  HBUINT32	length;		/* Length of the subtable (including this header). */
  HBUINT8	coverage;	/* Coverage bits. */
  HBUINT8	format;		/* Subtable format. */
  HBUINT16	tupleIndex;	/* The tuple index (used for variations fonts).
			       * This value specifies which tuple this subtable covers.
			       * Note: We don't implement. */
  public:
  DEFINE_SIZE_STATIC (8);
};

struct KernAAT : AAT::KerxTable<KernAAT>
{
  friend struct AAT::KerxTable<KernAAT>;

  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
  static constexpr unsigned minVersion = 0x00010000u;

  typedef KernAATSubTableHeader SubTableHeader;
  typedef SubTableHeader::Types Types;
  typedef KernSubTable<SubTableHeader> SubTable;

  protected:
  HBUINT32	version;	/* Version--0x00010000u */
  HBUINT32	tableCount;	/* Number of subtables in the kerning table. */
  SubTable	firstSubTable;	/* Subtables. */
  public:
  DEFINE_SIZE_MIN (8);
};

struct kern
{
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;

  bool has_data () const { return u.version32; }
  unsigned int get_type () const { return u.major; }

  bool has_state_machine () const
  {
    switch (get_type ()) {
    case 0: return u.ot.has_state_machine ();
    case 1: return u.aat.has_state_machine ();
    default:return false;
    }
  }

  bool has_cross_stream () const
  {
    switch (get_type ()) {
    case 0: return u.ot.has_cross_stream ();
    case 1: return u.aat.has_cross_stream ();
    default:return false;
    }
  }

  int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  {
    switch (get_type ()) {
    case 0: return u.ot.get_h_kerning (left, right);
    case 1: return u.aat.get_h_kerning (left, right);
    default:return 0;
    }
  }

  bool apply (AAT::hb_aat_apply_context_t *c) const
  { return dispatch (c); }

  template <typename context_t>
  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 0:	return_trace (c->dispatch (u.ot));
    case 1:	return_trace (c->dispatch (u.aat));
    default:	return_trace (c->default_return_value ());
    }
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (!u.version32.sanitize (c)) return_trace (false);
    return_trace (dispatch (c));
  }

  protected:
  union {
  HBUINT32		version32;
  HBUINT16		major;
  KernOT		ot;
  KernAAT		aat;
  } u;
  public:
  DEFINE_SIZE_UNION (4, version32);
};

} /* namespace OT */


#endif /* HB_OT_KERN_TABLE_HH */
