/*
 * Copyright © 2015  Google, Inc.
 * Copyright © 2019  Adobe Inc.
 * Copyright © 2019  Ebrahim Byagowi
 *
 *  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, Garret Rieger, Roderick Sheeter
 * Adobe Author(s): Michiharu Ariza
 */

#ifndef HB_OT_GLYF_TABLE_HH
#define HB_OT_GLYF_TABLE_HH

#include "hb-open-type.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-var-gvar-table.hh"
#include "hb-draw.hh"

namespace OT {


/*
 * loca -- Index to Location
 * https://docs.microsoft.com/en-us/typography/opentype/spec/loca
 */
#define HB_OT_TAG_loca HB_TAG('l','o','c','a')


struct loca
{
  friend struct glyf;

  static constexpr hb_tag_t tableTag = HB_OT_TAG_loca;

  bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
  {
    TRACE_SANITIZE (this);
    return_trace (true);
  }

  protected:
  UnsizedArrayOf<HBUINT8>
		dataZ;	/* Location data. */
  public:
  DEFINE_SIZE_MIN (0);	/* In reality, this is UNBOUNDED() type; but since we always
			 * check the size externally, allow Null() object of it by
			 * defining it _MIN instead. */
};


/*
 * glyf -- TrueType Glyph Data
 * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf
 */
#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')


struct glyf
{
  static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;

  bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
  {
    TRACE_SANITIZE (this);
    /* Runtime checks as eager sanitizing each glyph is costy */
    return_trace (true);
  }

  template<typename Iterator,
	   hb_requires (hb_is_source_of (Iterator, unsigned int))>
  static bool
  _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets)
  {
    unsigned max_offset = + padded_offsets | hb_reduce(hb_add, 0);
    unsigned num_offsets = padded_offsets.len () + 1;
    bool use_short_loca = max_offset < 0x1FFFF;
    unsigned entry_size = use_short_loca ? 2 : 4;
    char *loca_prime_data = (char *) calloc (entry_size, num_offsets);

    if (unlikely (!loca_prime_data)) return false;

    DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d "
				"max_offset %d size %d",
	       entry_size, num_offsets, max_offset, entry_size * num_offsets);

    if (use_short_loca)
      _write_loca (padded_offsets, 1, hb_array ((HBUINT16*) loca_prime_data, num_offsets));
    else
      _write_loca (padded_offsets, 0, hb_array ((HBUINT32*) loca_prime_data, num_offsets));

    hb_blob_t * loca_blob = hb_blob_create (loca_prime_data,
					    entry_size * num_offsets,
					    HB_MEMORY_MODE_WRITABLE,
					    loca_prime_data,
					    free);

    bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
		  && _add_head_and_set_loca_version (plan, use_short_loca);

