/*
 * Copyright © 2011,2012  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, Roderick Sheeter
 */

#ifndef HB_OT_HMTX_TABLE_HH
#define HB_OT_HMTX_TABLE_HH

#include "hb-open-type.hh"
#include "hb-ot-maxp-table.hh"
#include "hb-ot-hhea-table.hh"
#include "hb-ot-var-hvar-table.hh"
#include "hb-ot-metrics.hh"

/*
 * hmtx -- Horizontal Metrics
 * https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx
 * vmtx -- Vertical Metrics
 * https://docs.microsoft.com/en-us/typography/opentype/spec/vmtx
 */
#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')


HB_INTERNAL bool
_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, int *lsb);

HB_INTERNAL unsigned
_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);


namespace OT {


struct LongMetric
{
  UFWORD	advance; /* Advance width/height. */
  FWORD		sb; /* Leading (left/top) side bearing. */
  public:
  DEFINE_SIZE_STATIC (4);
};


template <typename T/*Data table type*/, typename H/*Header table type*/, typename V/*Var table type*/>
struct hmtxvmtx
{
  bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
  {
    TRACE_SANITIZE (this);
    /* We don't check for anything specific here.  The users of the
     * struct do all the hard work... */
    return_trace (true);
  }


  bool subset_update_header (hb_subset_plan_t *plan,
			     unsigned int num_hmetrics) const
  {
    hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag);
    hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
    hb_blob_destroy (src_blob);

    if (unlikely (!dest_blob)) {
      return false;
    }

    unsigned int length;
    H *table = (H *) hb_blob_get_data (dest_blob, &length);
    table->numberOfLongMetrics = num_hmetrics;

    bool result = plan->add_table (H::tableTag, dest_blob);
    hb_blob_destroy (dest_blob);

    return result;
  }

  template<typename Iterator,
	   hb_requires (hb_is_iterator (Iterator))>
  void serialize (hb_serialize_context_t *c,
		  Iterator it,
		  unsigned num_long_metrics)
  {
    unsigned idx = 0;
    for (auto _ : it)
    {
      if (idx < num_long_metrics)
      {
	LongMetric lm;
	lm.advance = _.first;
	lm.sb = _.second;
	if (unlikely (!c->embed<LongMetric> (&lm))) return;
      }
      else
      {
	FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
	if (unlikely (!sb)) return;
	*sb = _.second;
      }
      idx++;
    }
  }

  bool subset (hb_subset_context_t *c) const
  {
    TRACE_SUBSET (this);

    T *table_prime = c->serializer->start_embed <T> ();
    if (unlikely (!table_prime)) return_trace (false);

    accelerator_t _mtx (c->plan->source);
    unsigned num_long_metrics;
    {
      /* Determine num_long_metrics to encode. */
      auto& plan = c->plan;
      num_long_metrics = plan->num_output_glyphs ();
      hb_codepoint_t old_gid = 0;
      unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0;
      while (num_long_metrics > 1 &&
	     last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0))
      {
	num_long_metrics--;
      }
    }

    auto it =
    + hb_range (c->plan->num_output_glyphs ())
    | hb_map ([c, &_mtx] (unsigned _)
	      {
		hb_codepoint_t old_gid;
		if (!c->plan->old_gid_for_new_gid (_, &old_gid))
		  return hb_pair (0u, 0);
		int lsb = 0;
		(void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb);
		return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
	      })
    ;

    table_prime->serialize (c->serializer, it, num_long_metrics);

    if (unlikely (c->serializer->in_error ()))
      return_trace (false);

    // Amend header num hmetrics
    if (unlikely (!subset_update_header (c->plan, num_long_metrics)))
      return_trace (false);