    hb_blob_destroy (loca_blob);
    return result;
  }

  template<typename IteratorIn, typename IteratorOut,
	   hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
	   hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
  static void
  _write_loca (IteratorIn it, unsigned right_shift, IteratorOut dest)
  {
    unsigned int offset = 0;
    dest << 0;
    + it
    | hb_map ([=, &offset] (unsigned int padded_size)
	      {
		offset += padded_size;
		DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
		return offset >> right_shift;
	      })
    | hb_sink (dest)
    ;
  }

  /* requires source of SubsetGlyph complains the identifier isn't declared */
  template <typename Iterator>
  bool serialize (hb_serialize_context_t *c,
		  Iterator it,
		  const hb_subset_plan_t *plan)
  {
    TRACE_SERIALIZE (this);
    unsigned init_len = c->length ();
    for (const auto &_ : it) _.serialize (c, plan);

    /* As a special case when all glyph in the font are empty, add a zero byte
     * to the table, so that OTS doesn’t reject it, and to make the table work
     * on Windows as well.
     * See https://github.com/khaledhosny/ots/issues/52 */
    if (init_len == c->length ())
    {
      HBUINT8 empty_byte;
      empty_byte = 0;
      c->copy (empty_byte);
    }
    return_trace (true);
  }

  /* Byte region(s) per glyph to output
     unpadded, hints removed if so requested
     If we fail to process a glyph we produce an empty (0-length) glyph */
  bool subset (hb_subset_context_t *c) const
  {
    TRACE_SUBSET (this);

    glyf *glyf_prime = c->serializer->start_embed <glyf> ();
    if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);

    hb_vector_t<SubsetGlyph> glyphs;
    _populate_subset_glyphs (c->plan, &glyphs);

    glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan);

    auto padded_offsets =
    + hb_iter (glyphs)
    | hb_map (&SubsetGlyph::padded_size)
    ;

    if (c->serializer->in_error ()) return_trace (false);
    return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
								    padded_offsets)));
  }

  template <typename SubsetGlyph>
  void
  _populate_subset_glyphs (const hb_subset_plan_t   *plan,
			   hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
  {
    OT::glyf::accelerator_t glyf;
    glyf.init (plan->source);

    + hb_range (plan->num_output_glyphs ())
    | hb_map ([&] (hb_codepoint_t new_gid)
	      {
		SubsetGlyph subset_glyph = {0};
		subset_glyph.new_gid = new_gid;

		/* should never fail: all old gids should be mapped */
		if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
		  return subset_glyph;

		subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
		if (plan->drop_hints) subset_glyph.drop_hints_bytes ();
		else subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();

		return subset_glyph;
	      })
    | hb_sink (glyphs)
    ;

    glyf.fini ();
  }

  static bool
  _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
  {
    hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
    hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
    hb_blob_destroy (head_blob);

    if (unlikely (!head_prime_blob))
      return false;

    head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
    head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
    bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);

    hb_blob_destroy (head_prime_blob);
    return success;
  }

  struct CompositeGlyphChain
  {
    enum composite_glyph_flag_t
    {
      ARG_1_AND_2_ARE_WORDS	= 0x0001,
      ARGS_ARE_XY_VALUES	= 0x0002,
      ROUND_XY_TO_GRID		= 0x0004,
      WE_HAVE_A_SCALE		= 0x0008,
      MORE_COMPONENTS		= 0x0020,
      WE_HAVE_AN_X_AND_Y_SCALE	= 0x0040,
      WE_HAVE_A_TWO_BY_TWO	= 0x0080,
      WE_HAVE_INSTRUCTIONS	= 0x0100,
      USE_MY_METRICS		= 0x0200,
      OVERLAP_COMPOUND		= 0x0400,
      SCALED_COMPONENT_OFFSET	= 0x0800,
      UNSCALED_COMPONENT_OFFSET = 0x1000
    };

    unsigned int get_size () const
    {
      unsigned int size = min_size;
      /* arg1 and 2 are int16 */
      if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
      /* arg1 and 2 are int8 */
      else size += 2;

      /* One x 16 bit (scale) */
      if (flags & WE_HAVE_A_SCALE) size += 2;
      /* Two x 16 bit (xscale, yscale) */
      else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
      /* Four x 16 bit (xscale, scale01, scale10, yscale) */
      else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;

      return size;
    }

    bool is_use_my_metrics () const { return   flags & USE_MY_METRICS; }
    bool is_anchored ()       const { return !(flags & ARGS_ARE_XY_VALUES); }
    void get_anchor_points (unsigned int &point1, unsigned int &point2) const
    {
      const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
      if (flags & ARG_1_AND_2_ARE_WORDS)
      {
	point1 = ((const HBUINT16 *) p)[0];
	point2 = ((const HBUINT16 *) p)[1];
      }
      else
      {
	point1 = p[0];
	point2 = p[1];
      }
    }

    void transform_points (contour_point_vector_t &points) const
    {
      float matrix[4];
      contour_point_t trans;
      if (get_transformation (matrix, trans))
      {
	if (scaled_offsets ())
	{
	  points.translate (trans);
	  points.transform (matrix);
	}
	else
	{
	  points.transform (matrix);
	  points.translate (trans);
	}
      }
    }

    protected:
    bool scaled_offsets () const
    { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }

    bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
    {
      matrix[0] = matrix[3] = 1.f;
      matrix[1] = matrix[2] = 0.f;

      int tx, ty;
      const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
      if (flags & ARG_1_AND_2_ARE_WORDS)
      {
	tx = *(const HBINT16 *) p;
	p += HBINT16::static_size;
	ty = *(const HBINT16 *) p;
	p += HBINT16::static_size;
      }
      else
      {
	tx = *p++;
	ty = *p++;
      }
      if (is_anchored ()) tx = ty = 0;

      trans.init ((float) tx, (float) ty);

      {
	const F2DOT14 *points = (const F2DOT14 *) p;
	if (flags & WE_HAVE_A_SCALE)
	{
	  matrix[0] = matrix[3] = points[0].to_float ();
	  return true;
	}
	else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
	{
	  matrix[0] = points[0].to_float ();
	  matrix[3] = points[1].to_float ();
	  return true;
	}
	else if (flags & WE_HAVE_A_TWO_BY_TWO)
	{
	  matrix[0] = points[0].to_float ();
	  matrix[1] = points[1].to_float ();
	  matrix[2] = points[2].to_float ();
	  matrix[3] = points[3].to_float ();
	  return true;
	}
      }
      return tx || ty;
    }

    public:
    HBUINT16	flags;
    HBGlyphID	glyphIndex;
    public:
    DEFINE_SIZE_MIN (4);
  };

  struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphChain &>
  {
    typedef const CompositeGlyphChain *__item_t__;
    composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
      glyph (glyph_), current (current_)
    { if (!check_range (current)) current = nullptr; }
    composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {}

    const CompositeGlyphChain &__item__ () const { return *current; }
    bool __more__ () const { return current; }
    void __next__ ()
    {
      if (!(current->flags & CompositeGlyphChain::MORE_COMPONENTS)) { current = nullptr; return; }

      const CompositeGlyphChain *possible = &StructAfter<CompositeGlyphChain,
							 CompositeGlyphChain> (*current);
      if (!check_range (possible)) { current = nullptr; return; }
      current = possible;
    }
    bool operator != (const composite_iter_t& o) const
    { return glyph != o.glyph || current != o.current; }

    bool check_range (const CompositeGlyphChain *composite) const
    {
      return glyph.check_range (composite, CompositeGlyphChain::min_size)
	  && glyph.check_range (composite, composite->get_size ());
    }

    private:
    hb_bytes_t glyph;
    __item_t__ current;
  };

  enum phantom_point_index_t
  {
    PHANTOM_LEFT   = 0,
    PHANTOM_RIGHT  = 1,
    PHANTOM_TOP    = 2,
    PHANTOM_BOTTOM = 3,
    PHANTOM_COUNT  = 4
  };

  struct Glyph
  {
    enum simple_glyph_flag_t
    {
      FLAG_ON_CURVE  = 0x01,
      FLAG_X_SHORT   = 0x02,
      FLAG_Y_SHORT   = 0x04,
      FLAG_REPEAT    = 0x08,
      FLAG_X_SAME    = 0x10,
      FLAG_Y_SAME    = 0x20,
      FLAG_RESERVED1 = 0x40,
      FLAG_RESERVED2 = 0x80
    };

    private:
    struct GlyphHeader
    {
      bool has_data () const { return numberOfContours; }

      bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
      {
	/* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
	/* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
	extents->x_bearing = font->em_scale_x (font->face->table.hmtx->get_side_bearing (gid));
	extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax));
	extents->width     = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
	extents->height    = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));

	return true;
      }

      HBINT16	numberOfContours;
			/* If the number of contours is
			 * greater than or equal to zero,
			 * this is a simple glyph; if negative,
			 * this is a composite glyph. */
      FWORD	xMin;	/* Minimum x for coordinate data. */
      FWORD	yMin;	/* Minimum y for coordinate data. */
      FWORD	xMax;	/* Maximum x for coordinate data. */
      FWORD	yMax;	/* Maximum y for coordinate data. */
      public:
      DEFINE_SIZE_STATIC (10);
    };

    struct SimpleGlyph
    {
      const GlyphHeader &header;
      hb_bytes_t bytes;
      SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
	header (header_), bytes (bytes_) {}

      unsigned int instruction_len_offset () const
      { return GlyphHeader::static_size + 2 * header.numberOfContours; }

      unsigned int length (unsigned int instruction_len) const
      { return instruction_len_offset () + 2 + instruction_len; }

      unsigned int instructions_length () const
      {
	unsigned int instruction_length_offset = instruction_len_offset ();
	if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0;

	const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset);
	/* Out of bounds of the current glyph */
	if (unlikely (length (instructionLength) > bytes.length)) return 0;
	return instructionLength;
      }

      const Glyph trim_padding () const
      {
	/* based on FontTools _g_l_y_f.py::trim */
	const char *glyph = bytes.arrayZ;
	const char *glyph_end = glyph + bytes.length;
	/* simple glyph w/contours, possibly trimmable */
	glyph += instruction_len_offset ();

	if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
	unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
	unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);

	glyph += 2 + num_instructions;

	unsigned int coord_bytes = 0;
	unsigned int coords_with_flags = 0;
	while (glyph < glyph_end)
	{
	  uint8_t flag = *glyph;
	  glyph++;

	  unsigned int repeat = 1;
	  if (flag & FLAG_REPEAT)
	  {
	    if (unlikely (glyph >= glyph_end)) return Glyph ();
	    repeat = *glyph + 1;
	    glyph++;
	  }

	  unsigned int xBytes, yBytes;
	  xBytes = yBytes = 0;
	  if (flag & FLAG_X_SHORT) xBytes = 1;
	  else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;

	  if (flag & FLAG_Y_SHORT) yBytes = 1;
	  else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;

	  coord_bytes += (xBytes + yBytes) * repeat;
	  coords_with_flags += repeat;
	  if (coords_with_flags >= num_coordinates) break;
	}

	if (unlikely (coords_with_flags != num_coordinates)) return Glyph ();
	return Glyph (bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph)));
      }

      /* zero instruction length */
      void drop_hints ()
      {
	GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
	(HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
      }

      void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
      {
	unsigned int instructions_len = instructions_length ();
	unsigned int glyph_length = length (instructions_len);
	dest_start = bytes.sub_array (0, glyph_length - instructions_len);
	dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
      }

      static bool read_points (const HBUINT8 *&p /* IN/OUT */,
			       contour_point_vector_t &points_ /* IN/OUT */,
			       const hb_bytes_t &bytes,
			       void (* setter) (contour_point_t &_, float v),
			       const simple_glyph_flag_t short_flag,
			       const simple_glyph_flag_t same_flag)
      {
	float v = 0;
	for (unsigned i = 0; i < points_.length; i++)
	{
	  uint8_t flag = points_[i].flag;
	  if (flag & short_flag)
	  {
	    if (unlikely (!bytes.check_range (p))) return false;
	    if (flag & same_flag)
	      v += *p++;
	    else
	      v -= *p++;
	  }
	  else
	  {
	    if (!(flag & same_flag))
	    {
	      if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false;
	      v += *(const HBINT16 *) p;
	      p += HBINT16::static_size;
	    }
	  }
	  setter (points_[i], v);
	}
	return true;
      }

      bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
			       bool phantom_only = false) const
      {
	const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
	int num_contours = header.numberOfContours;
	if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours + 1]))) return false;
	unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;

	points_.resize (num_points);
	for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
	if (phantom_only) return true;

	for (int i = 0; i < num_contours; i++)
	  points_[endPtsOfContours[i]].is_end_point = true;

	/* Skip instructions */
	const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
						     endPtsOfContours[num_contours]);

	/* Read flags */
	for (unsigned int i = 0; i < num_points; i++)
	{
	  if (unlikely (!bytes.check_range (p))) return false;
	  uint8_t flag = *p++;
	  points_[i].flag = flag;
	  if (flag & FLAG_REPEAT)
	  {
	    if (unlikely (!bytes.check_range (p))) return false;
	    unsigned int repeat_count = *p++;
	    while ((repeat_count-- > 0) && (++i < num_points))
	      points_[i].flag = flag;
	  }
	}

	/* Read x & y coordinates */
	return (read_points (p, points_, bytes,
			     [] (contour_point_t &p, float v) { p.x = v; }, FLAG_X_SHORT, FLAG_X_SAME) &&
		read_points (p, points_, bytes,
			     [] (contour_point_t &p, float v) { p.y = v; }, FLAG_Y_SHORT, FLAG_Y_SAME));
      }
    };

    struct CompositeGlyph
    {
      const GlyphHeader &header;
      hb_bytes_t bytes;
      CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
	header (header_), bytes (bytes_) {}

      composite_iter_t get_iterator () const
      { return composite_iter_t (bytes, &StructAfter<CompositeGlyphChain, GlyphHeader> (header)); }

      unsigned int instructions_length (hb_bytes_t bytes) const
      {
	unsigned int start = bytes.length;
	unsigned int end = bytes.length;
	const CompositeGlyphChain *last = nullptr;
	for (auto &item : get_iterator ())
	  last = &item;
	if (unlikely (!last)) return 0;

	if ((uint16_t) last->flags & CompositeGlyphChain::WE_HAVE_INSTRUCTIONS)
	  start = (char *) last - &bytes + last->get_size ();
	if (unlikely (start > end)) return 0;
	return end - start;
      }

      /* Trimming for composites not implemented.
       * If removing hints it falls out of that. */
      const Glyph trim_padding () const { return Glyph (bytes); }

      /* remove WE_HAVE_INSTRUCTIONS flag from composite glyph */
      void drop_hints ()
      {
	for (const auto &_ : get_iterator ())
	  *const_cast<OT::HBUINT16 *> (&_.flags) = (uint16_t) _.flags & ~OT::glyf::CompositeGlyphChain::WE_HAVE_INSTRUCTIONS;
      }

      /* Chop instructions off the end */
      void drop_hints_bytes (hb_bytes_t &dest_start) const
      { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
    };

    enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };

    public:
    composite_iter_t get_composite_iterator () const
    {
      if (type != COMPOSITE) return composite_iter_t ();
      return CompositeGlyph (*header, bytes).get_iterator ();
    }

    const Glyph trim_padding () const
    {
      switch (type) {
      case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
      case SIMPLE:    return SimpleGlyph (*header, bytes).trim_padding ();
      default:        return bytes;
      }
    }

    void drop_hints ()
    {
      switch (type) {
      case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
      case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints (); return;
      default:        return;
      }
    }

    void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
    {
      switch (type) {
      case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
      case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
      default:        return;
      }
    }

    /* Note: Recursively calls itself.
     * all_points includes phantom points
     */
    template<typename T>
    bool get_points (T glyph_for_gid, hb_font_t *font,
		     contour_point_vector_t &all_points /* OUT */,
		     bool phantom_only = false,
		     unsigned int depth = 0) const
    {
      if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
      contour_point_vector_t points;

      switch (type) {
      case COMPOSITE:
      {
	/* pseudo component points for each component in composite glyph */
	unsigned num_points = hb_len (CompositeGlyph (*header, bytes).get_iterator ());
	if (unlikely (!points.resize (num_points))) return false;
	for (unsigned i = 0; i < points.length; i++)
	  points[i].init ();
	break;
      }
      case SIMPLE:
	if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
	  return false;
	break;
      default: return false; /* empty glyph */
      }

      hb_face_t *face = font->face;

      /* Init phantom points */
      if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
      hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
      {
	for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init ();
	int h_delta = (int) header->xMin - face->table.hmtx->get_side_bearing (gid);
	int v_orig  = (int) header->yMax + face->table.vmtx->get_side_bearing (gid);
	unsigned h_adv = face->table.hmtx->get_advance (gid);
	unsigned v_adv = face->table.vmtx->get_advance (gid);
	phantoms[PHANTOM_LEFT].x = h_delta;
	phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
	phantoms[PHANTOM_TOP].y = v_orig;
	phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
      }

#ifndef HB_NO_VAR
      if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, font, points.as_array ())))
	return false;
#endif

      switch (type) {
      case SIMPLE:
	all_points.extend (points.as_array ());
	break;
      case COMPOSITE:
      {
	unsigned int comp_index = 0;
	for (auto &item : get_composite_iterator ())
	{
	  contour_point_vector_t comp_points;
	  if (unlikely (!glyph_for_gid (item.glyphIndex).get_points (glyph_for_gid, font, comp_points, phantom_only, depth + 1))
			|| comp_points.length < PHANTOM_COUNT)
	    return false;

	  /* Copy phantom points from component if USE_MY_METRICS flag set */
	  if (item.is_use_my_metrics ())
	    for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
	      phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];

	  /* Apply component transformation & translation */
	  item.transform_points (comp_points);

	  /* Apply translation from gvar */
	  comp_points.translate (points[comp_index]);

	  if (item.is_anchored ())
	  {
	    unsigned int p1, p2;
	    item.get_anchor_points (p1, p2);
	    if (likely (p1 < all_points.length && p2 < comp_points.length))
	    {
	      contour_point_t delta;
	      delta.init (all_points[p1].x - comp_points[p2].x,
			  all_points[p1].y - comp_points[p2].y);

	      comp_points.translate (delta);
	    }
	  }

	  all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));

	  comp_index++;
	}

	all_points.extend (phantoms);
      } break;
      default: return false;
      }

      if (depth == 0) /* Apply at top level */
      {
	/* Undocumented rasterizer behavior:
	 * Shift points horizontally by the updated left side bearing
	 */
	contour_point_t delta;
	delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
	if (delta.x) all_points.translate (delta);
      }

      return true;
    }

    bool get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
    {
      if (type == EMPTY) return true; /* Empty glyph; zero extents. */
      return header->get_extents (font, gid, extents);
    }

    hb_bytes_t get_bytes () const { return bytes; }

    Glyph (hb_bytes_t bytes_ = hb_bytes_t (),
	   hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), gid (gid_),
							header (bytes.as<GlyphHeader> ())
    {
      int num_contours = header->numberOfContours;
      if (unlikely (num_contours == 0)) type = EMPTY;
      else if (num_contours > 0) type = SIMPLE;
      else type = COMPOSITE; /* negative numbers */
    }

    protected:
    hb_bytes_t bytes;
    hb_codepoint_t gid;
    const GlyphHeader *header;
    unsigned type;
  };

  struct accelerator_t
  {
    void init (hb_face_t *face_)
    {
      short_offset = false;
      num_glyphs = 0;
      loca_table = nullptr;
      glyf_table = nullptr;
      face = face_;
      const OT::head &head = *face->table.head;
      if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
	/* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
	return;
      short_offset = 0 == head.indexToLocFormat;

      loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
      glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);

      num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
      num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
    }

    void fini ()
    {
      loca_table.destroy ();
      glyf_table.destroy ();
    }

    protected:
    template<typename T>
    bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const
    {
      /* Making this alloc free is not that easy
	 https://github.com/harfbuzz/harfbuzz/issues/2095
	 mostly because of gvar handling in VF fonts,
	 perhaps a separate path for non-VF fonts can be considered */
      contour_point_vector_t all_points;

      bool phantom_only = !consumer.is_consuming_contour_points ();
      if (unlikely (!glyph_for_gid (gid).get_points ([this] (hb_codepoint_t gid) -> const Glyph { return this->glyph_for_gid (gid); },
						     font, all_points, phantom_only)))
	return false;

      if (consumer.is_consuming_contour_points ())
      {
	for (unsigned point_index = 0; point_index + 4 < all_points.length; ++point_index)
	  consumer.consume_point (all_points[point_index]);
	consumer.points_end ();
      }

      /* Where to write phantoms, nullptr if not requested */
      contour_point_t *phantoms = consumer.get_phantoms_sink ();
      if (phantoms)
	for (unsigned i = 0; i < PHANTOM_COUNT; ++i)
	  phantoms[i] = all_points[all_points.length - PHANTOM_COUNT + i];

      return true;
    }

    public:
#ifndef HB_NO_VAR
    struct points_aggregator_t
    {
      hb_font_t *font;
      hb_glyph_extents_t *extents;
      contour_point_t *phantoms;

      struct contour_bounds_t
      {
	contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }

	void add (const contour_point_t &p)
	{
	  min_x = hb_min (min_x, p.x);
	  min_y = hb_min (min_y, p.y);
	  max_x = hb_max (max_x, p.x);
	  max_y = hb_max (max_y, p.y);
	}

	bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }

	void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
	{
	  if (unlikely (empty ()))
	  {
	    extents->width = 0;
	    extents->x_bearing = 0;
	    extents->height = 0;
	    extents->y_bearing = 0;
	    return;
	  }
	  extents->x_bearing = font->em_scalef_x (min_x);
	  extents->width = font->em_scalef_x (max_x - min_x);
	  extents->y_bearing = font->em_scalef_y (max_y);
	  extents->height = font->em_scalef_y (min_y - max_y);
	}

	protected:
	float min_x, min_y, max_x, max_y;
      } bounds;

      points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_)
      {
	font = font_;
	extents = extents_;
	phantoms = phantoms_;
	if (extents) bounds = contour_bounds_t ();
      }

      void consume_point (const contour_point_t &point) { bounds.add (point); }
      void points_end () { bounds.get_extents (font, extents); }

      bool is_consuming_contour_points () { return extents; }
      contour_point_t *get_phantoms_sink () { return phantoms; }
    };

    unsigned int
    get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
    {
      bool success = false;

      contour_point_t phantoms[PHANTOM_COUNT];
      if (likely (font->num_coords == face->table.gvar->get_axis_count ()))
	success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms));

      if (unlikely (!success))
	return is_vertical
	     ? face->table.vmtx->get_advance (gid)
	     : face->table.hmtx->get_advance (gid);

      return is_vertical
	   ? roundf (phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y)
	   : roundf (phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x);
    }

    int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
    {
      hb_glyph_extents_t extents;

      contour_point_t phantoms[PHANTOM_COUNT];
      if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms))))
	return is_vertical
	     ? face->table.vmtx->get_side_bearing (gid)
	     : face->table.hmtx->get_side_bearing (gid);

      return is_vertical
	   ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing
	   : floorf (phantoms[PHANTOM_LEFT].x);
    }