    return_trace (true);
  }

  struct accelerator_t
  {
    friend struct hmtxvmtx;

    accelerator_t (hb_face_t *face)
    {
      table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
      var_table = hb_sanitize_context_t ().reference_table<V> (face, T::variationsTag);

      default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face);

      /* Populate count variables and sort them out as we go */

      unsigned int len = table.get_length ();
      if (len & 1)
        len--;

      num_long_metrics = T::is_horizontal ?
			 face->table.hhea->numberOfLongMetrics :
#ifndef HB_NO_VERTICAL
			 face->table.vhea->numberOfLongMetrics
#else
			 0
#endif
			 ;
      if (unlikely (num_long_metrics * 4 > len))
	num_long_metrics = len / 4;
      len -= num_long_metrics * 4;

      num_bearings = face->table.maxp->get_num_glyphs ();

      if (unlikely (num_bearings < num_long_metrics))
        num_bearings = num_long_metrics;
      if (unlikely ((num_bearings - num_long_metrics) * 2 > len))
        num_bearings = num_long_metrics + len / 2;
      len -= (num_bearings - num_long_metrics) * 2;

      /* We MUST set num_bearings to zero if num_long_metrics is zero.
       * Our get_advance() depends on that. */
      if (unlikely (!num_long_metrics))
	num_bearings = num_long_metrics = 0;

      num_advances = num_bearings + len / 2;
      num_glyphs = face->get_num_glyphs ();
      if (num_glyphs < num_advances)
        num_glyphs = num_advances;
    }
    ~accelerator_t ()
    {
      table.destroy ();
      var_table.destroy ();
    }

    bool has_data () const { return (bool) num_bearings; }

    bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph,
						   int *lsb) const
    {
      if (glyph < num_long_metrics)
      {
	*lsb = table->longMetricZ[glyph].sb;
	return true;
      }

      if (unlikely (glyph >= num_bearings))
	return false;

      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
      *lsb = bearings[glyph - num_long_metrics];
      return true;
    }

    bool get_leading_bearing_with_var_unscaled (hb_font_t *font,
						hb_codepoint_t glyph,
						int *lsb) const
    {
      if (!font->num_coords)
	return get_leading_bearing_without_var_unscaled (glyph, lsb);

#ifndef HB_NO_VAR
      float delta;
      if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) &&
	  get_leading_bearing_without_var_unscaled (glyph, lsb))
      {
	*lsb += roundf (delta);
	return true;
      }

      return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb);
#else
      return false;
#endif
    }

    unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const
    {
      /* OpenType case. */
      if (glyph < num_bearings)
	return table->longMetricZ[hb_min (glyph, (uint32_t) num_long_metrics - 1)].advance;

      /* If num_advances is zero, it means we don't have the metrics table
       * for this direction: return default advance.  Otherwise, there's a
       * well-defined answer. */
      if (unlikely (!num_advances))
	return default_advance;

#ifdef HB_NO_BEYOND_64K
      return 0;
#endif

      if (unlikely (glyph >= num_glyphs))
        return 0;

      /* num_bearings <= glyph < num_glyphs;
       * num_bearings <= num_advances */

      /* TODO Optimize */

      if (num_bearings == num_advances)
        return get_advance_without_var_unscaled (num_bearings - 1);

      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
      const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics];

      return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)];
    }

    unsigned get_advance_with_var_unscaled (hb_codepoint_t  glyph,
					    hb_font_t      *font,
					    VariationStore::cache_t *store_cache = nullptr) const
    {
      unsigned int advance = get_advance_without_var_unscaled (glyph);

#ifndef HB_NO_VAR
      if (unlikely (glyph >= num_bearings) || !font->num_coords)
	return advance;

      if (var_table.get_length ())
	return advance + roundf (var_table->get_advance_delta_unscaled (glyph,
									font->coords, font->num_coords,
									store_cache)); // TODO Optimize?!

      return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
#else
      return advance;
#endif
    }

    protected:
    // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs
    unsigned num_long_metrics;
    unsigned num_bearings;
    unsigned num_advances;
    unsigned num_glyphs;

    unsigned int default_advance;

    public:
    hb_blob_ptr_t<hmtxvmtx> table;
    hb_blob_ptr_t<V> var_table;
  };

  protected:
  UnsizedArrayOf<LongMetric>
		longMetricZ;	/* Paired advance width and leading
				 * bearing values for each glyph. The
				 * value numOfHMetrics comes from
				 * the 'hhea' table. If the font is
				 * monospaced, only one entry need
				 * be in the array, but that entry is
				 * required. The last entry applies to
				 * all subsequent glyphs. */
/*UnsizedArrayOf<FWORD>	leadingBearingX;*/
				/* Here the advance is assumed
				 * to be the same as the advance
				 * for the last entry above. The
				 * number of entries in this array is
				 * derived from numGlyphs (from 'maxp'
				 * table) minus numberOfLongMetrics.
				 * This generally is used with a run
				 * of monospaced glyphs (e.g., Kanji
				 * fonts or Courier fonts). Only one
				 * run is allowed and it must be at
				 * the end. This allows a monospaced
				 * font to vary the side bearing
				 * values for each glyph. */
/*UnsizedArrayOf<UFWORD>advancesX;*/
				/* TODO Document. */
  public:
  DEFINE_SIZE_ARRAY (0, longMetricZ);
};

struct hmtx : hmtxvmtx<hmtx, hhea, HVAR> {
  static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
  static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
  static constexpr bool is_horizontal = true;
};
struct vmtx : hmtxvmtx<vmtx, vhea, VVAR> {
  static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
  static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
  static constexpr bool is_horizontal = false;
};

struct hmtx_accelerator_t : hmtx::accelerator_t {
  hmtx_accelerator_t (hb_face_t *face) : hmtx::accelerator_t (face) {}
};
struct vmtx_accelerator_t : vmtx::accelerator_t {
  vmtx_accelerator_t (hb_face_t *face) : vmtx::accelerator_t (face) {}
};

} /* namespace OT */


#endif /* HB_OT_HMTX_TABLE_HH */