#endif

    bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
    {
      if (unlikely (gid >= num_glyphs)) return false;
#ifndef HB_NO_VAR
      if (font->num_coords && font->num_coords == face->table.gvar->get_axis_count ())
	return get_points (font, gid, points_aggregator_t (font, extents, nullptr));
#endif
      return glyph_for_gid (gid).get_extents (font, extents);
    }

    const Glyph
    glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
    {
      unsigned int start_offset, end_offset;
      if (unlikely (gid >= num_glyphs)) return Glyph ();

      if (short_offset)
      {
	const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
	start_offset = 2 * offsets[gid];
	end_offset   = 2 * offsets[gid + 1];
      }
      else
      {
	const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
	start_offset = offsets[gid];
	end_offset   = offsets[gid + 1];
      }

      if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ()))
	return Glyph ();

      Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
			       end_offset - start_offset), gid);
      return needs_padding_removal ? glyph.trim_padding () : glyph;
    }

    void
    add_gid_and_children (hb_codepoint_t gid, hb_set_t *gids_to_retain,
			  unsigned int depth = 0) const
    {
      if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return;
      /* Check if is already visited */
      if (gids_to_retain->has (gid)) return;

      gids_to_retain->add (gid);

      for (auto &item : glyph_for_gid (gid).get_composite_iterator ())
	add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
    }

#ifdef HB_EXPERIMENTAL_API
    struct path_builder_t
    {
      hb_font_t *font;
      draw_helper_t *draw_helper;

      struct optional_point_t
      {
	optional_point_t () { has_data = false; }
	optional_point_t (float x_, float y_) { x = x_; y = y_; has_data = true; }

	bool has_data;
	float x;
	float y;

	optional_point_t lerp (optional_point_t p, float t)
	{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
      } first_oncurve, first_offcurve, last_offcurve;

      path_builder_t (hb_font_t *font_, draw_helper_t &draw_helper_)
      {
	font = font_;
	draw_helper = &draw_helper_;
	first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
      }

      /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
	 See also:
	 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
	 * https://stackoverflow.com/a/20772557 */
      void consume_point (const contour_point_t &point)
      {
	/* Skip empty contours */
	if (unlikely (point.is_end_point && !first_oncurve.has_data && !first_offcurve.has_data))
	  return;

	bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
	optional_point_t p (point.x, point.y);
	if (!first_oncurve.has_data)
	{
	  if (is_on_curve)
	  {
	    first_oncurve = p;
	    draw_helper->move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
	  }
	  else
	  {
	    if (first_offcurve.has_data)
	    {
	      optional_point_t mid = first_offcurve.lerp (p, .5f);
	      first_oncurve = mid;
	      last_offcurve = p;
	      draw_helper->move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
	    }
	    else
	      first_offcurve = p;
	  }
	}
	else
	{
	  if (last_offcurve.has_data)
	  {
	    if (is_on_curve)
	    {
	      draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
					 font->em_scalef_x (p.x), font->em_scalef_y (p.y));
	      last_offcurve = optional_point_t ();
	    }
	    else
	    {
	      optional_point_t mid = last_offcurve.lerp (p, .5f);
	      draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
					 font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
	      last_offcurve = p;
	    }
	  }
	  else
	  {
	    if (is_on_curve)
	      draw_helper->line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
	    else
	      last_offcurve = p;
	  }
	}

	if (point.is_end_point)
	{
	  if (first_offcurve.has_data && last_offcurve.has_data)
	  {
	    optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
	    draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
				       font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
	    last_offcurve = optional_point_t ();
	    /* now check the rest */
	  }

	  if (first_offcurve.has_data && first_oncurve.has_data)
	    draw_helper->quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y),
				       font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
	  else if (last_offcurve.has_data && first_oncurve.has_data)
	    draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
				       font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
	  else if (first_oncurve.has_data)
	    draw_helper->line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));

	  /* Getting ready for the next contour */
	  first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
	  draw_helper->end_path ();
	}
      }
      void points_end () {}

      bool is_consuming_contour_points () { return true; }
      contour_point_t *get_phantoms_sink () { return nullptr; }
    };

    bool
    get_path (hb_font_t *font, hb_codepoint_t gid, draw_helper_t &draw_helper) const
    { return get_points (font, gid, path_builder_t (font, draw_helper)); }
#endif

    private:
    bool short_offset;
    unsigned int num_glyphs;
    hb_blob_ptr_t<loca> loca_table;
    hb_blob_ptr_t<glyf> glyf_table;
    hb_face_t *face;
  };

  struct SubsetGlyph
  {
    hb_codepoint_t new_gid;
    hb_codepoint_t old_gid;
    Glyph source_glyph;
    hb_bytes_t dest_start;  /* region of source_glyph to copy first */
    hb_bytes_t dest_end;    /* region of source_glyph to copy second */

    bool serialize (hb_serialize_context_t *c,
		    const hb_subset_plan_t *plan) const
    {
      TRACE_SERIALIZE (this);

      hb_bytes_t dest_glyph = dest_start.copy (c);
      dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
      unsigned int pad_length = padding ();
      DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length  + pad_length, pad_length);

      HBUINT8 pad;
      pad = 0;
      while (pad_length > 0)
      {
	c->embed (pad);
	pad_length--;
      }

      if (unlikely (!dest_glyph.length)) return_trace (true);

      /* update components gids */
      for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
      {
	hb_codepoint_t new_gid;
	if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid))
	  ((OT::glyf::CompositeGlyphChain *) &_)->glyphIndex = new_gid;
      }

      if (plan->drop_hints) Glyph (dest_glyph).drop_hints ();

      return_trace (true);
    }

    void drop_hints_bytes ()
    { source_glyph.drop_hints_bytes (dest_start, dest_end); }

    unsigned int      length () const { return dest_start.length + dest_end.length; }
    /* pad to 2 to ensure 2-byte loca will be ok */
    unsigned int     padding () const { return length () % 2; }
    unsigned int padded_size () const { return length () + padding (); }
  };

  protected:
  UnsizedArrayOf<HBUINT8>
		dataZ;	/* Glyphs data. */
  public:
  DEFINE_SIZE_MIN (0);	/* In reality, this is UNBOUNDED() type; but since we always
			 * check the size externally, allow Null() object of it by
			 * defining it _MIN instead. */
};

struct glyf_accelerator_t : glyf::accelerator_t {};

} /* namespace OT */


#endif /* HB_OT_GLYF_TABLE_HH */
